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

Signed-off-by: Matthew Brost <[email protected]>
---
 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

Reply via email to