summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunil Khatri <sunil.khatri@amd.com>2026-05-20 14:09:49 +0300
committerAlex Deucher <alexander.deucher@amd.com>2026-05-27 17:50:02 +0300
commitef7dc711a664b0c548ecfdf13a00436b7446b8e7 (patch)
tree837854ea99cd99efabb1d4da355278fe527603c2
parent4ad65d610096498c8e265615aba42b3c47441bb5 (diff)
downloadlinux-ef7dc711a664b0c548ecfdf13a00436b7446b8e7.tar.xz
drm/amdgpu/userq: use array instead of list for userq_vas
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>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c88
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h20
-rw-r--r--drivers/gpu/drm/amd/amdgpu/mes_userqueue.c14
3 files changed, 45 insertions, 77 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 165dd9fa7b5e..5438d5fde878 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -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:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
index 76ef5cfab52e..28cfc6682333 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
@@ -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);
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 35af26b36d0d..09a6f50cc5f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -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);