On Mon, 2013-11-25 at 10:52 -0800, H. Peter Anvin wrote: > On 11/25/2013 09:35 AM, Peter Zijlstra wrote: > > > > I think this means x86 needs help too. > > > > Consider: > > > > x = y = 0 > > > > w[x] = 1 | w[y] = 1 > > mfence | mfence > > r[y] = 0 | r[x] = 0 > > > > This is generally an impossible case, right? (Since if we observe y=0 > > this means that w[y]=1 has not yet happened, and therefore x=1, and > > vice-versa). > > > > Now replace one of the mfences with smp_store_release(l1); > > smp_load_acquire(l2); such that we have a RELEASE+ACQUIRE pair that > > _should_ form a full barrier: > > > > w[x] = 1 | w[y] = 1 > > w[l1] = 1 | mfence > > r[l2] = 0 | r[x] = 0 > > r[y] = 0 | > > > > At which point we can observe the impossible, because as per the rule: > > > > 'reads may be reordered with older writes to different locations' > > > > Our r[y] can slip before the w[x]=1. > > > > Yes, because although r[l2] and r[y] are ordered with respect to each > other, they are allowed to be executed before w[x] and w[l1]. In other > words, smp_store_release() followed by smp_load_acquire() to a different > location do not form a full barrier. To the *same* location, they will. > > -hpa > Peter, Want to check with you on Paul's example, where we are indeed writing and reading to the same lock location when passing the lock on x86 with smp_store_release and smp_load_acquire. So the unlock and lock sequence looks like: CPU 0 (releasing) CPU 1 (acquiring) ----- ----- ACCESS_ONCE(X) = 1; while (ACCESS_ONCE(lock) == 1) continue; ACCESS_ONCE(lock) = 0; r1 = ACCESS_ONCE(Y); observer CPU 2: CPU 2 ----- ACCESS_ONCE(Y) = 1; smp_mb(); r2 = ACCESS_ONCE(X); If the write and read to lock act as a full memory barrier, it would be impossible to end up with (r1 == 0 && r2 == 0), correct? Tim -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>