[Intel-gfx] [PATCH 08/66] drm/i915: Make the stale cached active node available for any timeline

Chris Wilson chris at chris-wilson.co.uk
Wed Jul 29 14:52:33 UTC 2020


Quoting Tvrtko Ursulin (2020-07-29 15:22:26)
> 
> On 29/07/2020 14:42, Chris Wilson wrote:
> > Quoting Tvrtko Ursulin (2020-07-29 13:40:38)
> >>
> >> On 28/07/2020 15:28, Chris Wilson wrote:
> >>> Quoting Tvrtko Ursulin (2020-07-17 14:04:58)
> >>>>
> >>>> On 15/07/2020 12:50, Chris Wilson wrote:
> >>>>> @@ -235,9 +239,22 @@ static struct active_node *__active_lookup(struct i915_active *ref, u64 idx)
> >>>>>     {
> >>>>>         struct active_node *it;
> >>>>>     
> >>>>> +     GEM_BUG_ON(idx == 0); /* 0 is the unordered timeline, rsvd for cache */
> >>>>> +
> >>>>>         it = READ_ONCE(ref->cache);
> >>>>> -     if (it && it->timeline == idx)
> >>>>> -             return it;
> >>>>> +     if (it) {
> >>>>> +             u64 cached = READ_ONCE(it->timeline);
> >>>>> +
> >>>>> +             if (cached == idx)
> >>>>> +                     return it;
> >>>>> +
> >>>>> +#ifdef CONFIG_64BIT /* for cmpxchg(u64) */
> >>>>> +             if (!cached && !cmpxchg(&it->timeline, 0, idx)) {
> >>>>> +                     GEM_BUG_ON(i915_active_fence_isset(&it->base));
> >>>>> +                     return it;
> >>>>
> >>>> cpmxchg suggests this needs to be atomic, however above the check for
> >>>> equality comes from a separate read.
> >>>
> >>> That's fine, and quite common to avoid cmpxchg if the current value
> >>> already does not match the expected condition.
> >>
> >> How? What is another thread is about to install its idx into
> >> it->timeline with cmpxchg and this thread does not see it because it
> >> just returned on the "cached == idx" condition.
> > 
> > Because it's nonzero.
> > 
> > If the idx is already non-zero, it will always remain non-zero until
> > everybody idles (and there are no more threads).
> > 
> > If the idx is zero, it can only transition to non-zero once, atomically
> > via cmpxchg. The first and only first cmpxchg will return that the
> > previous value was 0, and so return with it->idx == idx.
> 
> I think this is worthy of a comment to avoid future reader having to 
> re-figure it all out.

        if (it) {
                u64 cached = READ_ONCE(it->timeline);

+               /* Once claimed, this slot will only belong to this idx */
                if (cached == idx)
                        return it;

 #ifdef CONFIG_64BIT /* for cmpxchg(u64) */
+               /*
+                * An unclaimed cache [.timeline=0] can only be claimed once.
+                *
+                * If the value is already non-zero, some other thread has
+                * claimed the cache and we know that is does not match our
+                * idx. If, and only if, the timeline is currently zero is it
+                * worth competing to claim it atomically for ourselves (for
+		 * only the winner of that race will cmpxchg return the old
+		 * value of 0).
+                */
                if (!cached && !cmpxchg(&it->timeline, 0, idx))
                        return it;
 #endif


More information about the Intel-gfx mailing list