959
960
retrieved : : +-------+
966
Transitivity is a deeply intuitive notion about ordering that is not
967
always provided by real computer systems. The following example
968
demonstrates transitivity (also called "cumulativity"):
971
======================= ======================= =======================
973
STORE X=1 LOAD X STORE Y=1
974
<general barrier> <general barrier>
977
Suppose that CPU 2's load from X returns 1 and its load from Y returns 0.
978
This indicates that CPU 2's load from X in some sense follows CPU 1's
979
store to X and that CPU 2's load from Y in some sense preceded CPU 3's
980
store to Y. The question is then "Can CPU 3's load from X return 0?"
982
Because CPU 2's load from X in some sense came after CPU 1's store, it
983
is natural to expect that CPU 3's load from X must therefore return 1.
984
This expectation is an example of transitivity: if a load executing on
985
CPU A follows a load from the same variable executing on CPU B, then
986
CPU A's load must either return the same value that CPU B's load did,
987
or must return some later value.
989
In the Linux kernel, use of general memory barriers guarantees
990
transitivity. Therefore, in the above example, if CPU 2's load from X
991
returns 1 and its load from Y returns 0, then CPU 3's load from X must
994
However, transitivity is -not- guaranteed for read or write barriers.
995
For example, suppose that CPU 2's general barrier in the above example
996
is changed to a read barrier as shown below:
999
======================= ======================= =======================
1001
STORE X=1 LOAD X STORE Y=1
1002
<read barrier> <general barrier>
1005
This substitution destroys transitivity: in this example, it is perfectly
1006
legal for CPU 2's load from X to return 1, its load from Y to return 0,
1007
and CPU 3's load from X to return 0.
1009
The key point is that although CPU 2's read barrier orders its pair
1010
of loads, it does not guarantee to order CPU 1's store. Therefore, if
1011
this example runs on a system where CPUs 1 and 2 share a store buffer
1012
or a level of cache, CPU 2 might have early access to CPU 1's writes.
1013
General barriers are therefore required to ensure that all CPUs agree
1014
on the combined order of CPU 1's and CPU 2's accesses.
1016
To reiterate, if your code requires transitivity, use general barriers
962
1020
========================
963
1021
EXPLICIT KERNEL BARRIERS
964
1022
========================