From: Jesse Zhang <Jesse.Zhang@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: <Alexander.Deucher@amd.com>,
Christian Koenig <christian.koenig@amd.com>,
Jesse Zhang <Jesse.Zhang@amd.com>
Subject: [PATCH v4 8/8] drm/amdgpu/mes_userqueue: add SDMA MODIFY support
Date: Mon, 7 Sep 2026 09:45:35 +0800 [thread overview]
Message-ID: <20260907014629.2186163-8-Jesse.Zhang@amd.com> (raw)
In-Reply-To: <20260907014629.2186163-1-Jesse.Zhang@amd.com>
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 <Jesse.Zhang@amd.com>
Suggested-by: Alexander Deucher <Alexander.Deucher@amd.com>
---
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
next prev parent reply other threads:[~2026-09-07 1:46 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 1:45 [PATCH v4 1/8] drm/amdgpu/mes_userqueue: refactor mqd_update into per-IP helpers Jesse Zhang
2026-09-07 1:45 ` [PATCH v4 2/8] drm/amdgpu: add mqd_prop modify flag for queue MODIFY Jesse Zhang
2026-09-07 1:45 ` [PATCH v4 3/8] drm/amdgpu/gfx11: honor mqd_prop modify flag in init_mqd Jesse Zhang
2026-09-07 1:45 ` [PATCH v4 4/8] drm/amdgpu/gfx12: " Jesse Zhang
2026-09-07 1:45 ` [PATCH v4 5/8] drm/amdgpu/sdma6: " Jesse Zhang
2026-09-07 1:45 ` [PATCH v4 6/8] drm/amdgpu/sdma7: " Jesse Zhang
2026-09-07 1:45 ` [PATCH v4 7/8] drm/amdgpu/sdma7_1: " Jesse Zhang
2026-09-07 1:45 ` Jesse Zhang [this message]
2026-09-10 3:03 ` [PATCH v4 1/8] drm/amdgpu/mes_userqueue: refactor mqd_update into per-IP helpers Zhang, Jesse(Jie)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260907014629.2186163-8-Jesse.Zhang@amd.com \
--to=jesse.zhang@amd.com \
--cc=Alexander.Deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=christian.koenig@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox