On Fri, Sep 12, 2025 at 1:55 AM Prike Liang <prike.li...@amd.com> wrote: > > Add the userq object virtual address get(),mapped() and put() > helpers for tracking the userq obj va address usage. > > Signed-off-by: Prike Liang <prike.li...@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 73 ++++++++++++++++++++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 17 ++++- > drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 13 ++-- > 4 files changed, 90 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > index 87523fcd4386..912c9afaf9e1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h > @@ -96,6 +96,7 @@ struct amdgpu_bo_va { > * if non-zero, cannot unmap from GPU because user queues may still > access it > */ > unsigned int queue_refcount; > + atomic_t userq_va_mapped; > }; > > struct amdgpu_bo { > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > index ba7be4db5a01..19a400bd4be1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c > @@ -44,7 +44,8 @@ u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device > *adev) > return userq_ip_mask; > } > > -int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, > +int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, > + struct amdgpu_vm *vm, u64 addr, > u64 expected_size) > { > struct amdgpu_bo_va_mapping *va_map; > @@ -67,6 +68,7 @@ int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, > u64 addr, > /* 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_get(queue, va_map, user_addr); > amdgpu_bo_unreserve(vm->root.bo); > return 0; > } > @@ -76,6 +78,66 @@ int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, > u64 addr, > return r; > } > > +int amdgpu_userq_buffer_va_get(struct amdgpu_usermode_queue *queue, > + struct amdgpu_bo_va_mapping *va_map, u64 addr)
I'd rename this to amdgpu_userq_buffer_va_list_add(). We aren't really treating this like a reference count. we are just adding it to a list. > +{ > + struct amdgpu_userq_va_cursor *va_cursor; > + struct userq_va_list; > + > + va_cursor = kzalloc(sizeof(*va_cursor), GFP_KERNEL); > + if (!va_cursor) > + return -ENOMEM; > + > + INIT_LIST_HEAD(&va_cursor->list); > + va_cursor->gpu_addr = addr; > + atomic_set(&va_map->bo_va->userq_va_mapped, 1); > + list_add(&va_cursor->list, &queue->userq_va_list); > + > + return 0; > + > +} > + > +bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr) > +{ > + struct amdgpu_bo_va_mapping *mapping; > + bool r; > + > + if (amdgpu_bo_reserve(vm->root.bo, false)) > + return false; > + > + mapping = amdgpu_vm_bo_lookup_mapping(vm, addr); > + if (!IS_ERR_OR_NULL(mapping) && > atomic_read(&mapping->bo_va->userq_va_mapped)) > + r = true; > + else > + r = false; > + amdgpu_bo_unreserve(vm->root.bo); > + > + return r; > +} > + > +int amdgpu_userq_buffer_va_put(struct amdgpu_vm *vm, And here amdgpu_userq_buffer_va_list_del(). Alex > + u64 addr) > +{ > + struct amdgpu_bo_va_mapping *mapping; > + int r; > + > + r = amdgpu_bo_reserve(vm->root.bo, false); > + if (r) > + return r; > + > + mapping = amdgpu_vm_bo_lookup_mapping(vm, addr); > + if (!mapping) > + goto out_err; > + > + atomic_set(&mapping->bo_va->userq_va_mapped, 0); > + amdgpu_bo_unreserve(vm->root.bo); > + return 0; > + > +out_err: > + amdgpu_bo_unreserve(vm->root.bo); > + return -EINVAL; > +} > + > static int > amdgpu_userq_unmap_helper(struct amdgpu_userq_mgr *uq_mgr, > struct amdgpu_usermode_queue *queue) > @@ -141,6 +203,7 @@ amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr, > uq_funcs->mqd_destroy(uq_mgr, queue); > amdgpu_userq_fence_driver_free(queue); > idr_remove(&uq_mgr->userq_idr, queue_id); > + list_del(&queue->userq_va_list); > kfree(queue); > } > > @@ -461,10 +524,11 @@ amdgpu_userq_create(struct drm_file *filp, union > drm_amdgpu_userq *args) > goto unlock; > } > > + INIT_LIST_HEAD(&queue->userq_va_list); > /* Validate the userq virtual address.*/ > - if (amdgpu_userq_input_va_validate(&fpriv->vm, args->in.queue_va, > args->in.queue_size) || > - amdgpu_userq_input_va_validate(&fpriv->vm, args->in.rptr_va, > AMDGPU_GPU_PAGE_SIZE) || > - amdgpu_userq_input_va_validate(&fpriv->vm, args->in.wptr_va, > AMDGPU_GPU_PAGE_SIZE)) { > + if (amdgpu_userq_input_va_validate(queue, &fpriv->vm, > args->in.queue_va, args->in.queue_size) || > + amdgpu_userq_input_va_validate(queue, &fpriv->vm, > args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE ) || > + amdgpu_userq_input_va_validate(queue, &fpriv->vm, > args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { > kfree(queue); > goto unlock; > } > @@ -504,7 +568,6 @@ amdgpu_userq_create(struct drm_file *filp, union > drm_amdgpu_userq *args) > goto unlock; > } > > - > qid = idr_alloc(&uq_mgr->userq_idr, queue, 1, AMDGPU_MAX_USERQ_COUNT, > GFP_KERNEL); > if (qid < 0) { > drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n"); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > index 33a582200dda..e4c2d7cabd15 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h > @@ -48,12 +48,19 @@ struct amdgpu_userq_obj { > struct amdgpu_bo *obj; > }; > > +struct amdgpu_userq_va_cursor { > + uint64_t gpu_addr; > + struct list_head list; > +}; > + > struct amdgpu_usermode_queue { > int queue_type; > enum amdgpu_userq_state state; > uint64_t doorbell_handle; > uint64_t doorbell_index; > + > uint64_t flags; > + > struct amdgpu_mqd_prop *userq_prop; > struct amdgpu_userq_mgr *userq_mgr; > struct amdgpu_vm *vm; > @@ -68,6 +75,8 @@ struct amdgpu_usermode_queue { > int priority; > struct dentry *debugfs_queue; > uint64_t generation; > + > + struct list_head userq_va_list; > }; > > struct amdgpu_userq_funcs { > @@ -138,7 +147,11 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct > amdgpu_device *adev, > u32 idx); > int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device > *adev, > u32 idx); > - > -int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, > +int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, > + struct amdgpu_vm *vm, u64 addr, > u64 expected_size); > +int amdgpu_userq_buffer_va_get(struct amdgpu_usermode_queue *queue, > + struct amdgpu_bo_va_mapping *va_map, u64 addr); > +bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr); > +int amdgpu_userq_buffer_va_put(struct amdgpu_vm *vm, u64 addr); > #endif > diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > index 3a4fd6de08ce..e10e4b6a10d6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > @@ -298,8 +298,8 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr > *uq_mgr, > goto free_mqd; > } > > - if (amdgpu_userq_input_va_validate(queue->vm, > compute_mqd->eop_va, > - max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE))) > + if (amdgpu_userq_input_va_validate(queue, queue->vm, > compute_mqd->eop_va, > + max_t(u32, PAGE_SIZE, > AMDGPU_GPU_PAGE_SIZE))) > goto free_mqd; > > userq_props->eop_gpu_addr = compute_mqd->eop_va; > @@ -330,8 +330,8 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr > *uq_mgr, > userq_props->tmz_queue = > mqd_user->flags & > AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; > > - if (amdgpu_userq_input_va_validate(queue->vm, > mqd_gfx_v11->shadow_va, > - shadow_info.shadow_size)) > + if (amdgpu_userq_input_va_validate(queue, queue->vm, > mqd_gfx_v11->shadow_va, > + shadow_info.shadow_size)) > goto free_mqd; > > kfree(mqd_gfx_v11); > @@ -350,9 +350,8 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr > *uq_mgr, > r = -ENOMEM; > goto free_mqd; > } > - > - if (amdgpu_userq_input_va_validate(queue->vm, > mqd_sdma_v11->csa_va, > - shadow_info.csa_size)) > + if (amdgpu_userq_input_va_validate(queue, queue->vm, > mqd_sdma_v11->csa_va, > + shadow_info.csa_size)) > goto free_mqd; > > userq_props->csa_addr = mqd_sdma_v11->csa_va; > -- > 2.34.1 >