AMD General

Regards,
      Prike

> -----Original Message-----
> From: Koenig, Christian <[email protected]>
> Sent: Tuesday, October 13, 2026 5:31 PM
> To: Liang, Prike <[email protected]>; [email protected]
> Cc: Deucher, Alexander <[email protected]>; Lazar, Lijo
> <[email protected]>; Prosyak, Vitaly <[email protected]>
> Subject: Re: [PATCH 7/9] drm/amdgpu/userq: take reset_domain->sem before
> userq_mutex in destroy
>
> On 10/13/26 10:24, Prike Liang wrote:
> > amdgpu_userq_destroy() takes reset_domain->sem for read in
> > amdgpu_userq_detach_doorbell() while holding userq_mutex.
>
> Yeah that is correct behavior.
>
> > GPU recovery
> > holds reset_domain->sem for write and then takes clientlist_mutex in
> > drm_client_dev_suspend(),
>
> That is completely broken behavior and need to be fixed.
>
> The GPU reset can *NEVER* call drm_client_dev_suspend(), who came up with
> that nonsense?

The call to drm_client_dev_suspend() have been in the GPU recovery path for 
some time, possibly leveraged incorrectly from the system suspend path. I’ll 
clean it up in the GPU recovery path.

Regards,
Prike

> Regards,
> Christian.
>
> > which already depends on userq_mutex through the fbdev reservation and
> > userq restore paths. Lockdep reports:
> >
> >   Chain exists of:
> >     &dev->clientlist_mutex --> &userq_mgr->userq_mutex -->
> > &reset_domain->sem
> >
> > Keep waiting for the last fence under userq_mutex only, as the fence
> > of a hung queue is only force-completed by the reset, then take
> > reset_domain->sem before re-acquiring userq_mutex for the doorbell
> > detach, unmap and fence driver teardown. This also keeps the MES unmap
> > from racing with an in-progress GPU reset.
> >
> > Fixes: f18719ef4bb7 ("drm/amdgpu: Convert amdgpu userqueue management
> > from IDR to XArray")
> > Signed-off-by: Prike Liang <[email protected]>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 16 ++++++----------
> >  1 file changed, 6 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > index 5fef0cc7703c..a34ea8ecd700 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> > @@ -415,15 +415,6 @@ static void amdgpu_userq_wait_for_last_fence(struct
> amdgpu_usermode_queue *queue
> >     dma_fence_wait(f, false);
> >  }
> >
> > -static void amdgpu_userq_detach_doorbell(struct amdgpu_usermode_queue
> > *queue) -{
> > -   struct amdgpu_device *adev = queue->userq_mgr->adev;
> > -
> > -   down_read(&adev->reset_domain->sem);
> > -   xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
> > -   up_read(&adev->reset_domain->sem);
> > -}
> > -
> >  /**
> >   * amdgpu_userq_ensure_ev_fence - ensure a valid, unsignaled eviction fence
> exists
> >   * @uq_mgr: the usermode queue manager for this process @@ -547,8
> > +538,12 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr,
> > struct amdgpu_usermode_que
> >
> >     mutex_lock(&uq_mgr->userq_mutex);
> >     amdgpu_userq_wait_for_last_fence(queue);
> > +   mutex_unlock(&uq_mgr->userq_mutex);
> >
> > -   amdgpu_userq_detach_doorbell(queue);
> > +   /* GPU recovery takes userq_mutex under reset_domain->sem, keep that
> order */
> > +   down_read(&adev->reset_domain->sem);
> > +   mutex_lock(&uq_mgr->userq_mutex);
> > +   xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
> >
> >  #if defined(CONFIG_DEBUG_FS)
> >     debugfs_remove_recursive(queue->debugfs_queue);
> > @@ -558,6 +553,7 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr
> *uq_mgr, struct amdgpu_usermode_que
> >     amdgpu_userq_fence_driver_free(queue);
> >     queue->fence_drv = NULL;
> >     mutex_unlock(&uq_mgr->userq_mutex);
> > +   up_read(&adev->reset_domain->sem);
> >
> >     /*
> >      * A failed unmap means MES could not remove the hung queue and is
> > now

Reply via email to