From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: mingo@kernel.org, peterz@infradead.org, dhowells@redhat.com,
will.deacon@arm.com, linux-arch@vger.kernel.org,
sj38.park@gmail.com,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Subject: [PATCH memory-barriers.txt 1/5] documentation: Clarify limited control-dependency scope
Date: Tue, 26 Jul 2016 11:19:27 -0700 [thread overview]
Message-ID: <1469557171-27507-1-git-send-email-paulmck@linux.vnet.ibm.com> (raw)
In-Reply-To: <20160726181807.GA26700@linux.vnet.ibm.com>
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>
---
Documentation/memory-barriers.txt | 41 +++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
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
the compiler to actually emit code for a given load, it does not force
the compiler to use the results.
+In addition, control dependencies apply only to the then-clause and
+else-clause of the if-statement in question. In particular, it does
+not necessarily apply to code following the if-statement:
+
+ q = READ_ONCE(a);
+ if (q) {
+ WRITE_ONCE(b, p);
+ } else {
+ WRITE_ONCE(b, r);
+ }
+ WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */
+
+It is tempting to argue that there in fact is ordering because the
+compiler cannot reorder volatile accesses and also cannot reorder
+the writes to "b" with the condition. Unfortunately for this line
+of reasoning, the compiler might compile the two writes to "b" as
+conditional-move instructions, as in this fanciful pseudo-assembly
+language:
+
+ ld r1,a
+ ld r2,p
+ ld r3,r
+ cmp r1,$0
+ cmov,ne r4,r2
+ cmov,eq r4,r3
+ st r4,b
+ st $1,c
+
+A weakly ordered CPU would have no dependency of any sort between the load
+from "a" and the store to "c". The control dependencies would extend
+only to the pair of cmov instructions and the store depending on them.
+In short, control dependencies apply only to the stores in the then-clause
+and else-clause of the if-statement in question (including functions
+invoked by those two clauses), not to code following that if-statement.
+
Finally, control dependencies do -not- provide transitivity. This is
demonstrated by two related examples, with the initial values of
x and y both being zero:
@@ -869,6 +904,12 @@ In summary:
atomic{,64}_read() can help to preserve your control dependency.
Please see the COMPILER BARRIER section for more information.
+ (*) Control dependencies apply only to the then-clause and else-clause
+ of the if-statement containing the control dependency, including
+ any functions that these two clauses call. Control dependencies
+ do -not- apply to code following the if-statement containing the
+ control dependency.
+
(*) Control dependencies pair normally with other types of barriers.
(*) Control dependencies do -not- provide transitivity. If you
--
2.5.2
next prev parent reply other threads:[~2016-07-26 18:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-26 18:18 [PATCH memory-barriers.txt 0/5] Fixes and Korean translation Paul E. McKenney
2016-07-26 18:19 ` Paul E. McKenney [this message]
2016-07-26 18:19 ` [PATCH memory-barriers.txt 2/5] memory-barriers.txt: Maintain consistent blank line Paul E. McKenney
2016-07-26 18:19 ` [PATCH memory-barriers.txt 3/5] memory-barriers.txt: Fix wrong section reference Paul E. McKenney
2016-07-26 18:19 ` [PATCH memory-barriers.txt 4/5] Doc/memory-barriers: Fix a typo of example result Paul E. McKenney
2016-07-26 18:19 ` [PATCH memory-barriers.txt 5/5] Doc/memory-barriers: Add Korean translation Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1469557171-27507-1-git-send-email-paulmck@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=dhowells@redhat.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=sj38.park@gmail.com \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).