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? 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 >
