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
