Re: [PATCH i-g-t 1/2] lib/xe/xe_spin: initialize ticks_delta to ~0u
Zbigniew Kempczyński <[email protected]> Fri, 31 Jul 2026 07:16:58 +0200
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <6jnwgnmcua4feocaej36rs7umd4whp457onxpy3axtpneha4ic@ebguddcckru3> |
On Thu, Jul 30, 2026 at 12:05:10PM +0200, Bernatowicz, Marcin wrote: > > On 7/29/2026 11:42 AM, Zbigniew Kempczyński wrote: > > On Tue, Jul 28, 2026 at 12:26:58PM +0200, Marcin Bernatowicz wrote: > > > Initialize ticks_delta to ~0u instead of 0. This value does not satisfy > > > the COND_BBE exit condition and prevents false batch termination. > > May you elaborate? Does it mean STORE-DWORD (loop) is not visible in the memory > > before COND_BBE is executed? IIUC with ~0 we could also drop this loop. > The issue is not about the STORE-DWORDs (loop) visibility within a single > batch; that's what the pad is for and that path works fine. I see two scenarios here: - loop causes delay to allow write to land in memory, where COND_BBE can read it. If there's stale read that means loop is too short. - we got two competing writes to same memory - one from cpu side (spin->ticks_delta = 0) and one from gpu - SRM. If this is possible COND_BBE could read cpu write (0 in this case, we don't know which will be visible at comparison time) so this causes premature spinner termination. > The problem is a cross-iteration potential stale cache read: when the same > BO is re-submitted, COND_BBE can read the ticks_delta value leftover > from the previous batch execution - which is <= ctx_ticks (since that's the > exit condition) - and immediately exit before the new SRM write propagates. > > With ticks_delta = 0 (or any value <= ctx_ticks at prev-iteration exit), a > stale read satisfies COND_BBE. > With ~0u, even a stale read of the sentinel gives 0xFFFFFFFF <= ctx_ticks -> > false -> batch continues safely. I did some experiments, MI_MATH_STOREINV() stores negative value to memory, so I assumed we're comparing signed values (and then 0 is fine as it larger than negative opts->ctx_ticks). But this comparison is done on unsigned values and 0 in ticks_delta is smaller than opts->ctx_ticks casted to unsigned and spinner is terminating. I think for sake of clearity instead of initializing ticks_delta to ~0u I would change MI_MATH_STOREINV() to MI_MATH_STORE(), replace ~opts->ctx_ticks to opts->ctx_ticks and add MAD_LT_IDD in COND_BBE. -- Zbigniew > > To reproduce: each gem_wsim invocation does 4000 submit/wait cycles on the > same BO (5 engines × 5ms each). > The failure appears only after many outer iterations under sustained load: > > i=1; while true; do > echo "Iteration: $i" > gem_wsim -w > "1.RCS.5000.0.0,1.BCS.5000.0.0,1.CCS.5000.0.1,1.VCS.5000.0.0,1.VECS.5000.0.0" > -VV -r 4000 || break > ((i++)) > done > > Typical failure after ~60 outer iterations: > > CRITICAL: Failed assertion: w->duration.requested_ticks <= > ~w->xe.data->spin.ticks_delta > CRITICAL: error: 96000 > 2 (sometimes 0, 1) > > With the sentinel reset before each submission, ran two days without > failure. > > -- > > Marcin > > > > > -- > > Zbigniew > > > > > Signed-off-by: Marcin Bernatowicz <[email protected]> > > > Cc: Adam Miszczak <[email protected]> > > > Cc: Kamil Konieczny <[email protected]> > > > Cc: Lukasz Laguna <[email protected]> > > > --- > > > lib/xe/xe_spin.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/lib/xe/xe_spin.c b/lib/xe/xe_spin.c > > > index 874310789..331bed1d2 100644 > > > --- a/lib/xe/xe_spin.c > > > +++ b/lib/xe/xe_spin.c > > > @@ -60,7 +60,7 @@ void xe_spin_init(struct xe_spin *spin, struct xe_spin_opts *opts) > > > spin->start = 0; > > > spin->end = 0xffffffff; > > > spin->wait_cond = 0; > > > - spin->ticks_delta = 0; > > > + spin->ticks_delta = ~0u; > > > if (opts->ctx_ticks) { > > > /* store start timestamp */ > > > -- > > > 2.43.0 > > >