diff options
author | Peter Zijlstra <peterz@infradead.org> | 2017-08-23 18:15:20 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-08-25 11:06:33 +0200 |
commit | ca110694c6950dfd7bc864138c80fe39ea43da5b (patch) | |
tree | cd1924e8654b7d3bf23e33eea2c4700536039b6c /Documentation/atomic_t.txt | |
parent | locking/lockdep: Fix workqueue crossrelease annotation (diff) | |
download | linux-ca110694c6950dfd7bc864138c80fe39ea43da5b.tar.xz linux-ca110694c6950dfd7bc864138c80fe39ea43da5b.zip |
Documentation/locking/atomic: Finish the document...
Julia reported that the document looked unfinished, and it is. I
forgot to include the example cooked up by Paul here:
https://lkml.kernel.org/r/20170731174345.GL3730@linux.vnet.ibm.com
and I added an explicit example showing how, while it is an ACQUIRE
pattern, it really does provide an MB.
Reported-by: Julia Cartwright <julia@ni.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'Documentation/atomic_t.txt')
-rw-r--r-- | Documentation/atomic_t.txt | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/Documentation/atomic_t.txt b/Documentation/atomic_t.txt index eee127115277..913396ac5824 100644 --- a/Documentation/atomic_t.txt +++ b/Documentation/atomic_t.txt @@ -197,4 +197,46 @@ Further, while something like: is a 'typical' RELEASE pattern, the barrier is strictly stronger than a RELEASE. Similarly for something like: + atomic_inc(&X); + smp_mb__after_atomic(); + +is an ACQUIRE pattern (though very much not typical), but again the barrier is +strictly stronger than ACQUIRE. As illustrated: + + C strong-acquire + + { + } + + P1(int *x, atomic_t *y) + { + r0 = READ_ONCE(*x); + smp_rmb(); + r1 = atomic_read(y); + } + + P2(int *x, atomic_t *y) + { + atomic_inc(y); + smp_mb__after_atomic(); + WRITE_ONCE(*x, 1); + } + + exists + (r0=1 /\ r1=0) + +This should not happen; but a hypothetical atomic_inc_acquire() -- +(void)atomic_fetch_inc_acquire() for instance -- would allow the outcome, +since then: + + P1 P2 + + t = LL.acq *y (0) + t++; + *x = 1; + r0 = *x (1) + RMB + r1 = *y (0) + SC *y, t; +is allowed. |