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
>

Reply via email to