amdgpu_userq_fence_driver_free() is now responsible only for releasing
per-queue ancillary state (last_fence, fence_drv_xa) and no longer
touches the ownership reference, making each function's contract clear.

Signed-off-by: Prike Liang <[email protected]>

v2: Get the userq fence driver from amdgpu_userq_fence_driver_alloc()
    directly and dropping the userq fence driver reference after removing
    userq_doorbell_xa entry.(Christian)
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c       |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 12 ++++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h |  2 +-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index c4841df80bf8..4f9f2e266562 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -458,9 +458,10 @@ static void amdgpu_userq_cleanup(struct 
amdgpu_usermode_queue *queue)
        /* Drop the userq reference. */
        amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
        uq_funcs->mqd_destroy(queue);
-       amdgpu_userq_fence_driver_free(queue);
        /* Use interrupt-safe locking since IRQ handlers may access these 
XArrays */
        xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index);
+       amdgpu_userq_fence_driver_free(queue);
+       queue->fence_drv = NULL;
        queue->userq_mgr = NULL;
        list_del(&queue->userq_va_list);
        kfree(queue);
@@ -799,7 +800,7 @@ amdgpu_userq_create(struct drm_file *filp, union 
drm_amdgpu_userq *args)
 
        queue->doorbell_index = index;
        xa_init_flags(&queue->fence_drv_xa, XA_FLAGS_ALLOC);
-       r = amdgpu_userq_fence_driver_alloc(adev, queue);
+       r = amdgpu_userq_fence_driver_alloc(adev, &queue->fence_drv);
        if (r) {
                drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n");
                goto free_queue;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index 87560c1251d8..3be80a82788a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -78,11 +78,15 @@ amdgpu_userq_fence_write(struct amdgpu_userq_fence_driver 
*fence_drv,
 }
 
 int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
-                                   struct amdgpu_usermode_queue *userq)
+                                   struct amdgpu_userq_fence_driver 
**fence_drv_req)
 {
        struct amdgpu_userq_fence_driver *fence_drv;
        int r;
 
+       if (!fence_drv_req)
+               return -EINVAL;
+       *fence_drv_req = NULL;
+
        fence_drv = kzalloc(sizeof(*fence_drv), GFP_KERNEL);
        if (!fence_drv)
                return -ENOMEM;
@@ -103,7 +107,7 @@ int amdgpu_userq_fence_driver_alloc(struct amdgpu_device 
*adev,
        fence_drv->context = dma_fence_context_alloc(1);
        get_task_comm(fence_drv->timeline_name, current);
 
-       userq->fence_drv = fence_drv;
+       *fence_drv_req = fence_drv;
 
        return 0;
 
@@ -134,10 +138,10 @@ void
 amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq)
 {
        dma_fence_put(userq->last_fence);
-
+       userq->last_fence = NULL;
        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 */
+       /* Drop the queue's ownership reference to fence_drv explicitly */
        amdgpu_userq_fence_driver_put(userq->fence_drv);
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
index d76add2afc77..d56246ad8c26 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.h
@@ -64,7 +64,7 @@ void amdgpu_userq_fence_slab_fini(void);
 void amdgpu_userq_fence_driver_get(struct amdgpu_userq_fence_driver 
*fence_drv);
 void amdgpu_userq_fence_driver_put(struct amdgpu_userq_fence_driver 
*fence_drv);
 int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev,
-                                   struct amdgpu_usermode_queue *userq);
+                                   struct amdgpu_userq_fence_driver 
**fence_drv_req);
 void amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq);
 void amdgpu_userq_fence_driver_process(struct amdgpu_userq_fence_driver 
*fence_drv);
 void amdgpu_userq_fence_driver_force_completion(struct amdgpu_usermode_queue 
*userq);
-- 
2.34.1

Reply via email to