[RFC PATCH 07/12] drm/xe: Make scheduler message lock IRQ-safe

Matthew Brost
2026-03-16T04:33:11Z

Make message enqueuing safe in IRQ context by converting the scheduler
message lock to an IRQ-safe guard.

Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/xe/xe_gpu_scheduler.c | 28 +++++++++++++--------------
drivers/gpu/drm/xe/xe_gpu_scheduler.h | 17 ++++++++--------
drivers/gpu/drm/xe/xe_guc_submit.c | 23 ++++++++++------------
3 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.c b/drivers/gpu/drm/xe/xe_gpu_scheduler.c
index a8e6384dffe8..14c1b8df439f 100644
--- a/drivers/gpu/drm/xe/xe_gpu_scheduler.c
+++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.c
@@ -14,11 +14,12 @@ static void xe_sched_process_msg_queue_if_ready(struct xe_gpu_scheduler *sched)
{
struct xe_sched_msg *msg;

- xe_sched_msg_lock(sched);
- msg = list_first_entry_or_null(&sched->msgs, struct xe_sched_msg, link);
- if (msg)
- xe_sched_process_msg_queue(sched);
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched) {
+ msg = list_first_entry_or_null(&sched->msgs,
+ struct xe_sched_msg, link);
+ if (msg)
+ xe_sched_process_msg_queue(sched);
+ }
}

static struct xe_sched_msg *
@@ -26,12 +27,12 @@ xe_sched_get_msg(struct xe_gpu_scheduler *sched)
{
struct xe_sched_msg *msg;

- xe_sched_msg_lock(sched);
- msg = list_first_entry_or_null(&sched->msgs,
- struct xe_sched_msg, link);
- if (msg)
- list_del_init(&msg->link);
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched) {
+ msg = list_first_entry_or_null(&sched->msgs,
+ struct xe_sched_msg, link);
+ if (msg)
+ list_del_init(&msg->link);
+ }

return msg;
}
@@ -108,9 +109,8 @@ void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched)
void xe_sched_add_msg(struct xe_gpu_scheduler *sched,
struct xe_sched_msg *msg)
{
- xe_sched_msg_lock(sched);
- xe_sched_add_msg_locked(sched, msg);
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched)
+ xe_sched_add_msg_locked(sched, msg);
}

void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched,
diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.h b/drivers/gpu/drm/xe/xe_gpu_scheduler.h
index 4086aafb0a9a..71c060398be6 100644
--- a/drivers/gpu/drm/xe/xe_gpu_scheduler.h
+++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.h
@@ -31,15 +31,14 @@ void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched,
void xe_sched_add_msg_head(struct xe_gpu_scheduler *sched,
struct xe_sched_msg *msg);

-static inline void xe_sched_msg_lock(struct xe_gpu_scheduler *sched)
-{
- spin_lock(&sched->msg_lock);
-}
-
-static inline void xe_sched_msg_unlock(struct xe_gpu_scheduler *sched)
-{
- spin_unlock(&sched->msg_lock);
-}
+/**
+ * xe_sched_msg_scoped_guard() - Scoped guard for scheduler message lock
+ * @__sched: xe_gpu_scheduler object
+ *
+ * IRQ-safe scoped guard for scheduler message lock
+ */
+#define xe_sched_msg_scoped_guard(__sched) \
+ scoped_guard(spinlock_irqsave, &(__sched)->msg_lock)

static inline void xe_sched_tdr_queue_imm(struct xe_gpu_scheduler *sched)
{
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index fc9704fad177..2f91902bd2cb 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -2183,10 +2183,10 @@ static int guc_exec_queue_suspend(struct xe_exec_queue *q)
if (exec_queue_killed_or_banned_or_wedged(q))
return -EINVAL;

- xe_sched_msg_lock(sched);
- if (guc_exec_queue_try_add_msg(q, msg, SUSPEND))
- q->guc->suspend_pending = true;
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched) {
+ if (guc_exec_queue_try_add_msg(q, msg, SUSPEND))
+ q->guc->suspend_pending = true;
+ }

return 0;
}
@@ -2242,9 +2242,8 @@ static void guc_exec_queue_resume(struct xe_exec_queue *q)

xe_gt_assert(guc_to_gt(guc), !q->guc->suspend_pending);

- xe_sched_msg_lock(sched);
- guc_exec_queue_try_add_msg(q, msg, RESUME);
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched)
+ guc_exec_queue_try_add_msg(q, msg, RESUME);
}

static bool guc_exec_queue_reset_status(struct xe_exec_queue *q)
@@ -2666,9 +2665,8 @@ static void guc_exec_queue_replay_pending_state_change(struct xe_exec_queue *q)
if (q->guc->needs_suspend) {
msg = q->guc->static_msgs + STATIC_MSG_SUSPEND;

- xe_sched_msg_lock(sched);
- guc_exec_queue_try_add_msg_head(q, msg, SUSPEND);
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched)
+ guc_exec_queue_try_add_msg_head(q, msg, SUSPEND);

q->guc->needs_suspend = false;
}
@@ -2681,9 +2679,8 @@ static void guc_exec_queue_replay_pending_state_change(struct xe_exec_queue *q)
if (q->guc->needs_resume) {
msg = q->guc->static_msgs + STATIC_MSG_RESUME;

- xe_sched_msg_lock(sched);
- guc_exec_queue_try_add_msg_head(q, msg, RESUME);
- xe_sched_msg_unlock(sched);
+ xe_sched_msg_scoped_guard(sched)
+ guc_exec_queue_try_add_msg_head(q, msg, RESUME);

q->guc->needs_resume = false;
}
--
2.34.1