AMD General Ping ...
> -----Original Message----- > From: Jesse Zhang <[email protected]> > Sent: Thursday, June 11, 2026 11:57 AM > To: [email protected] > Cc: Deucher, Alexander <[email protected]>; Koenig, Christian > <[email protected]>; Deucher, Alexander > <[email protected]>; Zhang, Jesse(Jie) <[email protected]> > Subject: [PATCH v2 1/7] drm/amdgpu/userq: add reset helper and identify guilty > user queue > > From: Alex Deucher <[email protected]> > > If we get an interrupt for a bad user queue (bad opcode, etc.), add a helper > to handle > the reset for user queues. > > v2: squash in fixes > > Signed-off-by: Alex Deucher <[email protected]> > Co-developed-by: Jesse Zhang <[email protected]> > Signed-off-by: Jesse Zhang <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 40 +++++++++++++++++++++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 12 +++++++ > 2 files changed, 49 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > index de6848b4fd67..231ffb29fe5e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > @@ -140,9 +140,14 @@ static void amdgpu_userq_hang_detect_work(struct > work_struct *work) > > AMDGPU_RESET_TYPE_PER_QUEUE)) { > int r; > > - if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) > - r = amdgpu_gfx_reset_mes_compute(adev, NULL, NULL, > NULL, NULL, NULL); > - else > + if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { > + struct amdgpu_usermode_queue *guilty_uq; > + > + /* IRQ-side WRITE_ONCE(guilty,true) hand-off via xchg */ > + guilty_uq = xchg(&queue->guilty, false) ? queue : NULL; > + r = amdgpu_gfx_reset_mes_compute(adev, NULL, NULL, > + guilty_uq, NULL, NULL); > + } else > r = userq_funcs->reset(queue); > if (r) > gpu_reset = true; > @@ -671,6 +676,7 @@ amdgpu_userq_create(struct drm_file *filp, union > drm_amdgpu_userq *args) > } > > queue->doorbell_index = index; > + queue->doorbell_offset = (u32)args->in.doorbell_offset; > r = uq_funcs->mqd_create(queue, &args->in); > if (r) { > drm_file_err(uq_mgr->file, "Failed to create Queue\n"); @@ > -1111,6 > +1117,34 @@ static void amdgpu_userq_restore_worker(struct work_struct *work) > dma_fence_put(ev_fence); > } > > +void amdgpu_userq_process_reset_irq(struct amdgpu_device *adev, > + u32 pasid, u32 doorbell_offset) { > + struct xarray *xa = &adev->userq_doorbell_xa; > + struct amdgpu_usermode_queue *queue; > + unsigned long flags, idx; > + > + /* > + * CP priv-fault payload is (pasid, src_data[0] & 0x3ff) - the same > + * per-process doorbell encoding KFD extracts via > + * KFD_CTXID0_DOORBELL_ID_MASK. Find the offending queue by the > + * (vm->pasid, doorbell_offset) pair, mark it guilty and fire > + * hang_detect immediately (queue_delayed_work() would no-op if the > + * work is already armed at submit time). > + */ > + xa_lock_irqsave(xa, flags); > + xa_for_each(xa, idx, queue) { > + if (queue->vm && queue->vm->pasid == pasid && > + queue->doorbell_offset == doorbell_offset) { > + WRITE_ONCE(queue->guilty, true); > + mod_delayed_work(adev->reset_domain->wq, > + &queue->hang_detect_work, 0); > + break; > + } > + } > + xa_unlock_irqrestore(xa, flags); > +} > + > static int > amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr) { diff --git > a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > index 9df1b78407f5..a55d57e2c169 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > @@ -53,6 +53,7 @@ struct amdgpu_usermode_queue { > enum amdgpu_userq_state state; > uint64_t doorbell_handle; > uint64_t doorbell_index; > + u32 doorbell_offset; > uint64_t flags; > struct amdgpu_mqd_prop *userq_prop; > struct amdgpu_userq_mgr *userq_mgr; > @@ -86,6 +87,7 @@ struct amdgpu_usermode_queue { > * Delayed work which runs when userq_fences time out. > */ > struct delayed_work hang_detect_work; > + bool guilty; > struct kref refcount; > > union { > @@ -176,6 +178,16 @@ int amdgpu_userq_post_reset(struct amdgpu_device > *adev, bool vram_lost); void amdgpu_userq_start_hang_detect_work(struct > amdgpu_usermode_queue *queue); void amdgpu_userq_process_fence_irq(struct > amdgpu_device *adev, u32 doorbell); > > +/* > + * CP packs the per-process doorbell_id of the queue in > + * CTXID0[9:0] on priv-fault (same encoding KFD uses via > + * KFD_CTXID0_DOORBELL_ID_MASK) > + */ > +#define AMDGPU_CTXID0_DOORBELL_ID_MASK 0x3ff > + > +void amdgpu_userq_process_reset_irq(struct amdgpu_device *adev, > + u32 pasid, u32 doorbell_offset); > + > int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, > struct amdgpu_usermode_queue *queue, > u64 addr, u64 expected_size, u64 *va_out); > -- > 2.49.0
