summaryrefslogtreecommitdiffstats
path: root/Documentation/memory-barriers.txt
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2016-06-15 19:08:17 -0400
committerIngo Molnar <mingo@kernel.org>2016-06-17 03:54:45 -0400
commitebff09a6ff164aec2b33bf1f9a488c45ac108413 (patch)
tree4c2e43caeacbd254daa8439564e991b1de82750c /Documentation/memory-barriers.txt
parentb316ff783d17bd6217804e2e4385ce9347d7dad9 (diff)
locking/Documentation: Clarify limited control-dependency scope
Nothing in the control-dependencies section of memory-barriers.txt says that control dependencies don't extend beyond the end of the if-statement containing the control dependency. Worse yet, in many situations, they do extend beyond that if-statement. In particular, the compiler cannot destroy the control dependency given proper use of READ_ONCE() and WRITE_ONCE(). However, a weakly ordered system having a conditional-move instruction provides the control-dependency guarantee only to code within the scope of the if-statement itself. This commit therefore adds words and an example demonstrating this limitation of control dependencies. Reported-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: corbet@lwn.net Cc: linux-arch@vger.kernel.org Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20160615230817.GA18039@linux.vnet.ibm.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'Documentation/memory-barriers.txt')
-rw-r--r--Documentation/memory-barriers.txt41
1 files changed, 41 insertions, 0 deletions
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 147ae8ec836f..a4d0a99de04d 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -806,6 +806,41 @@ out-guess your code. More generally, although READ_ONCE() does force
806the compiler to actually emit code for a given load, it does not force 806the compiler to actually emit code for a given load, it does not force
807the compiler to use the results. 807the compiler to use the results.
808 808
809In addition, control dependencies apply only to the then-clause and
810else-clause of the if-statement in question. In particular, it does
811not necessarily apply to code following the if-statement:
812
813 q = READ_ONCE(a);
814 if (q) {
815 WRITE_ONCE(b, p);
816 } else {
817 WRITE_ONCE(b, r);
818 }
819 WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */
820
821It is tempting to argue that there in fact is ordering because the
822compiler cannot reorder volatile accesses and also cannot reorder
823the writes to "b" with the condition. Unfortunately for this line
824of reasoning, the compiler might compile the two writes to "b" as
825conditional-move instructions, as in this fanciful pseudo-assembly
826language:
827
828 ld r1,a
829 ld r2,p
830 ld r3,r
831 cmp r1,$0
832 cmov,ne r4,r2
833 cmov,eq r4,r3
834 st r4,b
835 st $1,c
836
837A weakly ordered CPU would have no dependency of any sort between the load
838from "a" and the store to "c". The control dependencies would extend
839only to the pair of cmov instructions and the store depending on them.
840In short, control dependencies apply only to the stores in the then-clause
841and else-clause of the if-statement in question (including functions
842invoked by those two clauses), not to code following that if-statement.
843
809Finally, control dependencies do -not- provide transitivity. This is 844Finally, control dependencies do -not- provide transitivity. This is
810demonstrated by two related examples, with the initial values of 845demonstrated by two related examples, with the initial values of
811x and y both being zero: 846x and y both being zero:
@@ -869,6 +904,12 @@ In summary:
869 atomic{,64}_read() can help to preserve your control dependency. 904 atomic{,64}_read() can help to preserve your control dependency.
870 Please see the COMPILER BARRIER section for more information. 905 Please see the COMPILER BARRIER section for more information.
871 906
907 (*) Control dependencies apply only to the then-clause and else-clause
908 of the if-statement containing the control dependency, including
909 any functions that these two clauses call. Control dependencies
910 do -not- apply to code following the if-statement containing the
911 control dependency.
912
872 (*) Control dependencies pair normally with other types of barriers. 913 (*) Control dependencies pair normally with other types of barriers.
873 914
874 (*) Control dependencies do -not- provide transitivity. If you 915 (*) Control dependencies do -not- provide transitivity. If you