Series is: Reviewed-by: Alex Deucher <[email protected]>
On Sun, Sep 6, 2026 at 9:46 PM Jesse Zhang <[email protected]> wrote: > > Add mes_userq_sdma_mqd_update() to update an SDMA queue's MQD from a > drm_amdgpu_userq_mqd_sdma_gfx11 (csa address, queue size, ring base), > re-init it in place via prop->modify, and wire it into the queue_type > dispatcher. This aligns KGD user queues with KFD's update_mqd_sdma. > > v3: re-init the MQD via the mqd_prop modify flag instead of a separate > update_mqd callback, per review. > v4: keep the context-saved wptr instead of forwarding a user_wptr, per > review. > > Signed-off-by: Jesse Zhang <[email protected]> > Suggested-by: Alexander Deucher <[email protected]> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 1 + > drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 104 ++++++++++++++++++++- > include/uapi/drm/amdgpu_drm.h | 12 +++ > 3 files changed, 116 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > index 686c92e96025..5210ec381be7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c > @@ -840,6 +840,7 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring > *ring, > prop->use_doorbell = ring->use_doorbell; > prop->doorbell_index = ring->doorbell_index; > prop->kernel_queue = true; > + prop->modify = false; > > /* map_queues packet doesn't need activate the queue, > * so only kiq need set this field. > diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > index 82bb4369451e..5b53e6ec8897 100644 > --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c > @@ -479,6 +479,7 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > userq_props->use_doorbell = true; > userq_props->doorbell_index = queue->doorbell_index; > userq_props->fence_address = queue->fence_drv->gpu_addr; > + userq_props->modify = false; > > if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { > struct drm_amdgpu_userq_mqd_compute_gfx11 *compute_mqd; > @@ -573,8 +574,16 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > goto free_mqd; > } > > + if (mqd_gfx_v11->queue_percentage > > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE) { > + DRM_ERROR("Queue percentage must be between 0 to > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE.\n"); > + r = -EINVAL; > + kfree(mqd_gfx_v11); > + goto free_mqd; > + } > + > userq_props->shadow_addr = mqd_gfx_v11->shadow_va; > userq_props->csa_addr = mqd_gfx_v11->csa_va; > + userq_props->queue_percentage = mqd_gfx_v11->queue_percentage; > userq_props->tmz_queue = > mqd_user->flags & > AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; > > @@ -618,6 +627,13 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > goto free_mqd; > } > > + if (mqd_sdma_v11->queue_percentage > > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE) { > + DRM_ERROR("Queue percentage must be between 0 to > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE.\n"); > + r = -EINVAL; > + kfree(mqd_sdma_v11); > + goto free_mqd; > + } > + > r = amdgpu_bo_reserve(queue->vm->root.bo, false); > if (r) { > kfree(mqd_sdma_v11); > @@ -633,6 +649,7 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > } > > userq_props->csa_addr = mqd_sdma_v11->csa_va; > + userq_props->queue_percentage = > mqd_sdma_v11->queue_percentage; > kfree(mqd_sdma_v11); > } > > @@ -681,6 +698,85 @@ static int mes_userq_mqd_create(struct > amdgpu_usermode_queue *queue, > return r; > } > > +static int mes_userq_sdma_mqd_update(struct amdgpu_usermode_queue *queue, > + struct drm_amdgpu_userq_in *args_in) > +{ > + int retval = 0; > + struct amdgpu_device *adev = queue->userq_mgr->adev; > + struct amdgpu_mqd_prop *userq_props = queue->userq_prop; > + struct amdgpu_mqd *mqd_hw_default = &adev->mqds[queue->queue_type]; > + struct drm_amdgpu_userq_mqd_sdma_gfx11 *sdma_mqd_v11; > + > + if (args_in->mqd_size != sizeof(*sdma_mqd_v11)) { > + DRM_ERROR("Invalid SDMA IP MQD size\n"); > + return -EINVAL; > + } > + > + sdma_mqd_v11 = memdup_user(u64_to_user_ptr(args_in->mqd), > args_in->mqd_size); > + if (IS_ERR(sdma_mqd_v11)) { > + DRM_ERROR("Failed to read user MQD\n"); > + return -ENOMEM; > + } > + > + if (sdma_mqd_v11->queue_percentage > > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE) { > + DRM_ERROR("Queue percentage must be between 0 to > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE.\n"); > + kfree(sdma_mqd_v11); > + return -EINVAL; > + } > + > + userq_props->csa_addr = sdma_mqd_v11->csa_va; > + userq_props->queue_size = args_in->queue_size; > + userq_props->hqd_base_gpu_addr = args_in->queue_va; > + userq_props->queue_percentage = sdma_mqd_v11->queue_percentage; > + userq_props->modify = true; > + > + retval = mqd_hw_default->init_mqd(adev, (void *)queue->mqd.cpu_ptr, > + userq_props); > + > + kfree(sdma_mqd_v11); > + return retval; > +} > + > +static int mes_userq_gfx_mqd_update(struct amdgpu_usermode_queue *queue, > + struct drm_amdgpu_userq_in *args_in) > +{ > + int retval = 0; > + struct amdgpu_device *adev = queue->userq_mgr->adev; > + struct amdgpu_mqd_prop *userq_props = queue->userq_prop; > + struct amdgpu_mqd *mqd_hw_default = &adev->mqds[queue->queue_type]; > + struct drm_amdgpu_userq_mqd_gfx11 *gfx_mqd_v11; > + > + if (args_in->mqd_size != sizeof(*gfx_mqd_v11)) { > + DRM_ERROR("Invalid GFX IP MQD size\n"); > + return -EINVAL; > + } > + > + gfx_mqd_v11 = memdup_user(u64_to_user_ptr(args_in->mqd), > args_in->mqd_size); > + if (IS_ERR(gfx_mqd_v11)) { > + DRM_ERROR("Failed to read user MQD\n"); > + return -ENOMEM; > + } > + > + if (gfx_mqd_v11->queue_percentage > > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE) { > + DRM_ERROR("Queue percentage must be between 0 to > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE.\n"); > + kfree(gfx_mqd_v11); > + return -EINVAL; > + } > + > + userq_props->shadow_addr = gfx_mqd_v11->shadow_va; > + userq_props->csa_addr = gfx_mqd_v11->csa_va; > + userq_props->queue_size = args_in->queue_size; > + userq_props->hqd_base_gpu_addr = args_in->queue_va; > + userq_props->queue_percentage = gfx_mqd_v11->queue_percentage; > + userq_props->modify = true; > + > + retval = mqd_hw_default->init_mqd(adev, (void *)queue->mqd.cpu_ptr, > + userq_props); > + > + kfree(gfx_mqd_v11); > + return retval; > +} > + > static int mes_userq_compute_mqd_update(struct amdgpu_usermode_queue *queue, > struct drm_amdgpu_userq_in *args_in) > { > @@ -707,8 +803,10 @@ static int mes_userq_compute_mqd_update(struct > amdgpu_usermode_queue *queue, > > userq_props->queue_size = args_in->queue_size; > userq_props->hqd_base_gpu_addr = args_in->queue_va; > + userq_props->modify = true; > > - retval = mqd_hw_default->init_mqd(adev, (void *)queue->mqd.cpu_ptr, > userq_props); > + retval = mqd_hw_default->init_mqd(adev, (void *)queue->mqd.cpu_ptr, > + userq_props); > > free: > kfree(compute_mqd_v11); > @@ -723,6 +821,10 @@ static int mes_userq_mqd_update(struct > amdgpu_usermode_queue *queue, struct drm_ > switch (queue->queue_type) { > case AMDGPU_HW_IP_COMPUTE: > return mes_userq_compute_mqd_update(queue, args_in); > + case AMDGPU_HW_IP_GFX: > + return mes_userq_gfx_mqd_update(queue, args_in); > + case AMDGPU_HW_IP_DMA: > + return mes_userq_sdma_mqd_update(queue, args_in); > default: > return -EINVAL; > } > diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h > index 2de47ff7c4d0..94497d1217b8 100644 > --- a/include/uapi/drm/amdgpu_drm.h > +++ b/include/uapi/drm/amdgpu_drm.h > @@ -449,6 +449,12 @@ struct drm_amdgpu_userq_mqd_gfx11 { > * Use AMDGPU_INFO_IOCTL to find the exact size of the object. > */ > __u64 csa_va; > + /** > + * @queue_percentage: Queue resource allocation percentage (0-100) > + * Defines the percentage of GPU resources allocated to this queue. > + * A value of 0 marks the queue inactive and it will not be mapped. > + */ > + __u32 queue_percentage; > }; > > /* GFX V11 SDMA IP specific MQD parameters */ > @@ -459,6 +465,12 @@ struct drm_amdgpu_userq_mqd_sdma_gfx11 { > * to get the size. > */ > __u64 csa_va; > + /** > + * @queue_percentage: Queue resource allocation percentage (0-100) > + * Defines the percentage of GPU resources allocated to this queue. > + * A value of 0 marks the queue inactive and it will not be mapped. > + */ > + __u32 queue_percentage; > }; > > /* GFX V11 Compute IP specific MQD parameters */ > -- > 2.49.0 >
