mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user