Skip to contentSkip to conversation

Documentation/memory-barriers: fix a error that mistakes a CPU notion in Section Transitivity

PATCH In review larmbr 3 participants 4 messages Aug 27, 2013 – Aug 31, 2013

Subsystems (2)
lore
Share & tools
lore

larmbr

author
#0 lore raw

PATCH 1/1 Documentation/memory-barriers: fix a error that mistakes a CPU notion in Section Transitivity

The memory-barriers document may has a error in Section TRANSITIVITY.

For transitivity, see a example below, given that

* CPU 2's load from X follows CPU 1's store to X, and CPU 2's load from Y preceds CPU 3's store to Y.

CPU 1 CPU 2 CPU 3
======================= ======================= =======================

         { X = 0, Y = 0 }
 STORE X=1               LOAD X                  STORE Y=1
                         <read barrier>          <general barrier>
                         LOAD Y                  LOAD X

The <read barrier> in CPU 2 is inadquate, because it could _only_ guarantees that load operation _happen before_ load operation after the barrier, with respect to CPU 3, which constrained by a general barrier, but provide _NO_ guarantee that CPU 1' store X will happen before the <read barrier>.

Therefore, if this example runs on a system where CPUs 1 and 3 share a store buffer or a level of cache, CPU 3 might have early access to CPU 1's writes.

The original text has mistaken CPU 2 for CPU 3, so this patch fixes this, and adds a paragraph to explain why a <full barrier> should guarantee this.

---
Documentation/memory-barriers.txt | 11 +++++++++--

1 file changed, 9 insertions(+), 2 deletions(-)
Documentation/memory-barriers.txt +9 -2
index fa5d8a9..590a5a9 100644
@@ -992,6 +992,13 @@ transitivity.  Therefore, in the above example, if CPU 2's load from X
 returns 1 and its load from Y returns 0, then CPU 3's load from X must
 also return 1.
 
+The key point is that CPU 1's storing 1 to X preceds CPU 2's loading 1
+from X, and CPU 2's loading 0 from Y preceds CPU 3's storing 1 to Y,
+which implies a ordering that the general barrier in CPU 2 guarantees:
+all store and load operations must happen before those after the barrier
+with respect to view of CPU 3, which constrained by a general barrier, too.
+Thus, CPU 3's load from X must return 1.
+
 However, transitivity is -not- guaranteed for read or write barriers.
 For example, suppose that CPU 2's general barrier in the above example
 is changed to a read barrier as shown below:
@@ -1009,8 +1016,8 @@ and CPU 3's load from X to return 0.
 
 The key point is that although CPU 2's read barrier orders its pair
 of loads, it does not guarantee to order CPU 1's store.  Therefore, if
-this example runs on a system where CPUs 1 and 2 share a store buffer
-or a level of cache, CPU 2 might have early access to CPU 1's writes.
+this example runs on a system where CPUs 1 and 3 share a store buffer
+or a level of cache, CPU 3 might have early access to CPU 1's writes.
 General barriers are therefore required to ensure that all CPUs agree
 on the combined order of CPU 1's and CPU 2's accesses.
 
#1 lore raw
Quoted 6 lines · larmbr

The memory-barriers document may has a error in Section TRANSITIVITY.

For transitivity, see a example below, given that

* CPU 2's load from X follows CPU 1's store to X, and CPU 2's load from Y preceds CPU 3's store to Y.

I'd prefer somebody with a better understanding of this code review it before merging. I'm not a memory barrier semantics expert, I can't tell you if this _is_ a bug.

Quoted 2 lines

+The key point is that CPU 1's storing 1 to X preceds CPU 2's loading 1

precedes

Quoted 1 line

+from X, and CPU 2's loading 0 from Y preceds CPU 3's storing 1 to Y,

precedes

Quoted 2 lines

+which implies a ordering that the general barrier in CPU 2 guarantees:

an ordering

Quoted 4 lines

+all store and load operations must happen before those after the barrier
+with respect to view of CPU 3, which constrained by a general barrier, too.

the view of (or possibly "from the point of view of", the current phrasing is awkward)

which is constrained

Rob

#2 lore raw

Hi, Rob, thanks reviewing
and I'm sorry for my careless writing.

I resend the revised patch below:

---

The memory-barriers document may has an error in Section TRANSITIVITY.

For transitivity, see an example below, given that

* CPU 2's load from X follows CPU 1's store to X,
* CPU 2's load from Y preceds CPU 3's store to Y.

CPU 1 CPU 2 CPU 3
=====================================================================

            { X = 0, Y = 0 }

STORE X=1 LOAD X STORE Y=1
<read barrier> <general barrier>
LOAD Y LOAD X

The <read barrier> in CPU 2 is inadquate, because it could _only_ guarantees that load operation _happen before_ load operation after the barrier, with respect to CPU 3, which constrained by a general barrier, but provide _NO_ guarantee that CPU 1' store X will happen before the <read barrier>.

Therefore, if this example runs on a system where CPUs 1 and 3 share a store buffer
or a level of cache, CPU 3 might have early access to CPU 1's writes.

The original text has mistaken CPU 2 for CPU 3, so this patch fixes this, and adds
a paragraph to explain why a <full barrier> should guarantee this.

---
Documentation/memory-barriers.txt | 11 +++++++++--

1 file changed, 9 insertions(+), 2 deletions(-)
(quoted diff) +0 -0

b/Documentation/memory-barriers.txt
index fa5d8a9..590a5a9 100644

Documentation/memory-barriers.txt +0 -0
@@ -992,6 +992,13 @@ transitivity.  Therefore, in the above example,

if CPU 2's load from X
returns 1 and its load from Y returns 0, then CPU 3's load from X must also return 1.

+The key point is that CPU 1's storing 1 to X precedes CPU 2's loading 1 +from X, and CPU 2's loading 0 from Y precedes CPU 3's storing 1 to Y, +which implies an ordering that the general barrier in CPU 2 guarantees:
+all store and load operations must happen before those after the barrier +with respect to CPU 3, which is constrained by a general barrier, too. +Thus, CPU 3's load from X must return 1.
+
However, transitivity is -not- guaranteed for read or write barriers. For example, suppose that CPU 2's general barrier in the above example is changed to a read barrier as shown below:
@@ -1009,8 +1016,8 @@ and CPU 3's load from X to return 0.

The key point is that although CPU 2's read barrier orders its pair of loads, it does not guarantee to order CPU 1's store. Therefore, if
-this example runs on a system where CPUs 1 and 2 share a store buffer -or a level of cache, CPU 2 might have early access to CPU 1's writes. +this example runs on a system where CPUs 1 and 3 share a store buffer +or a level of cache, CPU 3 might have early access to CPU 1's writes.
General barriers are therefore required to ensure that all CPUs agree on the combined order of CPU 1's and CPU 2's accesses.

--

Regards,
Zhan Jianyu

Quoted 44 lines · Rob Landley
Quoted 7 lines · larmbr

The memory-barriers document may has a error in Section TRANSITIVITY.

For transitivity, see a example below, given that

* CPU 2's load from X follows CPU 1's store to X, and CPU 2's load from Y preceds CPU 3's store to Y.

I'd prefer somebody with a better understanding of this code review it before merging. I'm not a memory barrier semantics expert, I can't tell you if this _is_ a bug.

Quoted 1 line

+The key point is that CPU 1's storing 1 to X preceds CPU 2's loading 1

precedes

Quoted 1 line

+from X, and CPU 2's loading 0 from Y preceds CPU 3's storing 1 to Y,

precedes

Quoted 1 line

+which implies a ordering that the general barrier in CPU 2 guarantees:

an ordering

Quoted 3 lines
(quoted diff) +2 -0
+all store and load operations must happen before those after the barrier
+with respect to view of CPU 3, which constrained by a general barrier,

too.

the view of (or possibly "from the point of view of", the current phrasing is awkward)

which is constrained

Rob

#3 lore raw
Quoted 51 lines · Zhan Jianyu

Hi, Rob, thanks reviewing
and I'm sorry for my careless writing.

I resend the revised patch below:

---

The memory-barriers document may has an error in Section TRANSITIVITY.

For transitivity, see an example below, given that

* CPU 2's load from X follows CPU 1's store to X,
* CPU 2's load from Y preceds CPU 3's store to Y.

CPU 1 CPU 2 CPU 3
=====================================================================

            { X = 0, Y = 0 }

STORE X=1 LOAD X STORE Y=1
<read barrier> <general barrier>
LOAD Y LOAD X

The <read barrier> in CPU 2 is inadquate, because it could _only_ guarantees that load operation _happen before_ load operation after the barrier, with respect to CPU 3, which constrained by a general barrier, but provide _NO_ guarantee that CPU 1' store X will happen before the <read barrier>.

Therefore, if this example runs on a system where CPUs 1 and 3 share a store buffer
or a level of cache, CPU 3 might have early access to CPU 1's writes.

The original text has mistaken CPU 2 for CPU 3, so this patch fixes this, and adds
a paragraph to explain why a <full barrier> should guarantee this.

---
Documentation/memory-barriers.txt | 11 +++++++++--

1 file changed, 9 insertions(+), 2 deletions(-)
Documentation/memory-barriers.txt +0 -0
index fa5d8a9..590a5a9 100644
@@ -992,6 +992,13 @@ transitivity.  Therefore, in the above example,

if CPU 2's load from X
returns 1 and its load from Y returns 0, then CPU 3's load from X must also return 1.

Documentation/memory-barriers.txt

Quoted 7 lines
Documentation/memory-barriers.txt +7 -0
+The key point is that CPU 1's storing 1 to X precedes CPU 2's loading 1
+from X, and CPU 2's loading 0 from Y precedes CPU 3's storing 1 to Y,
+which implies an ordering that the general barrier in CPU 2 guarantees:
+all store and load operations must happen before those after the barrier
+with respect to CPU 3, which is constrained by a general barrier, too.
+Thus, CPU 3's load from X must return 1.
+

This one is a good addition, thank you!

Documentation/memory-barriers.txt and CPU 3's load from X to return 0. · line 1022

Quoted 13 lines

However, transitivity is -not- guaranteed for read or write barriers. For example, suppose that CPU 2's general barrier in the above example is changed to a read barrier as shown below:

Documentation/memory-barriers.txt +2 -2
@@ -1009,8 +1016,8 @@ and CPU 3's load from X to return 0.
 
 The key point is that although CPU 2's read barrier orders its pair
 of loads, it does not guarantee to order CPU 1's store.  Therefore, if
-this example runs on a system where CPUs 1 and 2 share a store buffer
-or a level of cache, CPU 2 might have early access to CPU 1's writes.
+this example runs on a system where CPUs 1 and 3 share a store buffer
+or a level of cache, CPU 3 might have early access to CPU 1's writes.
 General barriers are therefore required to ensure that all CPUs agree
 on the combined order of CPU 1's and CPU 2's accesses.

However, this change does not make sense. If CPUs 1 and 3 shared a store buffer, then CPU 3 would be more likely to see x==1. We need CPUs 1 and 2 to share a store buffer to make it more likely that CPU 3 will see x==0.

Thanx, Paul

Quoted 53 lines
Documentation/memory-barriers.txt +0 -1
--

Regards,
Zhan Jianyu

Quoted 44 lines · Rob Landley
Quoted 7 lines · larmbr

The memory-barriers document may has a error in Section TRANSITIVITY.

For transitivity, see a example below, given that

* CPU 2's load from X follows CPU 1's store to X, and CPU 2's load from Y preceds CPU 3's store to Y.

I'd prefer somebody with a better understanding of this code review it before merging. I'm not a memory barrier semantics expert, I can't tell you if this _is_ a bug.

Quoted 1 line

+The key point is that CPU 1's storing 1 to X preceds CPU 2's loading 1

precedes

Quoted 1 line

+from X, and CPU 2's loading 0 from Y preceds CPU 3's storing 1 to Y,

precedes

Quoted 1 line

+which implies a ordering that the general barrier in CPU 2 guarantees:

an ordering

Quoted 3 lines
(quoted diff) +2 -0
+all store and load operations must happen before those after the barrier
+with respect to view of CPU 3, which constrained by a general barrier,

too.

the view of (or possibly "from the point of view of", the current phrasing is awkward)

which is constrained

Rob