All of lore.kernel.org
 help / color / mirror / Atom feed
From: vitaly prosyak <vprosyak@amd.com>
To: Jesse Zhang <Jesse.Zhang@amd.com>, igt-dev@lists.freedesktop.org
Cc: Vitaly Prosyak <vitaly.prosyak@amd.com>,
	Alex Deucher <alexander.deucher@amd.com>,
	Christian Koenig <christian.koenig@amd.com>
Subject: Re: [PATCH i-g-t] tests/amdgpu/amd_deadlock: add gfx bad-opcode non-zero-count reset test
Date: Wed, 29 Jul 2026 21:15:50 -0400	[thread overview]
Message-ID: <84aceadf-b76c-4237-b666-7e47d59485cb@amd.com> (raw)
In-Reply-To: <20260729063923.892313-1-Jesse.Zhang@amd.com>

LGTM

Reviewed-by Vitaly Prosyak  <vitaly.prosyak@amd.com>

On 2026-07-29 02:38, Jesse Zhang wrote:
> Add amdgpu-gfx-priv-fault-badcount-umq: a gfx user-queue bad opcode (0xf2)
> whose PACKET3 header carries a non-zero count field but no body. The pipe HW
> cannot find the packet end and stalls mid-packet, so a per-queue (vmid) reset
> cannot recover it -- only a gfx pipe reset can (once that FW support lands).
> Until then the case escalates to a full GPU reset.
>
> Add a priv_fault_badcount_hang IP-block hook to emit the packet.
>
> Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
> ---
>  lib/amdgpu/amd_deadlock_helpers.c | 80 +++++++++++++++++++++++++++++++
>  lib/amdgpu/amd_deadlock_helpers.h |  4 ++
>  lib/amdgpu/amd_ip_blocks.h        | 11 +++++
>  lib/amdgpu/amd_ip_blocks_ex.c     | 24 ++++++++++
>  tests/amdgpu/amd_deadlock.c       |  9 ++++
>  5 files changed, 128 insertions(+)
>
> diff --git a/lib/amdgpu/amd_deadlock_helpers.c b/lib/amdgpu/amd_deadlock_helpers.c
> index 71c82aa91..1ce46422f 100644
> --- a/lib/amdgpu/amd_deadlock_helpers.c
> +++ b/lib/amdgpu/amd_deadlock_helpers.c
> @@ -529,6 +529,16 @@ static void gfx_ring_emit_priv_inst_hang(
>  	ring_context->pm4_dw = i;
>  }
>  
> +static void gfx_ring_emit_priv_fault_badcount_hang(
> +	const struct amdgpu_ip_block_version *ip_block,
> +	struct amdgpu_ring_context *ring_context)
> +{
> +	uint32_t i = 0;
> +
> +	ip_block->funcs->priv_fault_badcount_hang(ip_block->funcs, ring_context, &i);
> +	ring_context->pm4_dw = i;
> +}
> +
>  /*
>   * Fault a user queue with an invalid opcode followed by an endless wait: the
>   * bad opcode raises the gfx priv-fault interrupt and the wait hangs the queue
> @@ -600,6 +610,76 @@ void amdgpu_priv_fault_ring_helper(amdgpu_device_handle device_handle, unsigned
>  	}
>  }
>  
> +/*
> + * Fault a user queue with a bad opcode carrying a non-zero count field and no
> + * body: the pipe HW cannot find the packet end and stalls mid-packet, so a
> + * per-queue (vmid) reset cannot recover it -- only a gfx pipe reset can (once
> + * that FW support is ready). Until then the case escalates to a full GPU reset.
> + */
> +void amdgpu_priv_fault_badcount_ring_helper(amdgpu_device_handle device_handle, unsigned int ip_type,
> +					    struct pci_addr *pci, bool user_queue)
> +{
> +	const struct amdgpu_ip_block_version *ip_block;
> +	const int write_length = 128;
> +	const int pm4_dw = 256;
> +	struct amdgpu_ring_context *ring_context;
> +	int r = 0;
> +
> +	ip_block = get_ip_block(device_handle, ip_type);
> +	ring_context = calloc(1, sizeof(*ring_context));
> +	igt_assert(ring_context);
> +
> +	if (user_queue) {
> +		ip_block->funcs->userq_create(device_handle, ring_context, ip_type);
> +	} else {
> +		r = amdgpu_cs_ctx_create(device_handle, &ring_context->context_handle);
> +		igt_assert_eq(r, 0);
> +	}
> +
> +	ring_context->write_length = write_length;
> +	ring_context->pm4 = calloc(pm4_dw, sizeof(*ring_context->pm4));
> +	ring_context->pm4_size = pm4_dw;
> +	ring_context->res_cnt = 1;
> +	ring_context->ring_id = 0;
> +	ring_context->user_queue = user_queue;
> +	igt_assert(ring_context->pm4);
> +
> +	r = amdgpu_bo_alloc_and_map_sync(device_handle,
> +				    ring_context->write_length * sizeof(uint32_t),
> +				    4096, AMDGPU_GEM_DOMAIN_GTT,
> +				    AMDGPU_GEM_CREATE_CPU_GTT_USWC,
> +				    AMDGPU_VM_MTYPE_UC,
> +				    &ring_context->bo,
> +				    (void **)&ring_context->bo_cpu,
> +				    &ring_context->bo_mc,
> +				    &ring_context->va_handle,
> +				    ring_context->timeline_syncobj_handle,
> +				    ++ring_context->point, user_queue);
> +	igt_assert_eq(r, 0);
> +	if (user_queue) {
> +		r = amdgpu_timeline_syncobj_wait(device_handle,
> +			ring_context->timeline_syncobj_handle,
> +			ring_context->point);
> +		igt_assert_eq(r, 0);
> +	}
> +
> +	memset((void *)ring_context->bo_cpu, 0, ring_context->write_length * sizeof(uint32_t));
> +	ring_context->resources[0] = ring_context->bo;
> +
> +	gfx_ring_emit_priv_fault_badcount_hang(ip_block, ring_context);
> +
> +	amdgpu_test_exec_cs_helper(device_handle, ip_block->type, ring_context, 0);
> +
> +	amdgpu_bo_unmap_and_free(ring_context->bo, ring_context->va_handle, ring_context->bo_mc,
> +				 ring_context->write_length * sizeof(uint32_t));
> +	if (user_queue) {
> +		ip_block->funcs->userq_destroy(device_handle, ring_context, ip_type);
> +	} else {
> +		free(ring_context->pm4);
> +		free(ring_context);
> +	}
> +}
> +
>  /*
>   * Fault a user queue with a privileged INDIRECT_BUFFER (priv-instruction fault)
>   * followed by an endless wait: the privileged IB launch raises a fault interrupt
> diff --git a/lib/amdgpu/amd_deadlock_helpers.h b/lib/amdgpu/amd_deadlock_helpers.h
> index 69c321ef6..0fd5eb59a 100644
> --- a/lib/amdgpu/amd_deadlock_helpers.h
> +++ b/lib/amdgpu/amd_deadlock_helpers.h
> @@ -42,6 +42,10 @@ void
>  amdgpu_priv_fault_ring_helper(amdgpu_device_handle device_handle, unsigned int ip_type,
>  			      struct pci_addr *pci, bool user_queue);
>  
> +void
> +amdgpu_priv_fault_badcount_ring_helper(amdgpu_device_handle device_handle, unsigned int ip_type,
> +				       struct pci_addr *pci, bool user_queue);
> +
>  void
>  amdgpu_priv_inst_ring_helper(amdgpu_device_handle device_handle, unsigned int ip_type,
>  			     struct pci_addr *pci, bool user_queue);
> diff --git a/lib/amdgpu/amd_ip_blocks.h b/lib/amdgpu/amd_ip_blocks.h
> index 427010c2d..40a9735be 100644
> --- a/lib/amdgpu/amd_ip_blocks.h
> +++ b/lib/amdgpu/amd_ip_blocks.h
> @@ -460,6 +460,17 @@ struct amdgpu_ip_funcs {
>  		uint32_t *pm4_dw
>  	);
>  
> +	/*
> +	 * Emit a bad opcode with a non-zero count field and no body: the pipe HW
> +	 * cannot find the packet end and stalls mid-packet, so a per-queue (vmid)
> +	 * reset cannot recover it -- only a gfx pipe reset can.
> +	 */
> +	int (*priv_fault_badcount_hang)(
> +		const struct amdgpu_ip_funcs *func,
> +		const struct amdgpu_ring_context *context,
> +		uint32_t *pm4_dw
> +	);
> +
>  };
>  
>  extern const struct amdgpu_ip_block_version gfx_v6_0_ip_block;
> diff --git a/lib/amdgpu/amd_ip_blocks_ex.c b/lib/amdgpu/amd_ip_blocks_ex.c
> index 4655d9dcc..ad384ec33 100644
> --- a/lib/amdgpu/amd_ip_blocks_ex.c
> +++ b/lib/amdgpu/amd_ip_blocks_ex.c
> @@ -228,6 +228,10 @@ static int gfx_ring_priv_inst_hang(const struct amdgpu_ip_funcs *func,
>  				   const struct amdgpu_ring_context *ring_context,
>  				   uint32_t *pm4_dw);
>  
> +static int gfx_ring_priv_fault_badcount_hang(const struct amdgpu_ip_funcs *func,
> +					     const struct amdgpu_ring_context *ring_context,
> +					     uint32_t *pm4_dw);
> +
>  void amd_ip_blocks_ex_init(struct amdgpu_ip_funcs *funcs)
>  {
>  	funcs->gfx_program_compute = gfx_program_compute_default;
> @@ -240,6 +244,7 @@ void amd_ip_blocks_ex_init(struct amdgpu_ip_funcs *funcs)
>  	funcs->wait_reg_mem_hang = gfx_ring_wait_reg_mem_hang;
>  	funcs->priv_fault_hang = gfx_ring_priv_fault_hang;
>  	funcs->priv_inst_hang = gfx_ring_priv_inst_hang;
> +	funcs->priv_fault_badcount_hang = gfx_ring_priv_fault_badcount_hang;
>  
>  	switch (funcs->family_id) {
>  	case AMDGPU_FAMILY_RV:
> @@ -358,3 +363,22 @@ gfx_ring_priv_fault_hang(const struct amdgpu_ip_funcs *func,
>  	return 0;
>  }
>  
> +/*
> + * Emit a bad opcode (0xf2) with a non-zero count field and no body: the header
> + * claims a body that is never submitted, so the pipe HW cannot find the packet
> + * end and stalls mid-packet. A per-queue (vmid) reset cannot process it; only a
> + * gfx pipe reset can (once that FW support is ready).
> + */
> +static int
> +gfx_ring_priv_fault_badcount_hang(const struct amdgpu_ip_funcs *func,
> +				  const struct amdgpu_ring_context *ring_context,
> +				  uint32_t *pm4_dw)
> +{
> +	uint32_t i = *pm4_dw;
> +
> +	ring_context->pm4[i++] = PACKET3(0xf2, 0x3fff);
> +	*pm4_dw = i;
> +
> +	return 0;
> +}
> +
> diff --git a/tests/amdgpu/amd_deadlock.c b/tests/amdgpu/amd_deadlock.c
> index 1d729eeb4..d66a58859 100644
> --- a/tests/amdgpu/amd_deadlock.c
> +++ b/tests/amdgpu/amd_deadlock.c
> @@ -265,6 +265,15 @@ int igt_main()
>  		}
>  	}
>  
> +	igt_describe("Test-gfx-user-queue-bad-opcode-with-nonzero-count-recovers-via-gfx-pipe-reset");
> +	igt_subtest_with_dynamic("amdgpu-gfx-priv-fault-badcount-umq") {
> +		if (enable_test && userq_arr_cap[AMD_IP_GFX] &&
> +			is_reset_enable(AMD_IP_GFX, AMDGPU_RESET_TYPE_PER_QUEUE, &pci)) {
> +			igt_dynamic_f("amdgpu-gfx-priv-fault-badcount-umq")
> +			amdgpu_priv_fault_badcount_ring_helper(device, AMDGPU_HW_IP_GFX, &pci, true);
> +		}
> +	}
> +
>  	igt_describe("Test-per-queue-reset-recovery-of-a-gfx-user-queue-privileged-instruction-fault");
>  	igt_subtest_with_dynamic("amdgpu-gfx-priv-inst-umq") {
>  		if (enable_test && userq_arr_cap[AMD_IP_GFX] &&

      parent reply	other threads:[~2026-07-30  1:16 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-29  6:38 [PATCH i-g-t] tests/amdgpu/amd_deadlock: add gfx bad-opcode non-zero-count reset test Jesse Zhang
2026-07-29  7:45 ` ✓ i915.CI.BAT: success for " Patchwork
2026-07-29  8:35 ` ✓ Xe.CI.FULL: " Patchwork
2026-07-29 10:01 ` ✗ i915.CI.Full: failure " Patchwork
2026-07-30  1:15 ` vitaly prosyak [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=84aceadf-b76c-4237-b666-7e47d59485cb@amd.com \
    --to=vprosyak@amd.com \
    --cc=Jesse.Zhang@amd.com \
    --cc=alexander.deucher@amd.com \
    --cc=christian.koenig@amd.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=vitaly.prosyak@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.