Re: [PATCH v8 6/7] apei/ghes: Use unrcu_pointer for cmpxchg

Ard Biesheuvel
2022-10-14T15:24:58Z

On Fri, 14 Oct 2022 at 17:11, Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Fri, Oct 14, 2022 at 04:31:37PM +0200, Ard Biesheuvel wrote:
> > + if (slot != -1) {
> > + /*
> > + * Use release semantics to ensure that ghes_estatus_cached()
> > + * running on another CPU will see the updated cache fields if
> > + * it can see the new value of the pointer.
> > + */
> > + victim = xchg_release(ghes_estatus_caches + slot,
> > + RCU_INITIALIZER(new_cache));
> > +
> > + /*
> > + * At this point, victim may point to a cached item different
> > + * from the one based on which we selected the slot. Instead of
> > + * going to the loop again to pick another slot, let's just
> > + * drop the other item anyway: this may cause a false cache
> > + * miss later on, but that won't cause any problems.
> > + */
> > + if (victim) {
> > + call_rcu(&rcu_dereference(victim)->rcu,
> > + ghes_estatus_cache_rcu_free);
> }
>
> I think you can use unrcu_pointer() here instead, there should not be a
> data dependency since the ->rcu member itself should be otherwise unused
> (and if it were, we wouldn't care about its previous content anyway).
>
> But only Alpha cares about that distinction anyway, so *shrug*.
>

Ah yeah good point - and we are not actually dereferencing the pointer
at all here, just adding an offset to get at the address of the rcu
member.

So we can take this block out of the rcu_read_lock() section as well.

> While I much like the xchg() variant; I still don't really fancy the
> verbage the sparse nonsense makes us do.
>
> victim = xchg_release(&ghes_estatus_caches[slot], new_cache);
> if (victim)
> call_rcu(&victim->rcu, ghes_estatus_cache_rcu_free);
>
> is much nicer code.
>
> Over all; I'd simply ignore sparse (I often do).
>

No disagreement there.