]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdgpu/userq: use array instead of list for userq_vas
authorSunil Khatri <sunil.khatri@amd.com>
Wed, 20 May 2026 11:09:49 +0000 (16:39 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 27 May 2026 16:01:42 +0000 (12:01 -0400)
Use arrays instead of list for userq_vas since we have fixed no
of bos. Also, we dont have to worry to free that memory later
since this array would be free along with queue only.

Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ef7dc711a664b0c548ecfdf13a00436b7446b8e7)

drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
drivers/gpu/drm/amd/amdgpu/mes_userqueue.c

index 28a1849e7dcd1038b312b0c4daccf4b1bea658e4..cf192500800f8086b042c4afacfe1303819fcf67 100644 (file)
@@ -215,33 +215,15 @@ void amdgpu_userq_process_fence_irq(struct amdgpu_device *adev, u32 doorbell)
        xa_unlock_irqrestore(xa, flags);
 }
 
-static int amdgpu_userq_buffer_va_list_add(struct amdgpu_usermode_queue *queue,
-                                          struct amdgpu_bo_va_mapping *va_map, u64 addr)
-{
-       struct amdgpu_userq_va_cursor *va_cursor;
-       struct userq_va_list;
-
-       va_cursor = kzalloc_obj(*va_cursor);
-       if (!va_cursor)
-               return -ENOMEM;
-
-       INIT_LIST_HEAD(&va_cursor->list);
-       va_cursor->gpu_addr = addr;
-       va_map->bo_va->userq_va_mapped = true;
-       list_add(&va_cursor->list, &queue->userq_va_list);
-
-       return 0;
-}
-
 int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
                                   struct amdgpu_usermode_queue *queue,
-                                  u64 addr, u64 expected_size)
+                                  u64 addr, u64 expected_size,
+                                  u64 *va_out)
 {
        struct amdgpu_bo_va_mapping *va_map;
        struct amdgpu_vm *vm = queue->vm;
        u64 user_addr;
        u64 size;
-       int r = 0;
 
        /* Caller must hold vm->root.bo reservation */
        dma_resv_assert_held(queue->vm->root.bo->tbo.base.resv);
@@ -250,20 +232,18 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
        size = expected_size >> AMDGPU_GPU_PAGE_SHIFT;
 
        va_map = amdgpu_vm_bo_lookup_mapping(vm, user_addr);
-       if (!va_map) {
-               r = -EINVAL;
-               goto out_err;
-       }
+       if (!va_map)
+               return -EINVAL;
+
        /* Only validate the userq whether resident in the VM mapping range */
        if (user_addr >= va_map->start  &&
            va_map->last - user_addr + 1 >= size) {
-               amdgpu_userq_buffer_va_list_add(queue, va_map, user_addr);
+               va_map->bo_va->userq_va_mapped = true;
+               *va_out = user_addr;
                return 0;
        }
 
-       r = -EINVAL;
-out_err:
-       return r;
+       return -EINVAL;
 }
 
 static bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr)
@@ -284,14 +264,16 @@ static bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr)
 
 static bool amdgpu_userq_buffer_vas_mapped(struct amdgpu_usermode_queue *queue)
 {
-       struct amdgpu_userq_va_cursor *va_cursor, *tmp;
-       int r = 0;
+       int i, r = 0;
 
-       list_for_each_entry_safe(va_cursor, tmp, &queue->userq_va_list, list) {
-               r += amdgpu_userq_buffer_va_mapped(queue->vm, va_cursor->gpu_addr);
+       for (i = 0; i < ARRAY_SIZE(queue->userq_vas.va_array); i++) {
+               if (!queue->userq_vas.va_array[i])
+                       continue;
+               r += amdgpu_userq_buffer_va_mapped(queue->vm,
+                                                  queue->userq_vas.va_array[i]);
                dev_dbg(queue->userq_mgr->adev->dev,
                        "validate the userq mapping:%p va:%llx r:%d\n",
-                       queue, va_cursor->gpu_addr, r);
+                       queue, queue->userq_vas.va_array[i], r);
        }
 
        if (r != 0)
@@ -300,24 +282,7 @@ static bool amdgpu_userq_buffer_vas_mapped(struct amdgpu_usermode_queue *queue)
        return false;
 }
 
-static void amdgpu_userq_buffer_vas_list_cleanup(struct amdgpu_device *adev,
-                                                struct amdgpu_usermode_queue *queue)
-{
-       struct amdgpu_userq_va_cursor *va_cursor, *tmp;
-       struct amdgpu_bo_va_mapping *mapping;
 
-       /* Caller must hold vm->root.bo reservation */
-       dma_resv_assert_held(queue->vm->root.bo->tbo.base.resv);
-
-       list_for_each_entry_safe(va_cursor, tmp, &queue->userq_va_list, list) {
-               mapping = amdgpu_vm_bo_lookup_mapping(queue->vm, va_cursor->gpu_addr);
-               if (mapping)
-                       dev_dbg(adev->dev, "delete the userq:%p va:%llx\n",
-                               queue, va_cursor->gpu_addr);
-               list_del(&va_cursor->list);
-               kfree(va_cursor);
-       }
-}
 
 static int amdgpu_userq_preempt_helper(struct amdgpu_usermode_queue *queue)
 {
@@ -540,7 +505,6 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_que
 {
        struct amdgpu_device *adev = uq_mgr->adev;
        const struct amdgpu_userq_funcs *uq_funcs = adev->userq_funcs[queue->queue_type];
-       struct amdgpu_vm *vm = queue->vm;
        int r = 0;
 
        cancel_delayed_work_sync(&uq_mgr->resume_work);
@@ -560,10 +524,6 @@ amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_que
        mutex_unlock(&uq_mgr->userq_mutex);
 
        cancel_delayed_work_sync(&queue->hang_detect_work);
-       amdgpu_bo_reserve(vm->root.bo, true);
-       amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
-       amdgpu_bo_unreserve(vm->root.bo);
-       list_del(&queue->userq_va_list);
        uq_funcs->mqd_destroy(queue);
        queue->userq_mgr = NULL;
 
@@ -669,7 +629,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
        }
 
        kref_init(&queue->refcount);
-       INIT_LIST_HEAD(&queue->userq_va_list);
        queue->doorbell_handle = args->in.doorbell_handle;
        queue->queue_type = args->in.ip_type;
        queue->vm = &fpriv->vm;
@@ -690,14 +649,17 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
                goto free_fence_drv;
 
        if (amdgpu_userq_input_va_validate(adev, queue, args->in.queue_va,
-                                          args->in.queue_size) ||
+                                          args->in.queue_size,
+                                          &queue->userq_vas.va.queue_rb) ||
            amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va,
-                                          AMDGPU_GPU_PAGE_SIZE) ||
+                                          AMDGPU_GPU_PAGE_SIZE,
+                                          &queue->userq_vas.va.rptr) ||
            amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va,
-                                          AMDGPU_GPU_PAGE_SIZE)) {
+                                          AMDGPU_GPU_PAGE_SIZE,
+                                          &queue->userq_vas.va.wptr)) {
                r = -EINVAL;
                amdgpu_bo_unreserve(fpriv->vm.root.bo);
-               goto clean_mapping;
+               goto free_fence_drv;
        }
        amdgpu_bo_unreserve(fpriv->vm.root.bo);
 
@@ -709,7 +671,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
        r = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp, &index);
        if (r) {
                drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n");
-               goto clean_mapping;
+               goto free_fence_drv;
        }
 
        queue->doorbell_index = index;
@@ -769,10 +731,6 @@ clean_doorbell_bo:
        amdgpu_bo_unpin(queue->db_obj.obj);
        amdgpu_bo_unreserve(queue->db_obj.obj);
        amdgpu_bo_unref(&queue->db_obj.obj);
-clean_mapping:
-       amdgpu_bo_reserve(fpriv->vm.root.bo, true);
-       amdgpu_userq_buffer_vas_list_cleanup(adev, queue);
-       amdgpu_bo_unreserve(fpriv->vm.root.bo);
 free_fence_drv:
        amdgpu_userq_fence_driver_free(queue);
 free_queue:
index 76ef5cfab52ec735f55486928dda4186045e9c29..28cfc668233379b759ef2b4630392b2cd2458c39 100644 (file)
@@ -48,11 +48,6 @@ struct amdgpu_userq_obj {
        struct amdgpu_bo *obj;
 };
 
-struct amdgpu_userq_va_cursor {
-       u64                     gpu_addr;
-       struct list_head        list;
-};
-
 struct amdgpu_usermode_queue {
        int                     queue_type;
        enum amdgpu_userq_state state;
@@ -93,7 +88,17 @@ struct amdgpu_usermode_queue {
        struct delayed_work     hang_detect_work;
        struct kref             refcount;
 
-       struct list_head        userq_va_list;
+       union {
+               struct {
+                       u64 queue_rb;
+                       u64 wptr;
+                       u64 rptr;
+                       u64 eop;
+                       u64 shadow;
+                       u64 csa;
+               } va;
+               u64 va_array[6];
+       } userq_vas;
 };
 
 struct amdgpu_userq_funcs {
@@ -174,7 +179,8 @@ void amdgpu_userq_process_fence_irq(struct amdgpu_device *adev, u32 doorbell);
 
 int amdgpu_userq_input_va_validate(struct amdgpu_device *adev,
                                   struct amdgpu_usermode_queue *queue,
-                                  u64 addr, u64 expected_size);
+                                  u64 addr, u64 expected_size, u64 *va_out);
+
 void amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev,
                                        struct amdgpu_bo_va_mapping *mapping,
                                        uint64_t saddr);
index 71251370c8b3d7b429fd40d686d41b5878b88e62..98aa00eeb2f472e5b100801abeb4c5ed6b659ac9 100644 (file)
@@ -318,8 +318,9 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
                        kfree(compute_mqd);
                        goto free_mqd;
                }
-               r = amdgpu_userq_input_va_validate(adev, queue, compute_mqd->eop_va,
-                                                  2048);
+               r = amdgpu_userq_input_va_validate(adev, queue,
+                                                  compute_mqd->eop_va, 2048,
+                                                  &queue->userq_vas.va.eop);
                amdgpu_bo_unreserve(queue->vm->root.bo);
                if (r) {
                        kfree(compute_mqd);
@@ -368,7 +369,8 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
                        goto free_mqd;
                }
                r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->shadow_va,
-                                                  shadow_info.shadow_size);
+                                                  shadow_info.shadow_size,
+                                                  &queue->userq_vas.va.shadow);
                if (r) {
                        amdgpu_bo_unreserve(queue->vm->root.bo);
                        kfree(mqd_gfx_v11);
@@ -376,7 +378,8 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
                }
 
                r = amdgpu_userq_input_va_validate(adev, queue, mqd_gfx_v11->csa_va,
-                                                  shadow_info.csa_size);
+                                                  shadow_info.csa_size,
+                                                  &queue->userq_vas.va.csa);
                amdgpu_bo_unreserve(queue->vm->root.bo);
                if (r) {
                        kfree(mqd_gfx_v11);
@@ -406,7 +409,8 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
                        goto free_mqd;
                }
                r = amdgpu_userq_input_va_validate(adev, queue, mqd_sdma_v11->csa_va,
-                                                  32);
+                                                  32,
+                                                  &queue->userq_vas.va.csa);
                amdgpu_bo_unreserve(queue->vm->root.bo);
                if (r) {
                        kfree(mqd_sdma_v11);