On 1/14/26 12:28, Srinivasan Shanmugam wrote:
> The user mode queue keeps a pointer to the most recent fence in
> userq->last_fence. This pointer holds an extra dma_fence reference.
>
> When the queue is destroyed, we free the fence driver and its xarray,
> but we forgot to drop the last_fence reference.
>
> Because of the missing dma_fence_put(), the last fence object can stay
> alive when the driver unloads. This leaves an allocated object in the
> amdgpu_userq_fence slab cache and triggers
>
> This is visible during driver unload as:
>
> BUG amdgpu_userq_fence: Objects remaining on __kmem_cache_shutdown()
> kmem_cache_destroy amdgpu_userq_fence: Slab cache still has objects
> Call Trace:
> kmem_cache_destroy
> amdgpu_userq_fence_slab_fini
> amdgpu_exit
> __do_sys_delete_module
>
> Fix this by putting userq->last_fence and clearing the pointer during
> amdgpu_userq_fence_driver_free().
>
> This makes sure the fence reference is released and the slab cache is
> empty when the module exits.
>
> v2: Update to only release userq->last_fence with dma_fence_put()
> (Christian)
>
> Fixes: edc762a51c71 ("drm/amdgpu/userq: move some code around")
> Cc: Alex Deucher <[email protected]>
> Cc: Christian König <[email protected]>
> Signed-off-by: Srinivasan Shanmugam <[email protected]>
Reviewed-by: Christian König <[email protected]>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> index 3c6bd5531627..8d7420a9a113 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
> @@ -141,6 +141,8 @@ static void amdgpu_userq_walk_and_drop_fence_drv(struct
> xarray *xa)
> void
> amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq)
> {
> + dma_fence_put(userq->last_fence);
> +
> amdgpu_userq_walk_and_drop_fence_drv(&userq->fence_drv_xa);
> xa_destroy(&userq->fence_drv_xa);
> /* Drop the fence_drv reference held by user queue */