On Mon, Mar 17, 2014 at 07:45:22PM -0700, Paul E. McKenney wrote: > > > Yep! I will risk an ASCII diagram: > > > > > > > > > 3: > > > +----gpnum----+-- ... > > > | | > > > 2: > > > +----gpnum----+-------+--completed--+ > > > | | > > > 1: +----gpnum----+-------+--completed--+ > > > | | > > > 0: +-----+--completed--+ > > > > > > > > > A full RCU grace period happens between a pair of "|"s on the same line. > > > By inspection, if your snapshot of ->gpnum is greater than the current > > > value of ->completed, a grace period has passed. > > > > OK, so I get the > part, but I'm not sure I get the = part of the above. > > The way I read the diagram, when completed matches gpnum the grace > > period is done and we don't have to wait anymore. > > Absolutely not! Let's try laying out the scenario: > > 1. Someone calls get_state_synchronize_rcu() when ->gpnum==->completed==0. > It returns zero. > > 2. That someone immediately calls cond_synchronize_rcu(). Nothing > has changed, so oldstate==newstate==0. > > We had better call synchronize_rcu() in this case!!!
> Make sense? Yes, should have seen that! Thanks for bearing with me on this. > ------------------------------------------------------------------------ > > rcu: Provide grace-period piggybacking API > > The following pattern is currently not well supported by RCU: > > 1. Make data element inaccessible to RCU readers. > > 2. Do work that probably lasts for more than one grace period. > > 3. Do something to make sure RCU readers in flight before #1 above > have completed. > > Here are some things that could currently be done: > > a. Do a synchronize_rcu() unconditionally at either #1 or #3 above. > This works, but imposes needless work and latency. > > b. Post an RCU callback at #1 above that does a wakeup, then > wait for the wakeup at #3. This works well, but likely results > in an extra unneeded grace period. Open-coding this is also > a bit more semi-tricky code than would be good. > > This commit therefore adds get_state_synchronize_rcu() and > cond_synchronize_rcu() APIs. Call get_state_synchronize_rcu() at #1 > above and pass its return value to cond_synchronize_rcu() at #3 above. > This results in a call to synchronize_rcu() if no grace period has > elapsed between #1 and #3, but requires only a load, comparison, and > memory barrier if a full grace period did elapse. > > Requested-by: Peter Zijlstra <pet...@infradead.org> > Signed-off-by: Paul E. McKenney <paul...@linux.vnet.ibm.com> Thanks! Acked-by: Peter Zijlstra <pet...@infradead.org> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/