INIT_LIST_HEAD(&q->multi_gt_link);
INIT_LIST_HEAD(&q->hw_engine_group_link);
INIT_LIST_HEAD(&q->pxp.link);
+ spin_lock_init(&q->multi_queue.lock);
q->multi_queue.priority = XE_MULTI_QUEUE_PRIORITY_NORMAL;
q->sched_props.timeslice_us = hwe->eclass->sched_props.timeslice_us;
struct xe_exec_queue_group *group;
/** @multi_queue.link: Link into group's secondary queues list */
struct list_head link;
- /** @multi_queue.priority: Queue priority within the multi-queue group */
+ /**
+ * @multi_queue.priority: Queue priority within the multi-queue group.
+ * It is protected by @multi_queue.lock.
+ */
enum xe_multi_queue_priority priority;
+ /** @multi_queue.lock: Lock for protecting certain members */
+ spinlock_t lock;
/** @multi_queue.pos: Position of queue within the multi-queue group */
u8 pos;
/** @multi_queue.valid: Queue belongs to a multi queue group */
{
struct xe_exec_queue_group *group = q->multi_queue.group;
struct xe_device *xe = guc_to_xe(guc);
+ enum xe_multi_queue_priority priority;
long ret;
/*
return;
}
- xe_lrc_set_multi_queue_priority(q->lrc[0], q->multi_queue.priority);
+ scoped_guard(spinlock, &q->multi_queue.lock)
+ priority = q->multi_queue.priority;
+
+ xe_lrc_set_multi_queue_priority(q->lrc[0], priority);
xe_guc_exec_queue_group_cgp_update(xe, q);
WRITE_ONCE(group->sync_pending, true);
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))
+ if (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;
+ scoped_guard(spinlock, &q->multi_queue.lock) {
+ if (q->multi_queue.priority == priority) {
+ kfree(msg);
+ return 0;
+ }
+
+ q->multi_queue.priority = priority;
+ }
+
guc_exec_queue_add_msg(q, msg, SET_MULTI_QUEUE_PRIORITY);
return 0;