Re: [PATCH v2 1/4] drm/xe: split VF pause into prepare and revert phases
Matthew Brost <[email protected]> Mon, 3 Aug 2026 09:55:19 -0700
| Newsgroups | org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Jul 31, 2026 at 04:26:24PM -0700, Niranjana Vishwanathapura wrote: > Extract xe_sched_submission_stop() + cancel_delayed_work_sync() into a > new guc_exec_queue_pause_prepare() helper, then call it in a first pass > over all queues before the existing revert loop in > xe_guc_submit_pause_vf(). > > In a multi-queue group a secondary's run_job() can register the primary > queue, which must not race an in-progress revert of a sibling queue. > Stopping every scheduler before reverting any queue prevents that race. > > No functional change outside the VF migration path. > > Assisted-by: Github-Copilot:Claude-opus-4.8 > Signed-off-by: Niranjana Vishwanathapura <[email protected]> Reviewed-by: Matthew Brost <[email protected]> > --- > drivers/gpu/drm/xe/xe_guc_submit.c | 26 +++++++++++++++++++++++--- > 1 file changed, 23 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c > index 8aaed4fd13ea..314747336fb9 100644 > --- a/drivers/gpu/drm/xe/xe_guc_submit.c > +++ b/drivers/gpu/drm/xe/xe_guc_submit.c > @@ -2737,17 +2737,24 @@ static void lrc_parallel_clear(struct xe_lrc *lrc) > * during VF resume flows. The function scans the queue state, make adjustments > * as needed, and queues jobs / messages which replayed upon unpause. > */ > -static void guc_exec_queue_pause(struct xe_guc *guc, struct xe_exec_queue *q) > +static void guc_exec_queue_pause_prepare(struct xe_guc *guc, struct xe_exec_queue *q) > { > struct xe_gpu_scheduler *sched = &q->guc->sched; > - struct xe_sched_job *job; > - int i; > > lockdep_assert_held(&guc->submission_state.lock); > > /* Stop scheduling + flush any DRM scheduler operations */ > xe_sched_submission_stop(sched); > cancel_delayed_work_sync(&sched->base.work_tdr); > +} > + > +static void guc_exec_queue_pause(struct xe_guc *guc, struct xe_exec_queue *q) > +{ > + struct xe_gpu_scheduler *sched = &q->guc->sched; > + struct xe_sched_job *job; > + int i; > + > + lockdep_assert_held(&guc->submission_state.lock); > > guc_exec_queue_revert_pending_state_change(guc, q); > > @@ -2806,6 +2813,19 @@ void xe_guc_submit_pause_vf(struct xe_guc *guc) > xe_gt_assert(guc_to_gt(guc), vf_recovery(guc)); > > mutex_lock(&guc->submission_state.lock); > + /* > + * Stop all schedulers before reverting any queue: in a multi-queue > + * group a secondary's run_job() can register the primary, which must > + * not race an in-progress revert. > + */ > + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { > + /* Prevent redundant attempts to stop parallel queues */ > + if (q->guc->id != index) > + continue; > + > + guc_exec_queue_pause_prepare(guc, q); > + } > + > xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { > /* Prevent redundant attempts to stop parallel queues */ > if (q->guc->id != index) > -- > 2.43.0 >