mes_userq_mqd_update() only handled compute user queues and rejected
every other queue type with -EINVAL, so an SDMA user queue could not be
updated at runtime.

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 and ring base)
and re-init the MQD. Validate the queue type up front, then dispatch to
the SDMA or compute path based on queue_type.

This aligns KGD user queues with KFD, which already supports updating
SDMA queues via update_mqd_sdma.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 36 +++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index ad72ced472dd..03f6b5ab32ae 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -681,6 +681,36 @@ 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;
+       }
+
+       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;
+
+       retval = mqd_hw_default->init_mqd(adev, (void *)queue->mqd.cpu_ptr, 
userq_props);
+
+       kfree(sdma_mqd_v11);
+       return retval;
+}
+
 static int mes_userq_mqd_update(struct amdgpu_usermode_queue *queue, struct 
drm_amdgpu_userq_in *args_in)
 {
        int retval = 0;
@@ -692,9 +722,13 @@ static int mes_userq_mqd_update(struct 
amdgpu_usermode_queue *queue, struct drm_
        if (!queue || !userq_props)
                return -EINVAL;
 
-       if (queue->queue_type != AMDGPU_HW_IP_COMPUTE)
+       if (queue->queue_type != AMDGPU_HW_IP_COMPUTE &&
+           queue->queue_type != AMDGPU_HW_IP_DMA)
                return -EINVAL;
 
+       if (queue->queue_type == AMDGPU_HW_IP_DMA)
+               return mes_userq_sdma_mqd_update(queue, args_in);
+
        if (args_in->mqd_size != sizeof(*compute_mqd_v11)) {
                DRM_ERROR("Invalid compute IP MQD size\n");
                return -EINVAL;
-- 
2.49.0

Reply via email to