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 + prop->user_wptr, 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.
Signed-off-by: Jesse Zhang <[email protected]>
Suggested-by: Alexander Deucher <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 50 ++++++++++++++++++++++
include/uapi/drm/amdgpu_drm.h | 6 +++
2 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 99da719ecffb..6bc6984b8e95 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -627,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);
@@ -642,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);
}
@@ -704,6 +712,46 @@ 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;
+ }
+
+ 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;
+ userq_props->user_wptr = mes_userq_read_user_wptr(queue);
+
+ 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)
{
@@ -792,6 +840,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