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
This commit is contained in:
Niranjana Vishwanathapura
2025-12-10 17:02:55 -08:00
parent 2a31ea17d5
commit 71e7d7e81d
3 changed files with 65 additions and 6 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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,