summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>2025-12-11 04:02:55 +0300
committerNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>2025-12-12 06:21:14 +0300
commit71e7d7e81d6a08c2abb1bb1ff01107280db62abb (patch)
treea4126ca82d4ea4afe989319933a029760b671a63
parent2a31ea17d5c69e51ea454485edd40e4aeff467c1 (diff)
downloadlinux-71e7d7e81d6a08c2abb1bb1ff01107280db62abb.tar.xz
drm/xe/multi_queue: Add support for multi queue dynamic priority change
Support dynamic priority change for multi queue group queues via exec queue set_property ioctl. Issue CGP_SYNC command to GuC through the drm scheduler message interface for priority to take effect. v2: Move is_multi_queue check to exec_queue layer and assert is_multi_queue being set in guc submission layer (Matt Brost) v3: Assert CGP_SYNC message length is valid (Matt Brost) Signed-off-by: Pallavi Mishra <pallavi.mishra@intel.com> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20251211010249.1647839-26-niranjana.vishwanathapura@intel.com
-rw-r--r--drivers/gpu/drm/xe/xe_exec_queue.c11
-rw-r--r--drivers/gpu/drm/xe/xe_exec_queue_types.h3
-rw-r--r--drivers/gpu/drm/xe/xe_guc_submit.c57
3 files changed, 65 insertions, 6 deletions
diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
index d738a9fea1e1..256e2ce1fe69 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.c
+++ b/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -771,9 +771,16 @@ static int exec_queue_set_multi_queue_priority(struct xe_device *xe, struct xe_e
if (XE_IOCTL_DBG(xe, value > XE_MULTI_QUEUE_PRIORITY_HIGH))
return -EINVAL;
- q->multi_queue.priority = value;
+ /* For queue creation time (!q->xef) setting, just store the priority value */
+ if (!q->xef) {
+ q->multi_queue.priority = value;
+ return 0;
+ }
- return 0;
+ if (!xe_exec_queue_is_multi_queue(q))
+ return -EINVAL;
+
+ return q->ops->set_multi_queue_priority(q, value);
}
typedef int (*xe_exec_queue_set_property_fn)(struct xe_device *xe,
diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h
index 46e5f4715a0d..1c285ac12868 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue_types.h
+++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h
@@ -260,6 +260,9 @@ struct xe_exec_queue_ops {
int (*set_timeslice)(struct xe_exec_queue *q, u32 timeslice_us);
/** @set_preempt_timeout: Set preemption timeout for exec queue */
int (*set_preempt_timeout)(struct xe_exec_queue *q, u32 preempt_timeout_us);
+ /** @set_multi_queue_priority: Set multi queue priority */
+ int (*set_multi_queue_priority)(struct xe_exec_queue *q,
+ enum xe_multi_queue_priority priority);
/**
* @suspend: Suspend exec queue from executing, allowed to be called
* multiple times in a row before resume with the caveat that
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 7cca03d4296c..2f467cc1929f 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -1779,10 +1779,34 @@ static void __guc_exec_queue_process_msg_resume(struct xe_sched_msg *msg)
}
}
-#define CLEANUP 1 /* Non-zero values to catch uninitialized msg */
-#define SET_SCHED_PROPS 2
-#define SUSPEND 3
-#define RESUME 4
+static void __guc_exec_queue_process_msg_set_multi_queue_priority(struct xe_sched_msg *msg)
+{
+ struct xe_exec_queue *q = msg->private_data;
+
+ if (guc_exec_queue_allowed_to_change_state(q)) {
+#define MAX_MULTI_QUEUE_CGP_SYNC_SIZE (2)
+ struct xe_guc *guc = exec_queue_to_guc(q);
+ struct xe_exec_queue_group *group = q->multi_queue.group;
+ u32 action[MAX_MULTI_QUEUE_CGP_SYNC_SIZE];
+ int len = 0;
+
+ action[len++] = XE_GUC_ACTION_MULTI_QUEUE_CONTEXT_CGP_SYNC;
+ action[len++] = group->primary->guc->id;
+
+ xe_gt_assert(guc_to_gt(guc), len <= MAX_MULTI_QUEUE_CGP_SYNC_SIZE);
+#undef MAX_MULTI_QUEUE_CGP_SYNC_SIZE
+
+ xe_guc_exec_queue_group_cgp_sync(guc, q, action, len);
+ }
+
+ kfree(msg);
+}
+
+#define CLEANUP 1 /* Non-zero values to catch uninitialized msg */
+#define SET_SCHED_PROPS 2
+#define SUSPEND 3
+#define RESUME 4
+#define SET_MULTI_QUEUE_PRIORITY 5
#define OPCODE_MASK 0xf
#define MSG_LOCKED BIT(8)
#define MSG_HEAD BIT(9)
@@ -1806,6 +1830,9 @@ static void guc_exec_queue_process_msg(struct xe_sched_msg *msg)
case RESUME:
__guc_exec_queue_process_msg_resume(msg);
break;
+ case SET_MULTI_QUEUE_PRIORITY:
+ __guc_exec_queue_process_msg_set_multi_queue_priority(msg);
+ break;
default:
XE_WARN_ON("Unknown message type");
}
@@ -2022,6 +2049,27 @@ static int guc_exec_queue_set_preempt_timeout(struct xe_exec_queue *q,
return 0;
}
+static int guc_exec_queue_set_multi_queue_priority(struct xe_exec_queue *q,
+ enum xe_multi_queue_priority priority)
+{
+ struct xe_sched_msg *msg;
+
+ xe_gt_assert(guc_to_gt(exec_queue_to_guc(q)), xe_exec_queue_is_multi_queue(q));
+
+ if (q->multi_queue.priority == priority ||
+ exec_queue_killed_or_banned_or_wedged(q))
+ return 0;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ q->multi_queue.priority = priority;
+ guc_exec_queue_add_msg(q, msg, SET_MULTI_QUEUE_PRIORITY);
+
+ return 0;
+}
+
static int guc_exec_queue_suspend(struct xe_exec_queue *q)
{
struct xe_gpu_scheduler *sched = &q->guc->sched;
@@ -2113,6 +2161,7 @@ static const struct xe_exec_queue_ops guc_exec_queue_ops = {
.set_priority = guc_exec_queue_set_priority,
.set_timeslice = guc_exec_queue_set_timeslice,
.set_preempt_timeout = guc_exec_queue_set_preempt_timeout,
+ .set_multi_queue_priority = guc_exec_queue_set_multi_queue_priority,
.suspend = guc_exec_queue_suspend,
.suspend_wait = guc_exec_queue_suspend_wait,
.resume = guc_exec_queue_resume,