Commit ff382810 authored by Paul E. McKenney's avatar Paul E. McKenney

documentation: Clarify control-dependency pairing

This commit explicitly states that control dependencies pair normally
with other barriers, and gives an example of such pairing.
Reported-by: default avatarPeter Zijlstra <peterz@infradead.org>
Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
parent daf1aab9
...@@ -592,9 +592,9 @@ See also the subsection on "Cache Coherency" for a more thorough example. ...@@ -592,9 +592,9 @@ See also the subsection on "Cache Coherency" for a more thorough example.
CONTROL DEPENDENCIES CONTROL DEPENDENCIES
-------------------- --------------------
A control dependency requires a full read memory barrier, not simply a data A load-load control dependency requires a full read memory barrier, not
dependency barrier to make it work correctly. Consider the following bit of simply a data dependency barrier to make it work correctly. Consider the
code: following bit of code:
q = ACCESS_ONCE(a); q = ACCESS_ONCE(a);
if (q) { if (q) {
...@@ -615,14 +615,15 @@ case what's actually required is: ...@@ -615,14 +615,15 @@ case what's actually required is:
} }
However, stores are not speculated. This means that ordering -is- provided However, stores are not speculated. This means that ordering -is- provided
in the following example: for load-store control dependencies, as in the following example:
q = ACCESS_ONCE(a); q = ACCESS_ONCE(a);
if (q) { if (q) {
ACCESS_ONCE(b) = p; ACCESS_ONCE(b) = p;
} }
Please note that ACCESS_ONCE() is not optional! Without the Control dependencies pair normally with other types of barriers.
That said, please note that ACCESS_ONCE() is not optional! Without the
ACCESS_ONCE(), might combine the load from 'a' with other loads from ACCESS_ONCE(), might combine the load from 'a' with other loads from
'a', and the store to 'b' with other stores to 'b', with possible highly 'a', and the store to 'b' with other stores to 'b', with possible highly
counterintuitive effects on ordering. counterintuitive effects on ordering.
...@@ -813,6 +814,8 @@ In summary: ...@@ -813,6 +814,8 @@ In summary:
barrier() can help to preserve your control dependency. Please barrier() can help to preserve your control dependency. Please
see the Compiler Barrier section for more information. see the Compiler Barrier section for more information.
(*) Control dependencies pair normally with other types of barriers.
(*) Control dependencies do -not- provide transitivity. If you (*) Control dependencies do -not- provide transitivity. If you
need transitivity, use smp_mb(). need transitivity, use smp_mb().
...@@ -823,14 +826,14 @@ SMP BARRIER PAIRING ...@@ -823,14 +826,14 @@ SMP BARRIER PAIRING
When dealing with CPU-CPU interactions, certain types of memory barrier should When dealing with CPU-CPU interactions, certain types of memory barrier should
always be paired. A lack of appropriate pairing is almost certainly an error. always be paired. A lack of appropriate pairing is almost certainly an error.
General barriers pair with each other, though they also pair with General barriers pair with each other, though they also pair with most
most other types of barriers, albeit without transitivity. An acquire other types of barriers, albeit without transitivity. An acquire barrier
barrier pairs with a release barrier, but both may also pair with other pairs with a release barrier, but both may also pair with other barriers,
barriers, including of course general barriers. A write barrier pairs including of course general barriers. A write barrier pairs with a data
with a data dependency barrier, an acquire barrier, a release barrier, dependency barrier, a control dependency, an acquire barrier, a release
a read barrier, or a general barrier. Similarly a read barrier or a barrier, a read barrier, or a general barrier. Similarly a read barrier,
data dependency barrier pairs with a write barrier, an acquire barrier, control dependency, or a data dependency barrier pairs with a write
a release barrier, or a general barrier: barrier, an acquire barrier, a release barrier, or a general barrier:
CPU 1 CPU 2 CPU 1 CPU 2
=============== =============== =============== ===============
...@@ -850,6 +853,19 @@ Or: ...@@ -850,6 +853,19 @@ Or:
<data dependency barrier> <data dependency barrier>
y = *x; y = *x;
Or even:
CPU 1 CPU 2
=============== ===============================
r1 = ACCESS_ONCE(y);
<general barrier>
ACCESS_ONCE(y) = 1; if (r2 = ACCESS_ONCE(x)) {
<implicit control dependency>
ACCESS_ONCE(y) = 1;
}
assert(r1 == 0 || r2 == 0);
Basically, the read barrier always has to be there, even though it can be of Basically, the read barrier always has to be there, even though it can be of
the "weaker" type. the "weaker" type.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment