On 19-09-2026 04:06, Matthew Brost wrote:
On Wed, Sep 16, 2026 at 03:23:34PM +0530, Arvind Yadav wrote:
disable_scheduling_deregister() waits for any pending scheduling
operation to complete before destroying an exec queue.
For a disable completion, handle_sched_done() can wake the waiter before
clearing pending_disable, or not wake it at all. The waiter can then miss
a completed operation and expire after five seconds. This causes a
spurious GT reset and immediate TDR.
Clear pending_disable before waking the waitqueue on every completion
path. Sample the destroyed state before clearing the pending state, as
required by the existing destroy protocol.
Also wake CT waiters after a suspend completion.
The queue remains alive until deregistration completes, so waking
waiters before sending the deregister request does not release it.
Cc: Matthew Brost <[email protected]>
Cc: Thomas Hellström <[email protected]>
Cc: Himal Prasad Ghimiray <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
I feel like this is an independent fix (like patch 1) that can be sent
on its own with a Fixes tag and CC'd to stable. This also looks very
similar to [1].
Can you coordinate with the author of [1]? Alternatively, if that patch
looks good to you, could you give it an RB?
Thank you for review.
Noted,
Arvind
Matt
[1] https://patchwork.freedesktop.org/patch/753791/?series=174199&rev=1
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Arvind Yadav <[email protected]>
---
drivers/gpu/drm/xe/xe_guc_submit.c | 42 +++++++++++++++++-------------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c
b/drivers/gpu/drm/xe/xe_guc_submit.c
index f3ba8abfc228..ca24a77dfb26 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -3265,26 +3265,32 @@ static void handle_sched_done(struct xe_guc *guc,
struct xe_exec_queue *q,
if (q->guc->suspend_pending) {
clear_exec_queue_pending_disable(q);
suspend_fence_signal(q);
+
+ /*
+ * Publish the cleared state before waking waiters.
+ */
+ smp_wmb();
+ wake_up_all(&guc->ct.wq);
} else {
- if (exec_queue_banned(q)) {
- smp_wmb();
- wake_up_all(&guc->ct.wq);
- }
- if (exec_queue_destroyed(q)) {
- /*
- * Make sure to clear the pending_disable only
- * after sampling the destroyed state. We want
- * to ensure we don't trigger the unregister too
- * early with something intending to only
- * disable scheduling. The caller doing the
- * destroy must wait for an ongoing
- * pending_disable before marking as destroyed.
- */
- clear_exec_queue_pending_disable(q);
+ bool destroyed = exec_queue_destroyed(q);
+
+ /*
+ * Make sure to clear pending_disable only after
sampling
+ * the destroyed state. The caller doing the destroy
must
+ * wait for an ongoing disable before marking the queue
+ * destroyed.
+ */
+ clear_exec_queue_pending_disable(q);
+
+ /*
+ * Publish the cleared state before waking waiters.
+ */
+ smp_wmb();
+ wake_up_all(&guc->ct.wq);
+
+ /* The queue remains alive until DEREGISTER_DONE. */
+ if (destroyed)
deregister_exec_queue(guc, q);
- } else {
- clear_exec_queue_pending_disable(q);
- }
}
}
}
--
2.43.0