On Mon, Jul 13, 2026 at 12:34 PM Srinivasan Shanmugam <[email protected]> wrote: > > Signal QUEUE_RESET EVENTFD subscriptions when hung user queues are > detected. > > MES reports the doorbell indices of hung queues. Use the existing > doorbell-to-queue mapping to find the affected queue and notify matching > EVENTFD subscribers. > > Move the queue reset handling into amdgpu_userq.c so the queue lookup > and queue handling are performed in one place. This avoids scanning all > queues to find a matching doorbell. > > EVENTFD remains notification-only. > > v2: (per Christian) > - Use the doorbell xarray to look up affected queues instead of scanning > all queues. > - Move queue reset handling into amdgpu_userq.c. > - Consolidate queue state updates, EVENTFD signaling, and fence > completion in a single helper. > > Cc: Alex Deucher <[email protected]> > Suggested-by: Christian König <[email protected]> > Signed-off-by: Srinivasan Shanmugam <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 33 ++++++++++ > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 3 +- > drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 73 ++++++++++++++-------- > 3 files changed, 83 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > index ab3ef3a9f655..5bf231d7a630 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > @@ -242,7 +242,40 @@ void amdgpu_userq_process_fence_irq(struct amdgpu_device > *adev, u32 doorbell) > xa_unlock_irqrestore(xa, flags); > } > > +/** > + * amdgpu_userq_handle_hung_queue - handle a successfully reset hung queue > + * @adev: AMDGPU device > + * @queue: affected user queue > + * > + * Mark the queue as hung, notify matching QUEUE_RESET EVENTFD > + * subscribers, force-complete its fences, and send the DRM wedged event. > + * > + * Return: > + * true when the queue was handled, false for an invalid queue. > + */ > +bool > +amdgpu_userq_handle_hung_queue(struct amdgpu_device *adev, > + struct amdgpu_usermode_queue *queue) > +{ > + struct amdgpu_eventfd_mgr *eventfd_mgr; > > + if (!queue) > + return false; > + > + queue->state = AMDGPU_USERQ_STATE_HUNG; > + > + eventfd_mgr = amdgpu_userq_eventfd_mgr(queue->userq_mgr); > + amdgpu_eventfd_signal(eventfd_mgr, > + DRM_AMDGPU_EVENT_TYPE_QUEUE_RESET, > + queue); > + > + amdgpu_userq_fence_driver_force_completion(queue); > + > + drm_dev_wedged_event(adev_to_drm(adev), > + DRM_WEDGE_RECOVERY_NONE, NULL); > + > + return true; > +} > > int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, > struct amdgpu_usermode_queue *queue, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > index b69621311b80..187bfd66eb13 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > @@ -180,7 +180,8 @@ void amdgpu_userq_pre_reset(struct amdgpu_device *adev); > 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); > - > +bool amdgpu_userq_handle_hung_queue(struct amdgpu_device *adev, > + struct amdgpu_usermode_queue *queue); > /* > * CP packs the per-process doorbell_id of the queue in > * CTXID0[9:0] on priv-fault (same encoding KFD uses via > diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > index 3fad95199e0c..4b546613c024 100644 > --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > @@ -26,6 +26,7 @@ > #include "amdgpu_gfx.h" > #include "mes_userqueue.h" > #include "amdgpu_userq_fence.h" > +#include "amdgpu_userq_internal.h" > #include "amdgpu_cwsr.h" > > #define AMDGPU_USERQ_PROC_CTX_SZ PAGE_SIZE > @@ -238,34 +239,56 @@ int mes_userq_reset_queue(struct amdgpu_device *adev,
mes_userq_reset_queue() is only called for collateral damage on compute queues. You also need to handle this in amdgpu_userq_hang_detect_work() for the original guilty queue. I think we also need this patch: https://patchwork.freedesktop.org/patch/739898/?series=170347&rev=1 Alex > unsigned int queue, > unsigned int db) > { > + struct xarray *xa = &adev->userq_doorbell_xa; > struct amdgpu_usermode_queue *uq; > bool use_mmio = adev->gfx.mec.use_mmio_for_reset; > - unsigned long uq_id; > - int r; > + unsigned long flags; > + int r = 0; > > - xa_for_each(&adev->userq_doorbell_xa, uq_id, uq) { > - if (uq->queue_type == queue_type) { > - if (uq == guilty_uq) > - continue; > - if (uq->doorbell_index == db) { > - uq->state = AMDGPU_USERQ_STATE_HUNG; > - if (use_mmio) > - r = amdgpu_mes_reset_queue_mmio(adev, > queue_type, 0, 1, pipe, queue, 0); > - else > - r = amdgpu_mes_reset_user_queue(adev, > queue_type, db, 0); > - if (r) > - return r; > - r = mes_userq_unmap(uq); > - if (r) > - return r; > - atomic_inc(&adev->gpu_reset_counter); > - > amdgpu_userq_fence_driver_force_completion(uq); > - drm_dev_wedged_event(adev_to_drm(adev), > DRM_WEDGE_RECOVERY_NONE, NULL); > - break; > - } > - } > - } > - return 0; > + /* > + * Resolve the doorbell directly to the affected queue instead of > + * scanning all user queues. > + */ > + xa_lock_irqsave(xa, flags); > + > + uq = xa_load(xa, db); > + if (uq) > + kref_get(&uq->refcount); > + > + xa_unlock_irqrestore(xa, flags); > + > + if (!uq) > + return 0; > + > + /* > + * The guilty queue is handled separately by the caller. > + */ > + if (uq == guilty_uq) > + goto out_put_queue; > + > + if (uq->queue_type != queue_type) > + goto out_put_queue; > + > + if (use_mmio) > + r = amdgpu_mes_reset_queue_mmio(adev, queue_type, > + 0, 1, pipe, queue, 0); > + else > + r = amdgpu_mes_reset_user_queue(adev, queue_type, db, 0); > + > + if (r) > + goto out_put_queue; > + > + r = mes_userq_unmap(uq); > + if (r) > + goto out_put_queue; > + > + if (amdgpu_userq_handle_hung_queue(adev, uq)) > + atomic_inc(&adev->gpu_reset_counter); > + > +out_put_queue: > + amdgpu_userq_put(uq); > + > + return r; > } > > static int mes_userq_create_ctx_space(struct amdgpu_userq_mgr *uq_mgr, > -- > 2.34.1 >
