On Thu, Oct 3, 2013 at 4:28 PM, Josh Triplett <josh@xxxxxxxxxxxxxxxx> wrote: > On Thu, Oct 03, 2013 at 01:52:45PM -0700, Linus Torvalds wrote: >> On Thu, Oct 3, 2013 at 1:41 PM, Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote: >> > >> > The problem is this: >> > A = 1, B = 1 >> > CPU1: >> > A = 0 >> > <full barrier> >> > synchronize_rcu() >> > read B >> > >> > CPU2: >> > rcu_read_lock() >> > B = 0 >> > read A >> > >> > Are we guaranteed that we won't get both of them seeing ones, in situation >> > when that rcu_read_lock() comes too late to be noticed by synchronize_rcu()? >> >> Yeah, I think we should be guaranteed that, because the >> synchronize_rcu() will guarantee that all other CPU's go through an >> idle period. So the "read A" on CPU2 cannot possibly see a 1 _unless_ >> it happens so early that synchronize_rcu() definitely sees it (ie it's >> a "preexisting reader" by definition), in which case synchronize_rcu() >> will be waiting for a subsequent idle period, in which case the B=0 on >> CPU2 is not only guaranteed to happen but also be visible out, so the >> "read B" on CPU1 will see 0. And that's true even if CPU2 doesn't have >> an explicit memory barrier, because the "RCU idle" state implies that >> it has gone through a barrier. > > I think the reasoning in one direction is actually quite a bit less > obvious than that. > > rcu_read_unlock() does *not* necessarily imply a memory barrier Don't think of it in those terms. The only thing that matters is semantics. The semantics of synchronize_rcu() is that it needs to wait for all RCU users. It's that simple. By definition, anything inside a "rcu_read_lock()" is a RCU user, so if we have a read of memory (memory barrier or not), then synchronize_rcu() needs to wait for it. Otherwise serialize_rcu() is clearly totally broken. Now, the fact that the normal rcu_read_lock() is just a compiler barrier may make you think "oh, it cannot work", but the thing is, the way things happens is that synchronize_rcu() ends up relying on the _scheduler_ data structures, rather than anything else. It requires seeing an idle scheduler state for each CPU after being called. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html