From: Matthew Brost <matthew.brost@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: francois.dugast@intel.com, thomas.hellstrom@linux.intel.com,
michal.mrozek@intel.com
Subject: [PATCH 4/6] drm/xe: Skip exec queue schedule toggle if queue is idle during suspend
Date: Thu, 11 Dec 2025 13:00:30 -0800 [thread overview]
Message-ID: <20251211210032.1520113-5-matthew.brost@intel.com> (raw)
In-Reply-To: <20251211210032.1520113-1-matthew.brost@intel.com>
If an exec queue is idle, there is no need to issue a schedule disable
to the GuC when suspending the queue’s execution. Opportunistically skip
this step if the queue is idle and not a parallel queue. Parallel queues
must have their scheduling state flipped in the GuC due to limitations
in how submission is implemented in run_job().
Also if all pagefault queues can skip the schedule disable during a
switch to dma-fence mode, do not schedule a resume for the pagefault
queues after the next submission.
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/xe/xe_exec_queue.h | 17 ++++++++++++++++
drivers/gpu/drm/xe/xe_guc_submit.c | 26 ++++++++++++++++++++++---
drivers/gpu/drm/xe/xe_hw_engine_group.c | 2 +-
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_exec_queue.h b/drivers/gpu/drm/xe/xe_exec_queue.h
index fda4d4f9bda8..ae16b9b39ced 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.h
+++ b/drivers/gpu/drm/xe/xe_exec_queue.h
@@ -111,4 +111,21 @@ int xe_exec_queue_contexts_hwsp_rebase(struct xe_exec_queue *q, void *scratch);
struct xe_lrc *xe_exec_queue_lrc(struct xe_exec_queue *q);
+/**
+ * xe_exec_queue_idle_skip_suspend() - Can exec queue skip suspend
+ * @q: The exec_queue
+ *
+ * If an exec queue is not parallel and is idle, the suspend steps can be
+ * skipped in the submission backend immediatley signaling the suspend fence.
+ * Parallel queues cannot skip this step due to limitations in the submission
+ * backend.
+ *
+ * Return: True if exec queue is idle and can skip suspend steps, False
+ * otherwise
+ */
+static inline bool xe_exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
+{
+ return !xe_exec_queue_is_parallel(q) && xe_exec_queue_is_idle(q);
+}
+
#endif
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 92c703888cff..c4eb845628c4 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -72,6 +72,7 @@ exec_queue_to_guc(struct xe_exec_queue *q)
#define EXEC_QUEUE_STATE_EXTRA_REF (1 << 11)
#define EXEC_QUEUE_STATE_PENDING_RESUME (1 << 12)
#define EXEC_QUEUE_STATE_PENDING_TDR_EXIT (1 << 13)
+#define EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND (1 << 14)
static bool exec_queue_registered(struct xe_exec_queue *q)
{
@@ -263,6 +264,21 @@ static void clear_exec_queue_pending_tdr_exit(struct xe_exec_queue *q)
atomic_and(~EXEC_QUEUE_STATE_PENDING_TDR_EXIT, &q->guc->state);
}
+static bool exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
+{
+ return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND;
+}
+
+static void set_exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
+{
+ atomic_or(EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND, &q->guc->state);
+}
+
+static void clear_exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
+{
+ atomic_and(~EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND, &q->guc->state);
+}
+
static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q)
{
return (atomic_read(&q->guc->state) &
@@ -1585,9 +1601,10 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
{
struct xe_exec_queue *q = msg->private_data;
struct xe_guc *guc = exec_queue_to_guc(q);
+ bool idle_skip_suspend = xe_exec_queue_idle_skip_suspend(q);
- if (guc_exec_queue_allowed_to_change_state(q) && !exec_queue_suspended(q) &&
- exec_queue_enabled(q)) {
+ if (!idle_skip_suspend && guc_exec_queue_allowed_to_change_state(q) &&
+ !exec_queue_suspended(q) && exec_queue_enabled(q)) {
wait_event(guc->ct.wq, vf_recovery(guc) ||
((q->guc->resume_time != RESUME_PENDING ||
xe_guc_read_stopped(guc)) && !exec_queue_pending_disable(q)));
@@ -1606,6 +1623,8 @@ static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
disable_scheduling(q, false);
}
} else if (q->guc->suspend_pending) {
+ if (idle_skip_suspend)
+ set_exec_queue_idle_skip_suspend(q);
set_exec_queue_suspended(q);
suspend_fence_signal(q);
}
@@ -1617,8 +1636,9 @@ static void __guc_exec_queue_process_msg_resume(struct xe_sched_msg *msg)
if (guc_exec_queue_allowed_to_change_state(q)) {
clear_exec_queue_suspended(q);
- if (!exec_queue_enabled(q)) {
+ if (!exec_queue_enabled(q) || exec_queue_idle_skip_suspend(q)) {
q->guc->resume_time = RESUME_PENDING;
+ clear_exec_queue_idle_skip_suspend(q);
set_exec_queue_pending_resume(q);
enable_scheduling(q);
}
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_group.c b/drivers/gpu/drm/xe/xe_hw_engine_group.c
index 290205a266b8..4d9263a1a208 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine_group.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine_group.c
@@ -205,7 +205,7 @@ static int xe_hw_engine_group_suspend_faulting_lr_jobs(struct xe_hw_engine_group
continue;
xe_gt_stats_incr(q->gt, XE_GT_STATS_ID_HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_COUNT, 1);
- need_resume = true;
+ need_resume |= !xe_exec_queue_idle_skip_suspend(q);
q->ops->suspend(q);
}
--
2.34.1
next prev parent reply other threads:[~2025-12-11 21:00 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-11 21:00 [PATCH 0/6] Fix performance when pagefaults and 3d/display share resources Matthew Brost
2025-12-11 21:00 ` [PATCH 1/6] drm/xe: Adjust long-running workload timeslices to reasonable values Matthew Brost
2025-12-11 21:00 ` [PATCH 2/6] drm/xe: Use usleep_range for accurate long-running workload timeslicing Matthew Brost
2025-12-11 21:00 ` [PATCH 3/6] drm/xe: Add debugfs knobs to control long running " Matthew Brost
2025-12-11 21:00 ` Matthew Brost [this message]
2025-12-11 21:00 ` [PATCH 5/6] drm/xe: Wait on in-syncs when swicthing to dma-fence mode Matthew Brost
2025-12-12 9:22 ` Thomas Hellström
2025-12-12 16:33 ` Matthew Brost
2025-12-12 16:38 ` Matthew Brost
2025-12-12 18:41 ` Thomas Hellström
2025-12-12 20:20 ` Matthew Brost
2025-12-11 21:00 ` [PATCH 6/6] drm/xe: Add more GT stats around pagefault mode switch flows Matthew Brost
2025-12-12 16:07 ` Francois Dugast
2025-12-12 16:18 ` Matthew Brost
2025-12-11 21:29 ` ✓ CI.KUnit: success for Fix performance when pagefaults and 3d/display share resources Patchwork
2025-12-11 22:34 ` ✗ Xe.CI.BAT: failure " Patchwork
2025-12-12 13:46 ` ✗ Xe.CI.Full: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251211210032.1520113-5-matthew.brost@intel.com \
--to=matthew.brost@intel.com \
--cc=francois.dugast@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=michal.mrozek@intel.com \
--cc=thomas.hellstrom@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox