On Fri, Aug 02, 2019 at 08:14:48AM -0700, Paul E. McKenney wrote: > +/* > + * Exchange the numeric length of the specified rcu_segcblist structure > + * with the specified value. This can cause the ->len field to disagree > + * with the actual number of callbacks on the structure. This exchange is > + * fully ordered with respect to the callers accesses both before and after. > + */ > +long rcu_segcblist_xchg_len(struct rcu_segcblist *rsclp, long v) > +{ > +#ifdef CONFIG_RCU_NOCB_CPU > + return atomic_long_xchg(&rsclp->len, v); > +#else > + long ret = rsclp->len; > + > + smp_mb(); /* Up to the caller! */ > + WRITE_ONCE(rsclp->len, v); > + smp_mb(); /* Up to the caller! */ > + return ret; > +#endif > +} That one's weird; for matching semantics the load needs to be between the memory barriers.