amdgpu_userq_wait_ioctl() takes extra references on waited-on fence drivers and stores them in waitq->fence_drv_xa. When a new userq fence is created, those references are transferred into userq_fence->fence_drv_array so they can be released when the fence completes.
However, those inherited references are currently only dropped from amdgpu_userq_fence_driver_process(). If a fence never reaches that path, such as it is already signaled when created or it is dropped through an error/cleanup path, amdgpu_userq_fence_free() frees fence_drv_array without putting the referenced fence drivers. Signed-off-by: Prike Liang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 3be80a82788a..bd196599d3d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -145,13 +145,21 @@ amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq) amdgpu_userq_fence_driver_put(userq->fence_drv); } +static void +amdgpu_userq_fence_put_fence_drv_array(struct amdgpu_userq_fence *userq_fence) +{ + unsigned long i; + for (i = 0; i < userq_fence->fence_drv_array_count; i++) + amdgpu_userq_fence_driver_put(userq_fence->fence_drv_array[i]); + userq_fence->fence_drv_array_count = 0; +} + void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_drv) { struct amdgpu_userq_fence *userq_fence, *tmp; struct dma_fence *fence; unsigned long flags; u64 rptr; - int i; if (!fence_drv) return; @@ -166,10 +174,7 @@ void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver *fence_d break; dma_fence_signal(fence); - - for (i = 0; i < userq_fence->fence_drv_array_count; i++) - amdgpu_userq_fence_driver_put(userq_fence->fence_drv_array[i]); - + amdgpu_userq_fence_put_fence_drv_array(userq_fence); list_del(&userq_fence->link); dma_fence_put(fence); } @@ -320,9 +325,9 @@ static void amdgpu_userq_fence_free(struct rcu_head *rcu) struct amdgpu_userq_fence *userq_fence = to_amdgpu_userq_fence(fence); struct amdgpu_userq_fence_driver *fence_drv = userq_fence->fence_drv; + amdgpu_userq_fence_put_fence_drv_array(userq_fence); /* Release the fence driver reference */ amdgpu_userq_fence_driver_put(fence_drv); - kvfree(userq_fence->fence_drv_array); kmem_cache_free(amdgpu_userq_fence_slab, userq_fence); } -- 2.34.1
