From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752476AbdGDVq5 (ORCPT ); Tue, 4 Jul 2017 17:46:57 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:45615 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752421AbdGDVqz (ORCPT ); Tue, 4 Jul 2017 17:46:55 -0400 Date: Tue, 4 Jul 2017 14:46:51 -0700 From: "Paul E. McKenney" To: Will Deacon Cc: linux-kernel@vger.kernel.org, ldr709@gmail.com, dhowells@redhat.com, peterz@infradead.org, corbet@lwn.net, stern@rowland.harvard.edu, parri.andrea@gmail.com, j.alglave@ucl.ac.uk, luc.maranget@inria.fr Subject: Re: [PATCH] doc: Update memory-barriers.txt for read-to-write dependencies Reply-To: paulmck@linux.vnet.ibm.com References: <20170630232810.GA28036@linux.vnet.ibm.com> <20170703130703.GD1573@arm.com> <20170703174106.GE2393@linux.vnet.ibm.com> <20170704163635.GK22175@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20170704163635.GK22175@arm.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-TM-AS-GCONF: 00 x-cbid: 17070421-0044-0000-0000-000003649738 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007320; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000214; SDB=6.00882886; UDB=6.00440388; IPR=6.00663077; BA=6.00005453; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00016083; XFM=3.00000015; UTC=2017-07-04 21:46:53 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17070421-0045-0000-0000-00000792984D Message-Id: <20170704214651.GP2393@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-07-04_13:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1707040371 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jul 04, 2017 at 05:36:36PM +0100, Will Deacon wrote: > Hello, Paul, > > On Mon, Jul 03, 2017 at 10:41:06AM -0700, Paul E. McKenney wrote: > > On Mon, Jul 03, 2017 at 02:07:03PM +0100, Will Deacon wrote: > > > Might be worth mentioning that you have to careful with the compiler here, > > > and pointing to the section on "Control dependencies" so that people don't > > > just take these three points as guarantees in isolation. > > > > > > > > > > > CPU 1 CPU 2 > > > > =============== =============== > > > > @@ -603,19 +606,19 @@ A data-dependency barrier must also order against dependent writes: > > > > > > > > WRITE_ONCE(P, &B); > > > > Q = READ_ONCE(P); > > > > - > > > > *Q = 5; > > > > > > Do we want that write to Q to be a WRITE_ONCE? Again, the control > > > dependencies section does call this out. > > > > Both good points! Like this? > > More or less, yes! Just one wibble below: > > > commit 00269a0e23dbc50f1c4f101b23c8d74992eace05 > > Author: Paul E. McKenney > > Date: Fri Jun 30 16:18:28 2017 -0700 > > > > doc: Update memory-barriers.txt for read-to-write dependencies > > > > The memory-barriers.txt document contains an obsolete passage stating that > > smp_read_barrier_depends() is required to force ordering for read-to-write > > dependencies. We now know that this is not required, even for DEC Alpha. > > This commit therefore updates this passage to state that read-to-write > > dependencies are respected even without smp_read_barrier_depends(). > > > > Reported-by: Lance Roy > > Signed-off-by: Paul E. McKenney > > Cc: David Howells > > Cc: Will Deacon > > Cc: Peter Zijlstra > > Cc: Jonathan Corbet > > Cc: Alan Stern > > Cc: Andrea Parri > > Cc: Jade Alglave > > Cc: Luc Maranget > > [ paulmck: Reference control-dependencies sections and use WRITE_ONCE() > > per Will Deacon. Correctly place split-cache paragraph while there. ] > > > > diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt > > index 9d5e0f853f08..7be80911e502 100644 > > --- a/Documentation/memory-barriers.txt > > +++ b/Documentation/memory-barriers.txt > > @@ -594,7 +594,23 @@ between the address load and the data load: > > This enforces the occurrence of one of the two implications, and prevents the > > third possibility from arising. > > > > -A data-dependency barrier must also order against dependent writes: > > + > > +[!] Note that this extremely counterintuitive situation arises most easily on > > +machines with split caches, so that, for example, one cache bank processes > > +even-numbered cache lines and the other bank processes odd-numbered cache > > +lines. The pointer P might be stored in an odd-numbered cache line, and the > > +variable B might be stored in an even-numbered cache line. Then, if the > > +even-numbered bank of the reading CPU's cache is extremely busy while the > > +odd-numbered bank is idle, one can see the new value of the pointer P (&B), > > +but the old value of the variable B (2). > > + > > + > > +A data-dependency barrier is not required to order dependent writes > > +because the CPUs that the Linux kernel supports don't do writes until > > +they are certain (1) that the write will actually happen, (2) of the > > +location of the write, and (3) of the value to be written. But please > > +carefully read the "CONTROL DEPENDENCIES" section: The compiler can > > +and does break control dependencies in a great many situations. > > This makes it sound like only control dependencies are susceptible to > being broken by compiler optimisations, so I'd drop the "control" and > just say "The compiler can and does break dependencies in a great many > situations". > > With that: > > Acked-by: Will Deacon Done! I also added a pointer to Documentation/RCU/rcu_dereference.txt, which lists some of the vandalism^Woptimizations that modern compilers can commit. Does the updated patch below capture it? Thanx, Paul ------------------------------------------------------------------------ commit 3a2414a7991c579e7391968b382988f0300655e5 Author: Paul E. McKenney Date: Fri Jun 30 16:18:28 2017 -0700 doc: Update memory-barriers.txt for read-to-write dependencies The memory-barriers.txt document contains an obsolete passage stating that smp_read_barrier_depends() is required to force ordering for read-to-write dependencies. We now know that this is not required, even for DEC Alpha. This commit therefore updates this passage to state that read-to-write dependencies are respected even without smp_read_barrier_depends(). Reported-by: Lance Roy Signed-off-by: Paul E. McKenney Cc: David Howells Cc: Peter Zijlstra Cc: Jonathan Corbet Cc: Alan Stern Cc: Andrea Parri Cc: Jade Alglave Cc: Luc Maranget [ paulmck: Reference control-dependencies sections and use WRITE_ONCE() per Will Deacon. Correctly place split-cache paragraph while there. ] Acked-by: Will Deacon diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index c239a0cf4b1a..f05aa34fe908 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -594,7 +594,24 @@ between the address load and the data load: This enforces the occurrence of one of the two implications, and prevents the third possibility from arising. -A data-dependency barrier must also order against dependent writes: + +[!] Note that this extremely counterintuitive situation arises most easily on +machines with split caches, so that, for example, one cache bank processes +even-numbered cache lines and the other bank processes odd-numbered cache +lines. The pointer P might be stored in an odd-numbered cache line, and the +variable B might be stored in an even-numbered cache line. Then, if the +even-numbered bank of the reading CPU's cache is extremely busy while the +odd-numbered bank is idle, one can see the new value of the pointer P (&B), +but the old value of the variable B (2). + + +A data-dependency barrier is not required to order dependent writes +because the CPUs that the Linux kernel supports don't do writes +until they are certain (1) that the write will actually happen, (2) +of the location of the write, and (3) of the value to be written. +But please carefully read the "CONTROL DEPENDENCIES" section and the +Documentation/RCU/rcu_dereference.txt file: The compiler can and does +break dependencies in a great many highly creative ways. CPU 1 CPU 2 =============== =============== @@ -603,29 +620,19 @@ A data-dependency barrier must also order against dependent writes: WRITE_ONCE(P, &B); Q = READ_ONCE(P); - - *Q = 5; + WRITE_ONCE(*Q, 5); -The data-dependency barrier must order the read into Q with the store -into *Q. This prohibits this outcome: +Therefore, no data-dependency barrier is required to order the read into +Q with the store into *Q. In other words, this outcome is prohibited, +even without a data-dependency barrier: (Q == &B) && (B == 4) Please note that this pattern should be rare. After all, the whole point of dependency ordering is to -prevent- writes to the data structure, along with the expensive cache misses associated with those writes. This pattern -can be used to record rare error conditions and the like, and the ordering -prevents such records from being lost. - - -[!] Note that this extremely counterintuitive situation arises most easily on -machines with split caches, so that, for example, one cache bank processes -even-numbered cache lines and the other bank processes odd-numbered cache -lines. The pointer P might be stored in an odd-numbered cache line, and the -variable B might be stored in an even-numbered cache line. Then, if the -even-numbered bank of the reading CPU's cache is extremely busy while the -odd-numbered bank is idle, one can see the new value of the pointer P (&B), -but the old value of the variable B (2). +can be used to record rare error conditions and the like, and the CPUs' +naturally occurring ordering prevents such records from being lost. The data dependency barrier is very important to the RCU system,