diff options
author | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-07-25 17:05:24 -0700 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2014-09-07 16:15:41 -0700 |
commit | 5646f7acc95f14873f1ec715380c1c493b4243ce (patch) | |
tree | 7a1a362a08ea7fe599226af082dff7182ac0a7dc | |
parent | 11ed7f934cb807f26da09547b5946c2e534d1dac (diff) | |
download | op-kernel-dev-5646f7acc95f14873f1ec715380c1c493b4243ce.zip op-kernel-dev-5646f7acc95f14873f1ec715380c1c493b4243ce.tar.gz |
memory-barriers: Fix control-ordering no-transitivity example
The control-ordering example demonstrating lack of transitivity had
multiple problems. This commit fixes them.
Reported-by: Nikolay Samofatov <nikolay.samofatov@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Pranith Kumar <bobby.prani@gmail.com>
-rw-r--r-- | Documentation/memory-barriers.txt | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index a4de88f..d67c508 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -697,30 +697,36 @@ should do something like the following: } Finally, control dependencies do -not- provide transitivity. This is -demonstrated by two related examples: +demonstrated by two related examples, with the initial values of +x and y both being zero: CPU 0 CPU 1 ===================== ===================== r1 = ACCESS_ONCE(x); r2 = ACCESS_ONCE(y); - if (r1 >= 0) if (r2 >= 0) + if (r1 > 0) if (r2 > 0) ACCESS_ONCE(y) = 1; ACCESS_ONCE(x) = 1; assert(!(r1 == 1 && r2 == 1)); The above two-CPU example will never trigger the assert(). However, if control dependencies guaranteed transitivity (which they do not), -then adding the following two CPUs would guarantee a related assertion: +then adding the following CPU would guarantee a related assertion: - CPU 2 CPU 3 - ===================== ===================== - ACCESS_ONCE(x) = 2; ACCESS_ONCE(y) = 2; + CPU 2 + ===================== + ACCESS_ONCE(x) = 2; + + assert(!(r1 == 2 && r2 == 1 && x == 2)); /* FAILS!!! */ - assert(!(r1 == 2 && r2 == 2 && x == 1 && y == 1)); /* FAILS!!! */ +But because control dependencies do -not- provide transitivity, the above +assertion can fail after the combined three-CPU example completes. If you +need the three-CPU example to provide ordering, you will need smp_mb() +between the loads and stores in the CPU 0 and CPU 1 code fragments, +that is, just before or just after the "if" statements. -But because control dependencies do -not- provide transitivity, the -above assertion can fail after the combined four-CPU example completes. -If you need the four-CPU example to provide ordering, you will need -smp_mb() between the loads and stores in the CPU 0 and CPU 1 code fragments. +These two examples are the LB and WWC litmus tests from this paper: +http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf and this +site: https://www.cl.cam.ac.uk/~pes20/ppcmem/index.html. In summary: |