Add the SDMA case to the mqd_update dispatcher, routing it through the
per-IP update_mqd callback like compute and GFX. Add a queue_percentage
field to drm_amdgpu_userq_mqd_sdma_gfx11 and plumb it through create; 0
marks the queue inactive so it is not remapped, aligning KGD SDMA user
queues with KFD (which controls activeness the same way via
update_mqd_sdma).

Signed-off-by: Jesse Zhang <[email protected]>
Suggested-by: Alexander Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 54 ++++++++++++++++++++++
 include/uapi/drm/amdgpu_drm.h              |  6 +++
 2 files changed, 60 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 3059224dd9ad..d9ddc0085d44 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -626,6 +626,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);
@@ -641,6 +648,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);
        }
 
@@ -708,6 +716,50 @@ static u64 mes_userq_read_user_wptr(struct 
amdgpu_usermode_queue *queue)
        return user_wptr;
 }
 
+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;
+       }
+
+       if (!mqd_hw_default->update_mqd) {
+               DRM_ERROR("SDMA MQD update not supported on this IP\n");
+               return -EOPNOTSUPP;
+       }
+
+       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;
+
+       retval = mqd_hw_default->update_mqd(adev, (void *)queue->mqd.cpu_ptr,
+                                           userq_props,
+                                           mes_userq_read_user_wptr(queue));
+
+       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)
 {
@@ -804,6 +856,8 @@ static int mes_userq_mqd_update(struct 
amdgpu_usermode_queue *queue, struct drm_
                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 da2016f42a2e..94497d1217b8 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -465,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