On Thu, Aug 13, 2026 at 11:50 PM Prike Liang <[email protected]> wrote:
>
> amdgpu_userq_fence_driver() and amdgpu_userq_fence_driver_destroy()
> don't acquire the dma_fence spinlock, so locking the dma_fence lock
> before test the signaled state and set error state.
>
> Signed-off-by: Prike Liang <[email protected]>
> ---
>  .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c   | 20 ++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> index 19af1adc2921..09e2079cfdbd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> @@ -191,14 +191,15 @@ void amdgpu_userq_fence_driver_destroy(struct kref *ref)
>         struct dma_fence *f;
>
>         spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
> +       lockdep_assert_held(&fence_drv->fence_list_lock);
>         list_for_each_entry_safe(fence, tmp, &fence_drv->fences, link) {
>                 f = &fence->base;
> -
> -               if (!dma_fence_is_signaled(f)) {
> +               spin_lock(dma_fence_spinlock(f));
> +               if (!dma_fence_is_signaled_locked(f)) {
>                         dma_fence_set_error(f, -ECANCELED);
> -                       dma_fence_signal(f);
> +                       dma_fence_signal_locked(f);
>                 }
> -
> +               spin_unlock(dma_fence_spinlock(f));
>                 list_del(&fence->link);
>                 dma_fence_put(f);
>         }
> @@ -423,11 +424,16 @@ amdgpu_userq_fence_driver_set_error(struct 
> amdgpu_userq_fence *fence,
>         struct dma_fence *f;
>
>         spin_lock_irqsave(&fence_drv->fence_list_lock, flags);
> -
> +       lockdep_assert_held(&fence_drv->fence_list_lock);
>         f = rcu_dereference_protected(&fence->base,
>                                       
> lockdep_is_held(&fence_drv->fence_list_lock));
> -       if (f && !dma_fence_is_signaled_locked(f))
> -               dma_fence_set_error(f, error);
> +       if (f) {
> +               /* nest f->lock inside fence_list_lock */
> +               spin_lock(dma_fence_spinlock(f));

Why do we need to take the fence spinlock for userqs, but not for
kernel queues?  See amdgpu_fence.c

Alex

> +               if (!dma_fence_is_signaled_locked(f))
> +                       dma_fence_set_error(f, error);
> +               spin_unlock(dma_fence_spinlock(f));
> +       }
>         spin_unlock_irqrestore(&fence_drv->fence_list_lock, flags);
>  }
>
> --
> 2.34.1
>

Reply via email to