* [PATCH v4 2/6] drm/amdgpu: Add CU mask support for MQD properties
2026-01-28 10:58 [PATCH v4 1/6] drm/amdgpu: add mqd_update callback to AMDGPU user queue interface Jesse.Zhang
@ 2026-01-28 10:58 ` Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 3/6] drm/amdgpu/gfx11: add CU mask support for compute MQD initialization Jesse.Zhang
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jesse.Zhang @ 2026-01-28 10:58 UTC (permalink / raw)
To: amd-gfx
Cc: Alexander.Deucher, Christian Koenig, Jesse.Zhang, Alex Deucher,
Jesse Zhang
Add new fields to the amdgpu_mqd_prop structure to track CU (Compute Unit)
mask information, including the mask itself, count, flags, and a flag to
indicate if user-specified CU masking is active.
v2: Create a generic function amdgpu_gfx_mqd_symmetrically_map_cu_mask()
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 10 +++++
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 49 +++++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 2 +
3 files changed, 61 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 11a36c132905..a8f4f73fa0ce 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -789,6 +789,12 @@ struct amd_powerplay {
(rid == 0x01) || \
(rid == 0x10))))
+enum amdgpu_mqd_update_flag {
+ AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE = 1,
+ AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE = 2,
+ AMDGPU_UPDATE_FLAG_IS_GWS = 4, /* quirk for gfx9 IP */
+};
+
struct amdgpu_mqd_prop {
uint64_t mqd_gpu_addr;
uint64_t hqd_base_gpu_addr;
@@ -809,6 +815,10 @@ struct amdgpu_mqd_prop {
uint64_t fence_address;
bool tmz_queue;
bool kernel_queue;
+ uint32_t *cu_mask;
+ uint32_t cu_mask_count;
+ uint32_t cu_flags;
+ bool is_user_cu_masked;
};
struct amdgpu_mqd {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index 6abe5103a78d..73e6988cb703 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -501,6 +501,55 @@ void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id)
&ring->mqd_ptr);
}
+void amdgpu_gfx_mqd_symmetrically_map_cu_mask(struct amdgpu_device *adev, const uint32_t *cu_mask,
+ uint32_t cu_mask_count, uint32_t *se_mask)
+{
+ struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info;
+ struct amdgpu_gfx_config *gfx_info = &adev->gfx.config;
+ uint32_t cu_per_sh[8][4] = {0};
+ int i, se, sh, cu, cu_bitmap_sh_mul;
+ int xcc_inst = ffs(adev->gfx.xcc_mask) - 1;
+ bool wgp_mode_req = amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 0, 0);
+ int cu_inc = wgp_mode_req ? 2 : 1;
+ uint32_t en_mask = wgp_mode_req ? 0x3 : 0x1;
+ int num_xcc, inc, inst = 0;
+
+ if (xcc_inst < 0)
+ xcc_inst = 0;
+
+ num_xcc = hweight16(adev->gfx.xcc_mask);
+ if (!num_xcc)
+ num_xcc = 1;
+
+ inc = cu_inc * num_xcc;
+
+ cu_bitmap_sh_mul = 2;
+
+ for (se = 0; se < gfx_info->max_shader_engines; se++)
+ for (sh = 0; sh < gfx_info->max_sh_per_se; sh++)
+ cu_per_sh[se][sh] = hweight32(
+ cu_info->bitmap[xcc_inst][se % 4][sh + (se / 4) *
+ cu_bitmap_sh_mul]);
+
+ for (i = 0; i < gfx_info->max_shader_engines; i++)
+ se_mask[i] = 0;
+
+ i = inst;
+ for (cu = 0; cu < 16; cu += cu_inc) {
+ for (sh = 0; sh < gfx_info->max_sh_per_se; sh++) {
+ for (se = 0; se < gfx_info->max_shader_engines; se++) {
+ if (cu_per_sh[se][sh] > cu) {
+ if ((i / 32) < cu_mask_count && (cu_mask[i / 32] & (1 << (i % 32))))
+ se_mask[se] |= en_mask << (cu + sh * 16);
+ i += inc;
+ if (i >= cu_mask_count * 32)
+ return;
+ }
+ }
+ }
+ }
+}
+
int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id)
{
struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_id];
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
index 585cc8e81bb2..720ed3a2c78c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
@@ -583,6 +583,8 @@ int amdgpu_gfx_kiq_init(struct amdgpu_device *adev,
int amdgpu_gfx_mqd_sw_init(struct amdgpu_device *adev,
unsigned mqd_size, int xcc_id);
void amdgpu_gfx_mqd_sw_fini(struct amdgpu_device *adev, int xcc_id);
+void amdgpu_gfx_mqd_symmetrically_map_cu_mask(struct amdgpu_device *adev, const uint32_t *cu_mask,
+ uint32_t cu_mask_count, uint32_t *se_mask);
int amdgpu_gfx_disable_kcq(struct amdgpu_device *adev, int xcc_id);
int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev, int xcc_id);
int amdgpu_gfx_disable_kgq(struct amdgpu_device *adev, int xcc_id);
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 3/6] drm/amdgpu/gfx11: add CU mask support for compute MQD initialization
2026-01-28 10:58 [PATCH v4 1/6] drm/amdgpu: add mqd_update callback to AMDGPU user queue interface Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 2/6] drm/amdgpu: Add CU mask support for MQD properties Jesse.Zhang
@ 2026-01-28 10:58 ` Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 4/6] drm/amdgpu/gfx12: " Jesse.Zhang
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jesse.Zhang @ 2026-01-28 10:58 UTC (permalink / raw)
To: amd-gfx
Cc: Alexander.Deucher, Christian Koenig, Jesse.Zhang, Alex Deucher,
Jesse Zhang
Extend the GFX11 compute MQD initialization to support
Compute Unit (CU) masking for fine-grained resource allocation.
This allows compute queues to be limited to specific CUs for
performance isolation and debugging purposes.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 33 ++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 3a4ca104b161..55d98b1a9ac5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -4238,6 +4238,37 @@ static int gfx_v11_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
return gfx_v11_0_cp_gfx_start(adev);
}
+static void gfx_v11_0_compute_mqd_set_cu_mask(struct amdgpu_device *adev,
+ struct v11_compute_mqd *mqd,
+ struct amdgpu_mqd_prop *prop)
+{
+ uint32_t se_mask[8] = {0};
+ uint32_t wa_mask;
+ bool has_wa_flag = prop->cu_flags & (AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE |
+ AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE);
+
+ if (!has_wa_flag && (!prop->cu_mask || !prop->cu_mask_count))
+ return;
+
+ if (has_wa_flag) {
+ wa_mask = (prop->cu_flags & AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE) ?
+ 0xffff : 0xffffffff;
+ mqd->compute_static_thread_mgmt_se0 = wa_mask;
+ mqd->compute_static_thread_mgmt_se1 = wa_mask;
+ mqd->compute_static_thread_mgmt_se2 = wa_mask;
+ mqd->compute_static_thread_mgmt_se3 = wa_mask;
+ return;
+ }
+
+ amdgpu_gfx_mqd_symmetrically_map_cu_mask(adev, prop->cu_mask,
+ prop->cu_mask_count, se_mask);
+
+ mqd->compute_static_thread_mgmt_se0 = se_mask[0];
+ mqd->compute_static_thread_mgmt_se1 = se_mask[1];
+ mqd->compute_static_thread_mgmt_se2 = se_mask[2];
+ mqd->compute_static_thread_mgmt_se3 = se_mask[3];
+}
+
static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
struct amdgpu_mqd_prop *prop)
{
@@ -4372,6 +4403,8 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
/* set UQ fenceaddress */
mqd->fence_address_lo = lower_32_bits(prop->fence_address);
mqd->fence_address_hi = upper_32_bits(prop->fence_address);
+ /* set CU mask */
+ gfx_v11_0_compute_mqd_set_cu_mask(adev, mqd, prop);
return 0;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 4/6] drm/amdgpu/gfx12: add CU mask support for compute MQD initialization
2026-01-28 10:58 [PATCH v4 1/6] drm/amdgpu: add mqd_update callback to AMDGPU user queue interface Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 2/6] drm/amdgpu: Add CU mask support for MQD properties Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 3/6] drm/amdgpu/gfx11: add CU mask support for compute MQD initialization Jesse.Zhang
@ 2026-01-28 10:58 ` Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 5/6] drm/amdgpu: add MQD update support for user mode compute queues Jesse.Zhang
2026-01-28 10:58 ` [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for " Jesse.Zhang
4 siblings, 0 replies; 10+ messages in thread
From: Jesse.Zhang @ 2026-01-28 10:58 UTC (permalink / raw)
To: amd-gfx
Cc: Alexander.Deucher, Christian Koenig, Jesse.Zhang, Alex Deucher,
Jesse Zhang
Extend the GFX12 compute MQD initialization to support
Compute Unit (CU) masking for fine-grained resource allocation.
This allows compute queues to be limited to specific CUs for
performance isolation and debugging purposes.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
---
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 33 ++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index 6cd16f016c37..73478dd0f6ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3110,6 +3110,37 @@ static int gfx_v12_0_cp_async_gfx_ring_resume(struct amdgpu_device *adev)
return gfx_v12_0_cp_gfx_start(adev);
}
+static void gfx_v12_0_compute_mqd_set_cu_mask(struct amdgpu_device *adev,
+ struct v12_compute_mqd *mqd,
+ struct amdgpu_mqd_prop *prop)
+{
+ uint32_t se_mask[8] = {0};
+ uint32_t wa_mask;
+ bool has_wa_flag = prop->cu_flags & (AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE |
+ AMDGPU_UPDATE_FLAG_DBG_WA_DISABLE);
+
+ if (!has_wa_flag && (!prop->cu_mask || !prop->cu_mask_count))
+ return;
+
+ if (has_wa_flag) {
+ wa_mask = (prop->cu_flags & AMDGPU_UPDATE_FLAG_DBG_WA_ENABLE) ?
+ 0xffff : 0xffffffff;
+ mqd->compute_static_thread_mgmt_se0 = wa_mask;
+ mqd->compute_static_thread_mgmt_se1 = wa_mask;
+ mqd->compute_static_thread_mgmt_se2 = wa_mask;
+ mqd->compute_static_thread_mgmt_se3 = wa_mask;
+ return;
+ }
+
+ amdgpu_gfx_mqd_symmetrically_map_cu_mask(adev, prop->cu_mask,
+ prop->cu_mask_count, se_mask);
+
+ mqd->compute_static_thread_mgmt_se0 = se_mask[0];
+ mqd->compute_static_thread_mgmt_se1 = se_mask[1];
+ mqd->compute_static_thread_mgmt_se2 = se_mask[2];
+ mqd->compute_static_thread_mgmt_se3 = se_mask[3];
+}
+
static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
struct amdgpu_mqd_prop *prop)
{
@@ -3243,6 +3274,8 @@ static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
/* set UQ fenceaddress */
mqd->fence_address_lo = lower_32_bits(prop->fence_address);
mqd->fence_address_hi = upper_32_bits(prop->fence_address);
+ /* set CU mask */
+ gfx_v12_0_compute_mqd_set_cu_mask(adev, mqd, prop);
return 0;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 5/6] drm/amdgpu: add MQD update support for user mode compute queues
2026-01-28 10:58 [PATCH v4 1/6] drm/amdgpu: add mqd_update callback to AMDGPU user queue interface Jesse.Zhang
` (2 preceding siblings ...)
2026-01-28 10:58 ` [PATCH v4 4/6] drm/amdgpu/gfx12: " Jesse.Zhang
@ 2026-01-28 10:58 ` Jesse.Zhang
2026-02-03 14:22 ` Lazar, Lijo
2026-01-28 10:58 ` [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for " Jesse.Zhang
4 siblings, 1 reply; 10+ messages in thread
From: Jesse.Zhang @ 2026-01-28 10:58 UTC (permalink / raw)
To: amd-gfx
Cc: Alexander.Deucher, Christian Koenig, Jesse.Zhang, Alex Deucher,
Jesse Zhang
The update functionality allows dynamic adjustment of queue properties at runtime,
enabling better resource management and performance tuning for compute workloads.
v2: Return an error for non-compute queues. (Alex)
remove the parameter minfo
V3: put the new paramters in drm_amdgpu_userq_mqd_compute_gfx11. (Alex)
v4: move the define AMDGPU_USERQ_OP_MODIFY to patch 6/6 (Alex)
add the props input paramter to amdgpu_userq_set_compute_mqd
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +
drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 166 ++++++++++++++++++++-
include/uapi/drm/amdgpu_drm.h | 28 ++++
3 files changed, 194 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index a8f4f73fa0ce..ad136145316b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -819,6 +819,9 @@ struct amdgpu_mqd_prop {
uint32_t cu_mask_count;
uint32_t cu_flags;
bool is_user_cu_masked;
+ uint32_t queue_percentage;
+ /* used in gfx9 and gfx12.1 */
+ uint32_t pm4_target_xcc;
};
struct amdgpu_mqd {
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index f2309d72bbe6..d5251f2d7613 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -30,6 +30,26 @@
#define AMDGPU_USERQ_PROC_CTX_SZ PAGE_SIZE
#define AMDGPU_USERQ_GANG_CTX_SZ PAGE_SIZE
+/* Mapping queue priority to pipe priority, indexed by queue priority */
+int amdgpu_userq_pipe_priority_map[] = {
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_0,
+ AMDGPU_RING_PRIO_1,
+ AMDGPU_RING_PRIO_1,
+ AMDGPU_RING_PRIO_1,
+ AMDGPU_RING_PRIO_1,
+ AMDGPU_RING_PRIO_2,
+ AMDGPU_RING_PRIO_2,
+ AMDGPU_RING_PRIO_2,
+ AMDGPU_RING_PRIO_2,
+ AMDGPU_RING_PRIO_2
+};
+
static int
mes_userq_map_gtt_bo_to_gart(struct amdgpu_bo *bo)
{
@@ -272,6 +292,105 @@ static int mes_userq_detect_and_reset(struct amdgpu_device *adev,
return r;
}
+/**
+ * amdgpu_userq_set_compute_mqd - Parse compute MQD and update queue props
+ * @queue: Target user mode queue
+ * @props: Queue property structure to be updated
+ * @args: User queue input arguments
+ * @uq_mgr: User queue manager (for logging)
+ *
+ * This function only parses and validates user input, updating queue props
+ * (no hardware MQD configuration - that's handled in MES layer)
+ * Returns: 0 on success, negative error code on failure
+ */
+static int amdgpu_userq_set_compute_mqd(struct amdgpu_usermode_queue *queue,
+ struct amdgpu_mqd_prop *props,
+ struct drm_amdgpu_userq_mqd_compute_gfx11 * compute_mqd)
+{
+ struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
+ struct amdgpu_device *adev = uq_mgr->adev;
+ const int max_num_cus = 1024;
+ size_t cu_mask_size;
+ uint32_t count;
+ uint32_t *cu_mask = NULL;
+ int ret = 0;
+
+ if (!queue || !props || !compute_mqd)
+ return -EINVAL;
+
+ if (compute_mqd->queue_percentage > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE) {
+ DRM_ERROR("Queue percentage must be between 0 to AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE.\n");
+ return -EINVAL;
+ }
+
+ /* Validate priority */
+ if (compute_mqd->hqd_queue_priority > AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM) {
+ DRM_ERROR("Queue priority must be between 0 to AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM.\n");
+ return -EINVAL;
+ }
+
+
+ /* validate and set CU mask property */
+ if (compute_mqd->cu_mask_count) {
+ if (compute_mqd->cu_mask_count % 32 != 0) {
+ DRM_ERROR("CU mask count must be a multiple of 32.\n");
+ return -EINVAL;
+ }
+ count = compute_mqd->cu_mask_count;
+
+ /* Limit CU mask size to prevent excessive memory allocation */
+ if (count > max_num_cus) {
+ DRM_ERROR("CU mask cannot be greater than 1024 bits.\n");
+ count = max_num_cus;
+ cu_mask_size = sizeof(uint32_t) * (max_num_cus / 32);
+ } else {
+ cu_mask_size = sizeof(uint32_t) * (compute_mqd->cu_mask_count / 32);
+ }
+
+ /* Copy CU mask from user space */
+ cu_mask = memdup_user(u64_to_user_ptr(compute_mqd->cu_mask_ptr), cu_mask_size);
+ if (IS_ERR(cu_mask)) {
+ ret = PTR_ERR(cu_mask);
+ cu_mask = NULL;
+ goto cleanup;
+ }
+
+ /* Validate pairwise CU mask for WGP-based ASICs */
+ if (cu_mask && adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0)) {
+ for (int i = 0; i < count; i += 2) {
+ uint32_t cu_pair = (cu_mask[i / 32] >> (i % 32)) & 0x3;
+ if (cu_pair && cu_pair != 0x3) {
+ DRM_ERROR("CUs must be adjacent pairwise enabled.\n");
+ kfree(cu_mask);
+ cu_mask = NULL;
+ ret = -EINVAL;
+ goto cleanup;
+ }
+ }
+ }
+
+ /* Free old CU mask */
+ if (props->cu_mask) {
+ kfree(props->cu_mask);
+ props->cu_mask = NULL;
+ }
+
+ props->cu_mask = cu_mask;
+ props->cu_mask_count = count;
+ props->is_user_cu_masked = (cu_mask != NULL);
+ }
+
+ /* Parse HQD priority and other compute properties */
+ props->queue_percentage = compute_mqd->queue_percentage;
+ props->pm4_target_xcc = compute_mqd->pm4_target_xcc;
+ props->hqd_queue_priority = compute_mqd->hqd_queue_priority;
+ props->hqd_pipe_priority = amdgpu_userq_pipe_priority_map[compute_mqd->hqd_queue_priority];
+ props->eop_gpu_addr = compute_mqd->eop_va;
+
+cleanup:
+ return ret;
+}
+
static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
struct drm_amdgpu_userq_in *args_in)
{
@@ -325,10 +444,10 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
2048);
if (r)
goto free_mqd;
+ r = amdgpu_userq_set_compute_mqd(queue, userq_props, compute_mqd);
+ if (r)
+ goto free_mqd;
- userq_props->eop_gpu_addr = compute_mqd->eop_va;
- userq_props->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_NORMAL;
- userq_props->hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM;
userq_props->hqd_active = false;
userq_props->tmz_queue =
mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE;
@@ -432,11 +551,51 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
return r;
}
+static int mes_userq_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_compute_gfx11 *compute_mqd_v11;
+
+ if (!queue || !userq_props)
+ return -EINVAL;
+
+ if (queue->queue_type != AMDGPU_HW_IP_COMPUTE)
+ return -EINVAL;
+
+ if (args_in->mqd_size != sizeof(*compute_mqd_v11)) {
+ DRM_ERROR("Invalid compute IP MQD size\n");
+ return -EINVAL;
+ }
+
+ compute_mqd_v11 = memdup_user(u64_to_user_ptr(args_in->mqd), args_in->mqd_size);
+ if (IS_ERR(compute_mqd_v11)) {
+ DRM_ERROR("Failed to read user MQD\n");
+ return -ENOMEM;
+ }
+
+ retval = amdgpu_userq_set_compute_mqd(queue, userq_props, compute_mqd_v11);
+ if (retval)
+ goto free;
+
+ 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);
+
+free:
+ kfree(compute_mqd_v11);
+ return retval;
+}
+
static void mes_userq_mqd_destroy(struct amdgpu_usermode_queue *queue)
{
struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
amdgpu_userq_destroy_object(uq_mgr, &queue->fw_obj);
+ kfree(queue->userq_prop->cu_mask);
kfree(queue->userq_prop);
amdgpu_userq_destroy_object(uq_mgr, &queue->mqd);
}
@@ -513,6 +672,7 @@ static int mes_userq_restore(struct amdgpu_usermode_queue *queue)
const struct amdgpu_userq_funcs userq_mes_funcs = {
.mqd_create = mes_userq_mqd_create,
+ .mqd_update = mes_userq_mqd_update,
.mqd_destroy = mes_userq_mqd_destroy,
.unmap = mes_userq_unmap,
.map = mes_userq_map,
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index ab2bf47553e1..c52949ea8c1e 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -341,6 +341,7 @@ union drm_amdgpu_ctx {
#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_HIGH 3 /* admin only */
/* for queues that need access to protected content */
#define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE (1 << 2)
+#define AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE 100
/*
* This structure is a container to pass input configuration
@@ -460,6 +461,33 @@ struct drm_amdgpu_userq_mqd_compute_gfx11 {
* to get the size.
*/
__u64 eop_va;
+ /**
+ * @cu_mask_ptr: User-space pointer to CU (Compute Unit) mask array
+ * Points to an array of __u32 values that define which CUs are enabled
+ * for this queue (0 = disabled, 1 = enabled per bit)
+ */
+ __u64 cu_mask_ptr;
+ /**
+ * @cu_mask_count: Number of entries in the CU mask array
+ * Total count of __u32 elements in the cu_mask_ptr array (each element
+ * represents 32 CUs/WGPs)
+ */
+ __u32 cu_mask_count;
+ /**
+ * @queue_percentage: Queue resource allocation percentage (0-100)
+ * Defines the percentage of GPU resources allocated to this queue
+ */
+ __u32 queue_percentage;
+ /**
+ * @hqd_queue_priority: Hqd Queue priority (0-15)
+ * Higher values indicate higher scheduling priority for the queue
+ */
+ __u32 hqd_queue_priority;
+ /**
+ * @pm4_target_xcc: PM4 target XCC identifier (for gfx9/gfx12.1)
+ * Specifies the target XCC (Cross Compute Complex) for PM4 commands
+ */
+ __u32 pm4_target_xcc;
};
/* userq signal/wait ioctl */
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 5/6] drm/amdgpu: add MQD update support for user mode compute queues
2026-01-28 10:58 ` [PATCH v4 5/6] drm/amdgpu: add MQD update support for user mode compute queues Jesse.Zhang
@ 2026-02-03 14:22 ` Lazar, Lijo
0 siblings, 0 replies; 10+ messages in thread
From: Lazar, Lijo @ 2026-02-03 14:22 UTC (permalink / raw)
To: Jesse.Zhang, amd-gfx; +Cc: Alexander.Deucher, Christian Koenig
On 28-Jan-26 4:28 PM, Jesse.Zhang wrote:
> The update functionality allows dynamic adjustment of queue properties at runtime,
> enabling better resource management and performance tuning for compute workloads.
>
> v2: Return an error for non-compute queues. (Alex)
> remove the parameter minfo
>
> V3: put the new paramters in drm_amdgpu_userq_mqd_compute_gfx11. (Alex)
> v4: move the define AMDGPU_USERQ_OP_MODIFY to patch 6/6 (Alex)
> add the props input paramter to amdgpu_userq_set_compute_mqd
>
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
> Suggested-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +
> drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 166 ++++++++++++++++++++-
> include/uapi/drm/amdgpu_drm.h | 28 ++++
> 3 files changed, 194 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index a8f4f73fa0ce..ad136145316b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -819,6 +819,9 @@ struct amdgpu_mqd_prop {
> uint32_t cu_mask_count;
> uint32_t cu_flags;
> bool is_user_cu_masked;
> + uint32_t queue_percentage;
This field is not implemented in KFD itself apart from active/inactive.
Should this be kept in the same way?
Thanks,
Lijo
> + /* used in gfx9 and gfx12.1 */
> + uint32_t pm4_target_xcc;
> };
>
> struct amdgpu_mqd {
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> index f2309d72bbe6..d5251f2d7613 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> @@ -30,6 +30,26 @@
> #define AMDGPU_USERQ_PROC_CTX_SZ PAGE_SIZE
> #define AMDGPU_USERQ_GANG_CTX_SZ PAGE_SIZE
>
> +/* Mapping queue priority to pipe priority, indexed by queue priority */
> +int amdgpu_userq_pipe_priority_map[] = {
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_0,
> + AMDGPU_RING_PRIO_1,
> + AMDGPU_RING_PRIO_1,
> + AMDGPU_RING_PRIO_1,
> + AMDGPU_RING_PRIO_1,
> + AMDGPU_RING_PRIO_2,
> + AMDGPU_RING_PRIO_2,
> + AMDGPU_RING_PRIO_2,
> + AMDGPU_RING_PRIO_2,
> + AMDGPU_RING_PRIO_2
> +};
> +
> static int
> mes_userq_map_gtt_bo_to_gart(struct amdgpu_bo *bo)
> {
> @@ -272,6 +292,105 @@ static int mes_userq_detect_and_reset(struct amdgpu_device *adev,
> return r;
> }
>
> +/**
> + * amdgpu_userq_set_compute_mqd - Parse compute MQD and update queue props
> + * @queue: Target user mode queue
> + * @props: Queue property structure to be updated
> + * @args: User queue input arguments
> + * @uq_mgr: User queue manager (for logging)
> + *
> + * This function only parses and validates user input, updating queue props
> + * (no hardware MQD configuration - that's handled in MES layer)
> + * Returns: 0 on success, negative error code on failure
> + */
> +static int amdgpu_userq_set_compute_mqd(struct amdgpu_usermode_queue *queue,
> + struct amdgpu_mqd_prop *props,
> + struct drm_amdgpu_userq_mqd_compute_gfx11 * compute_mqd)
> +{
> + struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
> + struct amdgpu_device *adev = uq_mgr->adev;
> + const int max_num_cus = 1024;
> + size_t cu_mask_size;
> + uint32_t count;
> + uint32_t *cu_mask = NULL;
> + int ret = 0;
> +
> + if (!queue || !props || !compute_mqd)
> + return -EINVAL;
> +
> + if (compute_mqd->queue_percentage > AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE) {
> + DRM_ERROR("Queue percentage must be between 0 to AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE.\n");
> + return -EINVAL;
> + }
> +
> + /* Validate priority */
> + if (compute_mqd->hqd_queue_priority > AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM) {
> + DRM_ERROR("Queue priority must be between 0 to AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM.\n");
> + return -EINVAL;
> + }
> +
> +
> + /* validate and set CU mask property */
> + if (compute_mqd->cu_mask_count) {
> + if (compute_mqd->cu_mask_count % 32 != 0) {
> + DRM_ERROR("CU mask count must be a multiple of 32.\n");
> + return -EINVAL;
> + }
> + count = compute_mqd->cu_mask_count;
> +
> + /* Limit CU mask size to prevent excessive memory allocation */
> + if (count > max_num_cus) {
> + DRM_ERROR("CU mask cannot be greater than 1024 bits.\n");
> + count = max_num_cus;
> + cu_mask_size = sizeof(uint32_t) * (max_num_cus / 32);
> + } else {
> + cu_mask_size = sizeof(uint32_t) * (compute_mqd->cu_mask_count / 32);
> + }
> +
> + /* Copy CU mask from user space */
> + cu_mask = memdup_user(u64_to_user_ptr(compute_mqd->cu_mask_ptr), cu_mask_size);
> + if (IS_ERR(cu_mask)) {
> + ret = PTR_ERR(cu_mask);
> + cu_mask = NULL;
> + goto cleanup;
> + }
> +
> + /* Validate pairwise CU mask for WGP-based ASICs */
> + if (cu_mask && adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 0, 0)) {
> + for (int i = 0; i < count; i += 2) {
> + uint32_t cu_pair = (cu_mask[i / 32] >> (i % 32)) & 0x3;
> + if (cu_pair && cu_pair != 0x3) {
> + DRM_ERROR("CUs must be adjacent pairwise enabled.\n");
> + kfree(cu_mask);
> + cu_mask = NULL;
> + ret = -EINVAL;
> + goto cleanup;
> + }
> + }
> + }
> +
> + /* Free old CU mask */
> + if (props->cu_mask) {
> + kfree(props->cu_mask);
> + props->cu_mask = NULL;
> + }
> +
> + props->cu_mask = cu_mask;
> + props->cu_mask_count = count;
> + props->is_user_cu_masked = (cu_mask != NULL);
> + }
> +
> + /* Parse HQD priority and other compute properties */
> + props->queue_percentage = compute_mqd->queue_percentage;
> + props->pm4_target_xcc = compute_mqd->pm4_target_xcc;
> + props->hqd_queue_priority = compute_mqd->hqd_queue_priority;
> + props->hqd_pipe_priority = amdgpu_userq_pipe_priority_map[compute_mqd->hqd_queue_priority];
> + props->eop_gpu_addr = compute_mqd->eop_va;
> +
> +cleanup:
> + return ret;
> +}
> +
> static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
> struct drm_amdgpu_userq_in *args_in)
> {
> @@ -325,10 +444,10 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
> 2048);
> if (r)
> goto free_mqd;
> + r = amdgpu_userq_set_compute_mqd(queue, userq_props, compute_mqd);
> + if (r)
> + goto free_mqd;
>
> - userq_props->eop_gpu_addr = compute_mqd->eop_va;
> - userq_props->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_NORMAL;
> - userq_props->hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MINIMUM;
> userq_props->hqd_active = false;
> userq_props->tmz_queue =
> mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE;
> @@ -432,11 +551,51 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
> return r;
> }
>
> +static int mes_userq_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_compute_gfx11 *compute_mqd_v11;
> +
> + if (!queue || !userq_props)
> + return -EINVAL;
> +
> + if (queue->queue_type != AMDGPU_HW_IP_COMPUTE)
> + return -EINVAL;
> +
> + if (args_in->mqd_size != sizeof(*compute_mqd_v11)) {
> + DRM_ERROR("Invalid compute IP MQD size\n");
> + return -EINVAL;
> + }
> +
> + compute_mqd_v11 = memdup_user(u64_to_user_ptr(args_in->mqd), args_in->mqd_size);
> + if (IS_ERR(compute_mqd_v11)) {
> + DRM_ERROR("Failed to read user MQD\n");
> + return -ENOMEM;
> + }
> +
> + retval = amdgpu_userq_set_compute_mqd(queue, userq_props, compute_mqd_v11);
> + if (retval)
> + goto free;
> +
> + 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);
> +
> +free:
> + kfree(compute_mqd_v11);
> + return retval;
> +}
> +
> static void mes_userq_mqd_destroy(struct amdgpu_usermode_queue *queue)
> {
> struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr;
>
> amdgpu_userq_destroy_object(uq_mgr, &queue->fw_obj);
> + kfree(queue->userq_prop->cu_mask);
> kfree(queue->userq_prop);
> amdgpu_userq_destroy_object(uq_mgr, &queue->mqd);
> }
> @@ -513,6 +672,7 @@ static int mes_userq_restore(struct amdgpu_usermode_queue *queue)
>
> const struct amdgpu_userq_funcs userq_mes_funcs = {
> .mqd_create = mes_userq_mqd_create,
> + .mqd_update = mes_userq_mqd_update,
> .mqd_destroy = mes_userq_mqd_destroy,
> .unmap = mes_userq_unmap,
> .map = mes_userq_map,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index ab2bf47553e1..c52949ea8c1e 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -341,6 +341,7 @@ union drm_amdgpu_ctx {
> #define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_HIGH 3 /* admin only */
> /* for queues that need access to protected content */
> #define AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE (1 << 2)
> +#define AMDGPU_USERQ_MAX_QUEUE_PERCENTAGE 100
>
> /*
> * This structure is a container to pass input configuration
> @@ -460,6 +461,33 @@ struct drm_amdgpu_userq_mqd_compute_gfx11 {
> * to get the size.
> */
> __u64 eop_va;
> + /**
> + * @cu_mask_ptr: User-space pointer to CU (Compute Unit) mask array
> + * Points to an array of __u32 values that define which CUs are enabled
> + * for this queue (0 = disabled, 1 = enabled per bit)
> + */
> + __u64 cu_mask_ptr;
> + /**
> + * @cu_mask_count: Number of entries in the CU mask array
> + * Total count of __u32 elements in the cu_mask_ptr array (each element
> + * represents 32 CUs/WGPs)
> + */
> + __u32 cu_mask_count;
> + /**
> + * @queue_percentage: Queue resource allocation percentage (0-100)
> + * Defines the percentage of GPU resources allocated to this queue
> + */
> + __u32 queue_percentage;
> + /**
> + * @hqd_queue_priority: Hqd Queue priority (0-15)
> + * Higher values indicate higher scheduling priority for the queue
> + */
> + __u32 hqd_queue_priority;
> + /**
> + * @pm4_target_xcc: PM4 target XCC identifier (for gfx9/gfx12.1)
> + * Specifies the target XCC (Cross Compute Complex) for PM4 commands
> + */
> + __u32 pm4_target_xcc;
> };
>
> /* userq signal/wait ioctl */
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
2026-01-28 10:58 [PATCH v4 1/6] drm/amdgpu: add mqd_update callback to AMDGPU user queue interface Jesse.Zhang
` (3 preceding siblings ...)
2026-01-28 10:58 ` [PATCH v4 5/6] drm/amdgpu: add MQD update support for user mode compute queues Jesse.Zhang
@ 2026-01-28 10:58 ` Jesse.Zhang
2026-01-30 8:30 ` Zhang, Jesse(Jie)
` (2 more replies)
4 siblings, 3 replies; 10+ messages in thread
From: Jesse.Zhang @ 2026-01-28 10:58 UTC (permalink / raw)
To: amd-gfx
Cc: Alexander.Deucher, Christian Koenig, Jesse.Zhang, Alex Deucher,
Jesse Zhang
Implement the AMDGPU_USERQ_OP_MODIFY ioctl operation to enable runtime updates
of compute queues.
v2: move queue size validate to a separate patch
remove the check for AMDGPU_HW_IP_COMPUTE (Alex)
Suggested-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 61 +++++++++++++++++++++++
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 3 ++
include/uapi/drm/amdgpu_drm.h | 1 +
3 files changed, 65 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 256ceca6d429..3003aba22e1d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -837,6 +837,7 @@ static int amdgpu_userq_input_args_validate(struct drm_device *dev,
switch (args->in.op) {
case AMDGPU_USERQ_OP_CREATE:
+ case AMDGPU_USERQ_OP_MODIFY:
if (args->in.flags & ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |
AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))
return -EINVAL;
@@ -901,6 +902,60 @@ bool amdgpu_userq_enabled(struct drm_device *dev)
return false;
}
+static int amdgpu_modify_queue(struct drm_file *filp, union drm_amdgpu_userq *args)
+{
+ struct amdgpu_fpriv *fpriv = filp->driver_priv;
+ struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
+ struct amdgpu_device *adev = uq_mgr->adev;
+ struct amdgpu_usermode_queue *queue;
+ const struct amdgpu_userq_funcs *userq_funcs;
+ int r;
+
+ mutex_lock(&uq_mgr->userq_mutex);
+ queue = amdgpu_userq_find(uq_mgr, args->in.queue_id);
+ if (!queue) {
+ drm_file_err(uq_mgr->file, "Queue %u not found\n", args->in.queue_id);
+ r = -EINVAL;
+ goto unlock;
+ }
+
+ userq_funcs = adev->userq_funcs[queue->queue_type];
+
+ /*
+ * Unmap the queue if it's mapped or preempted to ensure a clean update.
+ * If the queue is already unmapped or hung, we skip this step.
+ */
+ if (queue->state == AMDGPU_USERQ_STATE_MAPPED ||
+ queue->state == AMDGPU_USERQ_STATE_PREEMPTED) {
+ r = amdgpu_userq_unmap_helper(queue);
+ if (r) {
+ drm_file_err(uq_mgr->file, "Failed to unmap queue %llu\n",
+ queue->doorbell_index);
+ goto unlock;
+ }
+ }
+
+ r = userq_funcs->mqd_update(queue, &args->in);
+ if (r)
+ goto unlock;
+ /*
+ * If the queue is considered active (has valid size, address, and percentage),
+ * we attempt to map it. This effectively starts the queue or restarts it
+ * if it was previously running.
+ */
+ if (AMDGPU_USERQ_IS_ACTIVE(queue)) {
+ r = amdgpu_userq_map_helper(queue);
+ if (r)
+ drm_file_err(uq_mgr->file, "Failed to remap queue %llu after update\n",
+ queue->doorbell_index);
+ }
+
+unlock:
+ mutex_unlock(&uq_mgr->userq_mutex);
+
+ return r;
+}
+
int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
@@ -920,6 +975,12 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
drm_file_err(filp, "Failed to create usermode queue\n");
break;
+
+ case AMDGPU_USERQ_OP_MODIFY:
+ r = amdgpu_modify_queue(filp, args);
+ if (r)
+ drm_file_err(filp, "Failed to modify usermode queue\n");
+ break;
case AMDGPU_USERQ_OP_FREE:
r = amdgpu_userq_destroy(filp, args->in.queue_id);
if (r)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
index 833468b58603..7cd1ea94e368 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
@@ -31,6 +31,9 @@
#define to_ev_fence(f) container_of(f, struct amdgpu_eviction_fence, base)
#define uq_mgr_to_fpriv(u) container_of(u, struct amdgpu_fpriv, userq_mgr)
#define work_to_uq_mgr(w, name) container_of(w, struct amdgpu_userq_mgr, name)
+#define AMDGPU_USERQ_IS_ACTIVE(q) ((q)->userq_prop->queue_size > 0 && \
+ (q)->userq_prop->hqd_base_gpu_addr != 0 && \
+ (q)->userq_prop->queue_percentage > 0)
enum amdgpu_userq_state {
AMDGPU_USERQ_STATE_UNMAPPED = 0,
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index c52949ea8c1e..aa9b31578c6b 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -330,6 +330,7 @@ union drm_amdgpu_ctx {
/* user queue IOCTL operations */
#define AMDGPU_USERQ_OP_CREATE 1
#define AMDGPU_USERQ_OP_FREE 2
+#define AMDGPU_USERQ_OP_MODIFY 3
/* queue priority levels */
/* low < normal low < normal high < high */
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* RE: [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
2026-01-28 10:58 ` [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for " Jesse.Zhang
@ 2026-01-30 8:30 ` Zhang, Jesse(Jie)
2026-02-02 23:33 ` Zhang, Jesse(Jie)
2026-02-03 14:06 ` Alex Deucher
2 siblings, 0 replies; 10+ messages in thread
From: Zhang, Jesse(Jie) @ 2026-01-30 8:30 UTC (permalink / raw)
To: Zhang, Jesse(Jie), amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander, Koenig, Christian, Deucher, Alexander
[AMD Official Use Only - AMD Internal Distribution Only]
Ping ...
> -----Original Message-----
> From: Jesse.Zhang <Jesse.Zhang@amd.com>
> Sent: Wednesday, January 28, 2026 6:58 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Koenig, Christian
> <Christian.Koenig@amd.com>; Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>;
> Deucher, Alexander <Alexander.Deucher@amd.com>; Zhang, Jesse(Jie)
> <Jesse.Zhang@amd.com>
> Subject: [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
>
> Implement the AMDGPU_USERQ_OP_MODIFY ioctl operation to enable runtime
> updates of compute queues.
>
> v2: move queue size validate to a separate patch
> remove the check for AMDGPU_HW_IP_COMPUTE (Alex)
>
> Suggested-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 61
> +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 3
> ++
> include/uapi/drm/amdgpu_drm.h | 1 +
> 3 files changed, 65 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 256ceca6d429..3003aba22e1d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -837,6 +837,7 @@ static int amdgpu_userq_input_args_validate(struct
> drm_device *dev,
>
> switch (args->in.op) {
> case AMDGPU_USERQ_OP_CREATE:
> + case AMDGPU_USERQ_OP_MODIFY:
> if (args->in.flags &
> ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |
>
> AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))
> return -EINVAL;
> @@ -901,6 +902,60 @@ bool amdgpu_userq_enabled(struct drm_device *dev)
> return false;
> }
>
> +static int amdgpu_modify_queue(struct drm_file *filp, union
> +drm_amdgpu_userq *args) {
> + struct amdgpu_fpriv *fpriv = filp->driver_priv;
> + struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
> + struct amdgpu_device *adev = uq_mgr->adev;
> + struct amdgpu_usermode_queue *queue;
> + const struct amdgpu_userq_funcs *userq_funcs;
> + int r;
> +
> + mutex_lock(&uq_mgr->userq_mutex);
> + queue = amdgpu_userq_find(uq_mgr, args->in.queue_id);
> + if (!queue) {
> + drm_file_err(uq_mgr->file, "Queue %u not found\n", args-
> >in.queue_id);
> + r = -EINVAL;
> + goto unlock;
> + }
> +
> + userq_funcs = adev->userq_funcs[queue->queue_type];
> +
> + /*
> + * Unmap the queue if it's mapped or preempted to ensure a clean update.
> + * If the queue is already unmapped or hung, we skip this step.
> + */
> + if (queue->state == AMDGPU_USERQ_STATE_MAPPED ||
> + queue->state == AMDGPU_USERQ_STATE_PREEMPTED) {
> + r = amdgpu_userq_unmap_helper(queue);
> + if (r) {
> + drm_file_err(uq_mgr->file, "Failed to unmap queue %llu\n",
> + queue->doorbell_index);
> + goto unlock;
> + }
> + }
> +
> + r = userq_funcs->mqd_update(queue, &args->in);
> + if (r)
> + goto unlock;
> + /*
> + * If the queue is considered active (has valid size, address, and
> percentage),
> + * we attempt to map it. This effectively starts the queue or restarts it
> + * if it was previously running.
> + */
> + if (AMDGPU_USERQ_IS_ACTIVE(queue)) {
> + r = amdgpu_userq_map_helper(queue);
> + if (r)
> + drm_file_err(uq_mgr->file, "Failed to remap queue %llu after
> update\n",
> + queue->doorbell_index);
> + }
> +
> +unlock:
> + mutex_unlock(&uq_mgr->userq_mutex);
> +
> + return r;
> +}
> +
> int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> struct drm_file *filp)
> {
> @@ -920,6 +975,12 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void
> *data,
> drm_file_err(filp, "Failed to create usermode queue\n");
> break;
>
> +
> + case AMDGPU_USERQ_OP_MODIFY:
> + r = amdgpu_modify_queue(filp, args);
> + if (r)
> + drm_file_err(filp, "Failed to modify usermode queue\n");
> + break;
> case AMDGPU_USERQ_OP_FREE:
> r = amdgpu_userq_destroy(filp, args->in.queue_id);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> index 833468b58603..7cd1ea94e368 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> @@ -31,6 +31,9 @@
> #define to_ev_fence(f) container_of(f, struct amdgpu_eviction_fence, base)
> #define uq_mgr_to_fpriv(u) container_of(u, struct amdgpu_fpriv, userq_mgr)
> #define work_to_uq_mgr(w, name) container_of(w, struct amdgpu_userq_mgr,
> name)
> +#define AMDGPU_USERQ_IS_ACTIVE(q) ((q)->userq_prop->queue_size > 0 &&
> \
> + (q)->userq_prop->hqd_base_gpu_addr != 0 && \
> + (q)->userq_prop->queue_percentage > 0)
>
> enum amdgpu_userq_state {
> AMDGPU_USERQ_STATE_UNMAPPED = 0,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index
> c52949ea8c1e..aa9b31578c6b 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -330,6 +330,7 @@ union drm_amdgpu_ctx {
> /* user queue IOCTL operations */
> #define AMDGPU_USERQ_OP_CREATE 1
> #define AMDGPU_USERQ_OP_FREE 2
> +#define AMDGPU_USERQ_OP_MODIFY 3
>
> /* queue priority levels */
> /* low < normal low < normal high < high */
> --
> 2.49.0
^ permalink raw reply [flat|nested] 10+ messages in thread* RE: [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
2026-01-28 10:58 ` [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for " Jesse.Zhang
2026-01-30 8:30 ` Zhang, Jesse(Jie)
@ 2026-02-02 23:33 ` Zhang, Jesse(Jie)
2026-02-03 14:06 ` Alex Deucher
2 siblings, 0 replies; 10+ messages in thread
From: Zhang, Jesse(Jie) @ 2026-02-02 23:33 UTC (permalink / raw)
To: Zhang, Jesse(Jie), amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander, Koenig, Christian, Deucher, Alexander
[AMD Official Use Only - AMD Internal Distribution Only]
Ping...
> -----Original Message-----
> From: Jesse.Zhang <Jesse.Zhang@amd.com>
> Sent: Wednesday, January 28, 2026 6:58 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Koenig, Christian
> <Christian.Koenig@amd.com>; Zhang, Jesse(Jie) <Jesse.Zhang@amd.com>;
> Deucher, Alexander <Alexander.Deucher@amd.com>; Zhang, Jesse(Jie)
> <Jesse.Zhang@amd.com>
> Subject: [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
>
> Implement the AMDGPU_USERQ_OP_MODIFY ioctl operation to enable runtime
> updates of compute queues.
>
> v2: move queue size validate to a separate patch
> remove the check for AMDGPU_HW_IP_COMPUTE (Alex)
>
> Suggested-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 61
> +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 3
> ++
> include/uapi/drm/amdgpu_drm.h | 1 +
> 3 files changed, 65 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 256ceca6d429..3003aba22e1d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -837,6 +837,7 @@ static int amdgpu_userq_input_args_validate(struct
> drm_device *dev,
>
> switch (args->in.op) {
> case AMDGPU_USERQ_OP_CREATE:
> + case AMDGPU_USERQ_OP_MODIFY:
> if (args->in.flags &
> ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |
>
> AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))
> return -EINVAL;
> @@ -901,6 +902,60 @@ bool amdgpu_userq_enabled(struct drm_device *dev)
> return false;
> }
>
> +static int amdgpu_modify_queue(struct drm_file *filp, union
> +drm_amdgpu_userq *args) {
> + struct amdgpu_fpriv *fpriv = filp->driver_priv;
> + struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
> + struct amdgpu_device *adev = uq_mgr->adev;
> + struct amdgpu_usermode_queue *queue;
> + const struct amdgpu_userq_funcs *userq_funcs;
> + int r;
> +
> + mutex_lock(&uq_mgr->userq_mutex);
> + queue = amdgpu_userq_find(uq_mgr, args->in.queue_id);
> + if (!queue) {
> + drm_file_err(uq_mgr->file, "Queue %u not found\n", args-
> >in.queue_id);
> + r = -EINVAL;
> + goto unlock;
> + }
> +
> + userq_funcs = adev->userq_funcs[queue->queue_type];
> +
> + /*
> + * Unmap the queue if it's mapped or preempted to ensure a clean update.
> + * If the queue is already unmapped or hung, we skip this step.
> + */
> + if (queue->state == AMDGPU_USERQ_STATE_MAPPED ||
> + queue->state == AMDGPU_USERQ_STATE_PREEMPTED) {
> + r = amdgpu_userq_unmap_helper(queue);
> + if (r) {
> + drm_file_err(uq_mgr->file, "Failed to unmap queue %llu\n",
> + queue->doorbell_index);
> + goto unlock;
> + }
> + }
> +
> + r = userq_funcs->mqd_update(queue, &args->in);
> + if (r)
> + goto unlock;
> + /*
> + * If the queue is considered active (has valid size, address, and
> percentage),
> + * we attempt to map it. This effectively starts the queue or restarts it
> + * if it was previously running.
> + */
> + if (AMDGPU_USERQ_IS_ACTIVE(queue)) {
> + r = amdgpu_userq_map_helper(queue);
> + if (r)
> + drm_file_err(uq_mgr->file, "Failed to remap queue %llu after
> update\n",
> + queue->doorbell_index);
> + }
> +
> +unlock:
> + mutex_unlock(&uq_mgr->userq_mutex);
> +
> + return r;
> +}
> +
> int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> struct drm_file *filp)
> {
> @@ -920,6 +975,12 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void
> *data,
> drm_file_err(filp, "Failed to create usermode queue\n");
> break;
>
> +
> + case AMDGPU_USERQ_OP_MODIFY:
> + r = amdgpu_modify_queue(filp, args);
> + if (r)
> + drm_file_err(filp, "Failed to modify usermode queue\n");
> + break;
> case AMDGPU_USERQ_OP_FREE:
> r = amdgpu_userq_destroy(filp, args->in.queue_id);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> index 833468b58603..7cd1ea94e368 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> @@ -31,6 +31,9 @@
> #define to_ev_fence(f) container_of(f, struct amdgpu_eviction_fence, base)
> #define uq_mgr_to_fpriv(u) container_of(u, struct amdgpu_fpriv, userq_mgr)
> #define work_to_uq_mgr(w, name) container_of(w, struct amdgpu_userq_mgr,
> name)
> +#define AMDGPU_USERQ_IS_ACTIVE(q) ((q)->userq_prop->queue_size > 0 &&
> \
> + (q)->userq_prop->hqd_base_gpu_addr != 0 && \
> + (q)->userq_prop->queue_percentage > 0)
>
> enum amdgpu_userq_state {
> AMDGPU_USERQ_STATE_UNMAPPED = 0,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index
> c52949ea8c1e..aa9b31578c6b 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -330,6 +330,7 @@ union drm_amdgpu_ctx {
> /* user queue IOCTL operations */
> #define AMDGPU_USERQ_OP_CREATE 1
> #define AMDGPU_USERQ_OP_FREE 2
> +#define AMDGPU_USERQ_OP_MODIFY 3
>
> /* queue priority levels */
> /* low < normal low < normal high < high */
> --
> 2.49.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for compute queues
2026-01-28 10:58 ` [PATCH v4 6/6] drm/amdgpu: add MODIFY operation for " Jesse.Zhang
2026-01-30 8:30 ` Zhang, Jesse(Jie)
2026-02-02 23:33 ` Zhang, Jesse(Jie)
@ 2026-02-03 14:06 ` Alex Deucher
2 siblings, 0 replies; 10+ messages in thread
From: Alex Deucher @ 2026-02-03 14:06 UTC (permalink / raw)
To: Jesse.Zhang; +Cc: amd-gfx, Alexander.Deucher, Christian Koenig
On Wed, Jan 28, 2026 at 6:07 AM Jesse.Zhang <Jesse.Zhang@amd.com> wrote:
>
> Implement the AMDGPU_USERQ_OP_MODIFY ioctl operation to enable runtime updates
> of compute queues.
>
> v2: move queue size validate to a separate patch
> remove the check for AMDGPU_HW_IP_COMPUTE (Alex)
>
> Suggested-by: Alex Deucher <alexander.deucher@amd.com>
> Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 61 +++++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 3 ++
> include/uapi/drm/amdgpu_drm.h | 1 +
> 3 files changed, 65 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 256ceca6d429..3003aba22e1d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -837,6 +837,7 @@ static int amdgpu_userq_input_args_validate(struct drm_device *dev,
>
> switch (args->in.op) {
> case AMDGPU_USERQ_OP_CREATE:
> + case AMDGPU_USERQ_OP_MODIFY:
> if (args->in.flags & ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |
> AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))
> return -EINVAL;
> @@ -901,6 +902,60 @@ bool amdgpu_userq_enabled(struct drm_device *dev)
> return false;
> }
>
> +static int amdgpu_modify_queue(struct drm_file *filp, union drm_amdgpu_userq *args)
> +{
> + struct amdgpu_fpriv *fpriv = filp->driver_priv;
> + struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr;
> + struct amdgpu_device *adev = uq_mgr->adev;
> + struct amdgpu_usermode_queue *queue;
> + const struct amdgpu_userq_funcs *userq_funcs;
> + int r;
> +
> + mutex_lock(&uq_mgr->userq_mutex);
> + queue = amdgpu_userq_find(uq_mgr, args->in.queue_id);
> + if (!queue) {
> + drm_file_err(uq_mgr->file, "Queue %u not found\n", args->in.queue_id);
> + r = -EINVAL;
> + goto unlock;
> + }
> +
> + userq_funcs = adev->userq_funcs[queue->queue_type];
> +
> + /*
> + * Unmap the queue if it's mapped or preempted to ensure a clean update.
> + * If the queue is already unmapped or hung, we skip this step.
> + */
> + if (queue->state == AMDGPU_USERQ_STATE_MAPPED ||
> + queue->state == AMDGPU_USERQ_STATE_PREEMPTED) {
> + r = amdgpu_userq_unmap_helper(queue);
> + if (r) {
> + drm_file_err(uq_mgr->file, "Failed to unmap queue %llu\n",
> + queue->doorbell_index);
> + goto unlock;
> + }
> + }
> +
> + r = userq_funcs->mqd_update(queue, &args->in);
> + if (r)
> + goto unlock;
> + /*
> + * If the queue is considered active (has valid size, address, and percentage),
> + * we attempt to map it. This effectively starts the queue or restarts it
> + * if it was previously running.
> + */
> + if (AMDGPU_USERQ_IS_ACTIVE(queue)) {
> + r = amdgpu_userq_map_helper(queue);
> + if (r)
> + drm_file_err(uq_mgr->file, "Failed to remap queue %llu after update\n",
> + queue->doorbell_index);
> + }
> +
> +unlock:
> + mutex_unlock(&uq_mgr->userq_mutex);
> +
> + return r;
> +}
> +
> int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> struct drm_file *filp)
> {
> @@ -920,6 +975,12 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> drm_file_err(filp, "Failed to create usermode queue\n");
> break;
>
> +
> + case AMDGPU_USERQ_OP_MODIFY:
> + r = amdgpu_modify_queue(filp, args);
> + if (r)
> + drm_file_err(filp, "Failed to modify usermode queue\n");
> + break;
> case AMDGPU_USERQ_OP_FREE:
> r = amdgpu_userq_destroy(filp, args->in.queue_id);
> if (r)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> index 833468b58603..7cd1ea94e368 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h
> @@ -31,6 +31,9 @@
> #define to_ev_fence(f) container_of(f, struct amdgpu_eviction_fence, base)
> #define uq_mgr_to_fpriv(u) container_of(u, struct amdgpu_fpriv, userq_mgr)
> #define work_to_uq_mgr(w, name) container_of(w, struct amdgpu_userq_mgr, name)
> +#define AMDGPU_USERQ_IS_ACTIVE(q) ((q)->userq_prop->queue_size > 0 && \
> + (q)->userq_prop->hqd_base_gpu_addr != 0 && \
> + (q)->userq_prop->queue_percentage > 0)
>
> enum amdgpu_userq_state {
> AMDGPU_USERQ_STATE_UNMAPPED = 0,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index c52949ea8c1e..aa9b31578c6b 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -330,6 +330,7 @@ union drm_amdgpu_ctx {
> /* user queue IOCTL operations */
> #define AMDGPU_USERQ_OP_CREATE 1
> #define AMDGPU_USERQ_OP_FREE 2
> +#define AMDGPU_USERQ_OP_MODIFY 3
>
> /* queue priority levels */
> /* low < normal low < normal high < high */
> --
> 2.49.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread