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
}
}
-#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)
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");
}
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;
.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,