Skip to contentSkip to conversation

Updates to the formal memory model

PATCH New Paul E. McKenney 2 participants 28 messages Jul 16, 2018 – Jul 17, 2018

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover Updates to the formal memory model

Hello!

This series contains updates to the Linux kernel's formal memory model in tools/memory-model, along with corresponding changes in documentation and Linux-kernel code. These patches are ready for inclusion into -tip.

1. Add a litmus test for full multi-copy atomicity.

2. Fix the name of the ISA2+pooncelock+pooncelock+pombonce litmus test.

3. Add Daniel Lustig as an LKMM reviewer, with focus on RISC-V,
courtesy of Palmer Dabbelt.

4. Update Korean translation to fix broken DMA vs. MMIO ordering
example, courtesy of SeongJae Park with edits suggested by Byungchul Park.

5-6. Remove the now-obsolete ACCESS_ONCE() from recipes and the model
itself, courtesy of Mark Rutland.

7. Make regression-test scripts executable.

8. Describe atomic_set as a write operation, courtesy of Jonathan
Neuschäfer.

9. Add informal LKMM documentation to MAINTAINERS.

10. Use smp_mb() in wake_woken_function(), courtesy of Andrea Parri.

11. Clarify requirements for smp_mb__after_spinlock(), courtesy of
Andrea Parri.

12. Update wake_up() and friends' memory-barrier guarantees,
courtesy of Andrea Parri.

13. Fix "smb_wmb()" typo (should be "smp_wmb()"), courtesy of
Yauheni Kaliuta.

14. Rename litmus tests to comply to norm7, courtesy of Andrea Parri.

Thanx, Paul

------------------------------------------------------------------------

 Documentation/core-api/atomic_ops.rst                                                      |    2 
 Documentation/memory-barriers.txt                                                          |   43 +++---
 Documentation/translations/ko_KR/memory-barriers.txt                                       |   22 +--
 MAINTAINERS                                                                                |    6 
 include/linux/sched.h                                                                      |    4 
 include/linux/spinlock.h                                                                   |   53 +++++--
 kernel/sched/completion.c                                                                  |    8 -
 kernel/sched/core.c                                                                        |   71 ++++------
 kernel/sched/wait.c                                                                        |   55 +++----
 tools/memory-model/Documentation/explanation.txt                                           |    2 
 tools/memory-model/Documentation/recipes.txt                                               |   12 -
 tools/memory-model/README                                                                  |   20 +-
 tools/memory-model/linux-kernel.bell                                                       |    2 
 tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus                      |    2 
 tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus                 |    2 
 tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus                     |    2 
 tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus                |    2 
 tools/memory-model/litmus-tests/R+fencembonceonces.litmus                                  |    2 
 tools/memory-model/litmus-tests/README                                                     |   25 ++-
 tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus                    |    2 
 tools/memory-model/litmus-tests/SB+fencembonceonces.litmus                                 |    2 
 tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus                          |   32 ++++
 tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus             |    2 
 tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus |    2 
 tools/memory-model/scripts/checkalllitmus.sh                                               |    2 
 tools/memory-model/scripts/checklitmus.sh                                                  |    2 
 26 files changed, 223 insertions(+), 156 deletions(-)
#1 lore raw

PATCH 1/14 tools/memory-model: Add litmus test for full multicopy atomicity

This commit adds a litmus test suggested by Alan Stern that is forbidden on fully multicopy atomic systems, but allowed on other-multicopy and on non-multicopy atomic systems. For reference, s390 is fully multicopy atomic, x86 and ARMv8 are other-multicopy atomic, and ARMv7 and powerpc are non-multicopy atomic.

---
 tools/memory-model/litmus-tests/README        |  9 ++++++
 .../SB+rfionceonce-poonceonces.litmus         | 32 +++++++++++++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus
tools/memory-model/litmus-tests/README +9 -0
index 17eb9a8c222d..00140aaf58b7 100644
@@ -111,6 +111,15 @@ SB+mbonceonces.litmus
 SB+poonceonces.litmus
 	As above, but without the smp_mb() invocations.
 
+SB+rfionceonce-poonceonces.litmus
+	This litmus test demonstrates that LKMM is not fully multicopy
+	atomic.  (Neither is it other multicopy atomic.)  This litmus test
+	also demonstrates the "locations" debugging aid, which designates
+	additional registers and locations to be printed out in the dump
+	of final states in the herd7 output.  Without the "locations"
+	statement, only those registers and locations mentioned in the
+	"exists" clause will be printed.
+
 S+poonceonces.litmus
 	As below, but without the smp_wmb() and acquire load.
 
tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus new file +32 -0
new file mode 100644
index 000000000000..04a16603660b
@@ -0,0 +1,32 @@
+C SB+rfionceonce-poonceonces
+
+(*
+ * Result: Sometimes
+ *
+ * This litmus test demonstrates that LKMM is not fully multicopy atomic.
+ *)
+
+{}
+
+P0(int *x, int *y)
+{
+	int r1;
+	int r2;
+
+	WRITE_ONCE(*x, 1);
+	r1 = READ_ONCE(*x);
+	r2 = READ_ONCE(*y);
+}
+
+P1(int *x, int *y)
+{
+	int r3;
+	int r4;
+
+	WRITE_ONCE(*y, 1);
+	r3 = READ_ONCE(*y);
+	r4 = READ_ONCE(*x);
+}
+
+locations [0:r1; 1:r3; x; y] (* Debug aid: Print things not in "exists". *)
+exists (0:r2=0 /\ 1:r4=0)
Signature · 1 line
2.17.1
#2 lore raw

[tip:locking/core] tools/memory-model: Add litmus test for full multicopy atomicity

tools/memory-model: Add litmus test for full multicopy atomicity
Commit-ID:  b464818978d45cd4d78c8f13207891142c68bea9
Gitweb:     https://git.kernel.org/tip/b464818978d45cd4d78c8f13207891142c68bea9
Author:     Paul E. McKenney <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:52 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:29:29 +0200

tools/memory-model: Add litmus test for full multicopy atomicity

This commit adds a litmus test suggested by Alan Stern that is forbidden on fully multicopy atomic systems, but allowed on other-multicopy and on non-multicopy atomic systems. For reference, s390 is fully multicopy atomic, x86 and ARMv8 are other-multicopy atomic, and ARMv7 and powerpc are non-multicopy atomic.

---
 tools/memory-model/litmus-tests/README             |  9 ++++++
 .../litmus-tests/SB+rfionceonce-poonceonces.litmus | 32 ++++++++++++++++++++++
 2 files changed, 41 insertions(+)
tools/memory-model/litmus-tests/README +9 -0
index 17eb9a8c222d..00140aaf58b7 100644
@@ -111,6 +111,15 @@ SB+mbonceonces.litmus
 SB+poonceonces.litmus
 	As above, but without the smp_mb() invocations.
 
+SB+rfionceonce-poonceonces.litmus
+	This litmus test demonstrates that LKMM is not fully multicopy
+	atomic.  (Neither is it other multicopy atomic.)  This litmus test
+	also demonstrates the "locations" debugging aid, which designates
+	additional registers and locations to be printed out in the dump
+	of final states in the herd7 output.  Without the "locations"
+	statement, only those registers and locations mentioned in the
+	"exists" clause will be printed.
+
 S+poonceonces.litmus
 	As below, but without the smp_wmb() and acquire load.
 
tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus new file +32 -0
new file mode 100644
index 000000000000..04a16603660b
@@ -0,0 +1,32 @@
+C SB+rfionceonce-poonceonces
+
+(*
+ * Result: Sometimes
+ *
+ * This litmus test demonstrates that LKMM is not fully multicopy atomic.
+ *)
+
+{}
+
+P0(int *x, int *y)
+{
+	int r1;
+	int r2;
+
+	WRITE_ONCE(*x, 1);
+	r1 = READ_ONCE(*x);
+	r2 = READ_ONCE(*y);
+}
+
+P1(int *x, int *y)
+{
+	int r3;
+	int r4;
+
+	WRITE_ONCE(*y, 1);
+	r3 = READ_ONCE(*y);
+	r4 = READ_ONCE(*x);
+}
+
+locations [0:r1; 1:r3; x; y] (* Debug aid: Print things not in "exists". *)
+exists (0:r2=0 /\ 1:r4=0)
#3 lore raw

PATCH 2/14 tools/memory-model: Fix ISA2+pooncelock+pooncelock+pombonce name

In reply to Paul E. McKenney

The names on the first line of the litmus tests are arbitrary, but the convention is that they be the filename without the trailing ".litmus". This commit therefore removes the stray trailing ".litmus" from ISA2+pooncelock+pooncelock+pombonce.litmus's name.

---
 .../litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus +1 -1
index 7a39a0aaa976..0f749e419b34 100644
@@ -1,4 +1,4 @@
-C ISA2+pooncelock+pooncelock+pombonce.litmus
+C ISA2+pooncelock+pooncelock+pombonce
 
 (*
  * Result: Sometimes
Signature · 1 line
2.17.1
#4 lore raw

[tip:locking/core] tools/memory-model: Fix ISA2+pooncelock+pooncelock+pombonce name

tools/memory-model: Fix ISA2+pooncelock+pooncelock+pombonce name
Commit-ID:  acb6c96c52ac0da6bb464173ad2cf5ada9049ad4
Gitweb:     https://git.kernel.org/tip/acb6c96c52ac0da6bb464173ad2cf5ada9049ad4
Author:     Paul E. McKenney <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:53 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:29:31 +0200

tools/memory-model: Fix ISA2+pooncelock+pooncelock+pombonce name

The names on the first line of the litmus tests are arbitrary, but the convention is that they be the filename without the trailing ".litmus". This commit therefore removes the stray trailing ".litmus" from ISA2+pooncelock+pooncelock+pombonce.litmus's name.

---
 .../litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus             | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus +1 -1
index 7a39a0aaa976..0f749e419b34 100644
@@ -1,4 +1,4 @@
-C ISA2+pooncelock+pooncelock+pombonce.litmus
+C ISA2+pooncelock+pooncelock+pombonce
 
 (*
  * Result: Sometimes
#5 lore raw

PATCH 3/14 MAINTAINERS: Add Daniel Lustig as an LKMM reviewer

In reply to Paul E. McKenney

From: Palmer Dabbelt <[email protected]>

Dan runs the RISC-V memory model working group. I've been forwarding him LKMM emails that end up in my inbox, but I'm far from an expert in this stuff. He requested to be added as a reviewer, which seems sane to me as it'll take a human out of the loop.

---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
index 9d5eeff51b5f..ac8ed55dbe9b 100644
@@ -8316,6 +8316,7 @@ M:	Jade Alglave <[email protected]>
 M:	Luc Maranget <[email protected]>
 M:	"Paul E. McKenney" <[email protected]>
 R:	Akira Yokosawa <[email protected]>
+R:	Daniel Lustig <[email protected]>
 L:	[email protected]
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
Signature · 1 line
2.17.1
#6 lore raw

[tip:locking/core] MAINTAINERS: Add Daniel Lustig as an LKMM reviewer

MAINTAINERS: Add Daniel Lustig as an LKMM reviewer
Commit-ID:  2caf412dc46149b8714e0f52c8337e8eda035a83
Gitweb:     https://git.kernel.org/tip/2caf412dc46149b8714e0f52c8337e8eda035a83
Author:     Palmer Dabbelt <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:54 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:29:32 +0200

MAINTAINERS: Add Daniel Lustig as an LKMM reviewer

Dan runs the RISC-V memory model working group. I've been forwarding him LKMM emails that end up in my inbox, but I'm far from an expert in this stuff. He requested to be added as a reviewer, which seems sane to me as it'll take a human out of the loop.

---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)
MAINTAINERS +1 -0
index 192d7f73fd01..eb427596f3e0 100644
@@ -8316,6 +8316,7 @@ M:	Jade Alglave <[email protected]>
 M:	Luc Maranget <[email protected]>
 M:	"Paul E. McKenney" <[email protected]>
 R:	Akira Yokosawa <[email protected]>
+R:	Daniel Lustig <[email protected]>
 L:	[email protected]
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
#7 lore raw

PATCH 4/14 locking/memory-barriers.txt/kokr: Update Korean translation to fix broken DMA vs. MMIO ordering example

In reply to Paul E. McKenney

From: SeongJae Park <[email protected]>

Translate this commit to Korean:

5846581e3563 ("locking/memory-barriers.txt: Fix broken DMA vs. MMIO ordering example")

[ paulmck: Updated based on feedback from Byungchul Park. ]
---
 .../translations/ko_KR/memory-barriers.txt    | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)
Documentation/translations/ko_KR/memory-barriers.txt +11 -11
index 921739d00f69..7f01fb1c1084 100644
@@ -1891,22 +1891,22 @@ Mandatory 배리어들은 SMP 시스템에서도 UP 시스템에서도 SMP 효
 		/* 소유권을 수정 */
 		desc->status = DEVICE_OWN;
 
-		/* MMIO 를 통해 디바이스에 공지를 하기 전에 메모리를 동기화 */
-		wmb();
-
 		/* 업데이트된 디스크립터의 디바이스에 공지 */
 		writel(DESC_NOTIFY, doorbell);
 	}
 
      dma_rmb() 는 디스크립터로부터 데이터를 읽어오기 전에 디바이스가 소유권을
-     내놓았음을 보장하게 하고, dma_wmb() 는 디바이스가 자신이 소유권을 다시
-     가졌음을 보기 전에 디스크립터에 데이터가 쓰였음을 보장합니다.  wmb() 는
-     캐시 일관성이 없는 (cache incoherent) MMIO 영역에 쓰기를 시도하기 전에
-     캐시 일관성이 있는 메모리 (cache coherent memory) 쓰기가 완료되었음을
-     보장해주기 위해 필요합니다.
-
-     consistent memory 에 대한 자세한 내용을 위해선 Documentation/DMA-API.txt
-     문서를 참고하세요.
+     내려놓았을 것을 보장하고, dma_wmb() 는 디바이스가 자신이 소유권을 다시
+     가졌음을 보기 전에 디스크립터에 데이터가 쓰였을 것을 보장합니다.  참고로,
+     writel() 을 사용하면 캐시 일관성이 있는 메모리 (cache coherent memory)
+     쓰기가 MMIO 영역에의 쓰기 전에 완료되었을 것을 보장하므로 writel() 앞에
+     wmb() 를 실행할 필요가 없음을 알아두시기 바랍니다.  writel() 보다 비용이
+     저렴한 writel_relaxed() 는 이런 보장을 제공하지 않으므로 여기선 사용되지
+     않아야 합니다.
+
+     writel_relaxed() 와 같은 완화된 I/O 접근자들에 대한 자세한 내용을 위해서는
+     "커널 I/O 배리어의 효과" 섹션을, consistent memory 에 대한 자세한 내용을
+     위해선 Documentation/DMA-API.txt 문서를 참고하세요.
 
 
 MMIO 쓰기 배리어
Signature · 1 line
2.17.1
#8 lore raw

[tip:locking/core] locking/memory-barriers.txt/kokr: Update Korean translation to fix broken DMA vs. MMIO ordering example

locking/memory-barriers.txt/kokr: Update Korean translation to fix broken DMA vs. MMIO ordering example
Commit-ID:  68ec3444b32158541f4bbd47ed9345634c56399d
Gitweb:     https://git.kernel.org/tip/68ec3444b32158541f4bbd47ed9345634c56399d
Author:     SeongJae Park <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:55 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:29:33 +0200

locking/memory-barriers.txt/kokr: Update Korean translation to fix broken DMA vs. MMIO ordering example

Translate this commit to Korean:

5846581e3563 ("locking/memory-barriers.txt: Fix broken DMA vs. MMIO ordering example")

---
 .../translations/ko_KR/memory-barriers.txt         | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
Documentation/translations/ko_KR/memory-barriers.txt +11 -11
index 921739d00f69..7f01fb1c1084 100644
@@ -1891,22 +1891,22 @@ Mandatory 배리어들은 SMP 시스템에서도 UP 시스템에서도 SMP 효
 		/* 소유권을 수정 */
 		desc->status = DEVICE_OWN;
 
-		/* MMIO 를 통해 디바이스에 공지를 하기 전에 메모리를 동기화 */
-		wmb();
-
 		/* 업데이트된 디스크립터의 디바이스에 공지 */
 		writel(DESC_NOTIFY, doorbell);
 	}
 
      dma_rmb() 는 디스크립터로부터 데이터를 읽어오기 전에 디바이스가 소유권을
-     내놓았음을 보장하게 하고, dma_wmb() 는 디바이스가 자신이 소유권을 다시
-     가졌음을 보기 전에 디스크립터에 데이터가 쓰였음을 보장합니다.  wmb() 는
-     캐시 일관성이 없는 (cache incoherent) MMIO 영역에 쓰기를 시도하기 전에
-     캐시 일관성이 있는 메모리 (cache coherent memory) 쓰기가 완료되었음을
-     보장해주기 위해 필요합니다.
-
-     consistent memory 에 대한 자세한 내용을 위해선 Documentation/DMA-API.txt
-     문서를 참고하세요.
+     내려놓았을 것을 보장하고, dma_wmb() 는 디바이스가 자신이 소유권을 다시
+     가졌음을 보기 전에 디스크립터에 데이터가 쓰였을 것을 보장합니다.  참고로,
+     writel() 을 사용하면 캐시 일관성이 있는 메모리 (cache coherent memory)
+     쓰기가 MMIO 영역에의 쓰기 전에 완료되었을 것을 보장하므로 writel() 앞에
+     wmb() 를 실행할 필요가 없음을 알아두시기 바랍니다.  writel() 보다 비용이
+     저렴한 writel_relaxed() 는 이런 보장을 제공하지 않으므로 여기선 사용되지
+     않아야 합니다.
+
+     writel_relaxed() 와 같은 완화된 I/O 접근자들에 대한 자세한 내용을 위해서는
+     "커널 I/O 배리어의 효과" 섹션을, consistent memory 에 대한 자세한 내용을
+     위해선 Documentation/DMA-API.txt 문서를 참고하세요.
 
 
 MMIO 쓰기 배리어
#9 lore raw

PATCH 5/14 tools/memory-model: Remove ACCESS_ONCE() from recipes

In reply to Paul E. McKenney

From: Mark Rutland <[email protected]>

Since commit:

b899a850431e2dd0 ("compiler.h: Remove ACCESS_ONCE()")

... there has been no definition of ACCESS_ONCE() in the kernel tree, and it has been necessary to use READ_ONCE() or WRITE_ONCE() instead.

Let's update the exmaples in recipes.txt likewise for consistency, using READ_ONCE() for reads.

Cc Alan Stern <[email protected]>
Cc Will Deacon <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Boqun Feng <[email protected]>
Cc Nicholas Piggin <[email protected]>
Cc David Howells <[email protected]>
Cc Jade Alglave <[email protected]>
Cc Luc Maranget <[email protected]>
Cc Akira Yokosawa <[email protected]>
---
 tools/memory-model/Documentation/recipes.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/memory-model/Documentation/recipes.txt +2 -2
index ee4309a87fc4..1fea8ef2b184 100644
@@ -322,9 +322,9 @@ the following write-side code fragment:
 And the xlog_valid_lsn() function in fs/xfs/xfs_log_priv.h contains
 the corresponding read-side code fragment:
 
-	cur_cycle = ACCESS_ONCE(log->l_curr_cycle);
+	cur_cycle = READ_ONCE(log->l_curr_cycle);
 	smp_rmb();
-	cur_block = ACCESS_ONCE(log->l_curr_block);
+	cur_block = READ_ONCE(log->l_curr_block);
 
 Alternatively, consider the following comment in function
 perf_output_put_handle() in kernel/events/ring_buffer.c:
Signature · 1 line
2.17.1
#10 lore raw

[tip:locking/core] tools/memory-model: Remove ACCESS_ONCE() from recipes

tools/memory-model: Remove ACCESS_ONCE() from recipes
Commit-ID:  5bde06b63af2af8c2326270aae041067eef89245
Gitweb:     https://git.kernel.org/tip/5bde06b63af2af8c2326270aae041067eef89245
Author:     Mark Rutland <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:56 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:29:34 +0200

tools/memory-model: Remove ACCESS_ONCE() from recipes

Since commit:

b899a850431e2dd0 ("compiler.h: Remove ACCESS_ONCE()")

... there has been no definition of ACCESS_ONCE() in the kernel tree, and it has been necessary to use READ_ONCE() or WRITE_ONCE() instead.

Let's update the exmaples in recipes.txt likewise for consistency, using READ_ONCE() for reads.

---
 tools/memory-model/Documentation/recipes.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/memory-model/Documentation/recipes.txt +2 -2
index ee4309a87fc4..1fea8ef2b184 100644
@@ -322,9 +322,9 @@ the following write-side code fragment:
 And the xlog_valid_lsn() function in fs/xfs/xfs_log_priv.h contains
 the corresponding read-side code fragment:
 
-	cur_cycle = ACCESS_ONCE(log->l_curr_cycle);
+	cur_cycle = READ_ONCE(log->l_curr_cycle);
 	smp_rmb();
-	cur_block = ACCESS_ONCE(log->l_curr_block);
+	cur_block = READ_ONCE(log->l_curr_block);
 
 Alternatively, consider the following comment in function
 perf_output_put_handle() in kernel/events/ring_buffer.c:
#11 lore raw

PATCH 6/14 tools/memory-model: Remove ACCESS_ONCE() from model

In reply to Paul E. McKenney

From: Mark Rutland <[email protected]>

Since commit:

b899a850431e2dd0 ("compiler.h: Remove ACCESS_ONCE()")

... there has been no definition of ACCESS_ONCE() in the kernel tree, and it has been necessary to use READ_ONCE() or WRITE_ONCE() instead.

Correspondingly, let's remove ACCESS_ONCE() from the kernel memory model.

Cc Alan Stern <[email protected]>
Cc Will Deacon <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Boqun Feng <[email protected]>
Cc Nicholas Piggin <[email protected]>
Cc David Howells <[email protected]>
Cc Jade Alglave <[email protected]>
Cc Luc Maranget <[email protected]>
Cc Akira Yokosawa <[email protected]>
---
 tools/memory-model/linux-kernel.bell | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/memory-model/linux-kernel.bell +1 -1
index 64f5740e0e75..b84fb2f67109 100644
@@ -13,7 +13,7 @@
 
 "Linux-kernel memory consistency model"
 
-enum Accesses = 'once (*READ_ONCE,WRITE_ONCE,ACCESS_ONCE*) ||
+enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) ||
 		'release (*smp_store_release*) ||
 		'acquire (*smp_load_acquire*) ||
 		'noreturn (* R of non-return RMW *)
Signature · 1 line
2.17.1
#12 lore raw

[tip:locking/core] tools/memory-model: Remove ACCESS_ONCE() from model

tools/memory-model: Remove ACCESS_ONCE() from model
Commit-ID:  af41db5ef7c7cf0fee860f65cab59d0d188098d2
Gitweb:     https://git.kernel.org/tip/af41db5ef7c7cf0fee860f65cab59d0d188098d2
Author:     Mark Rutland <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:57 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:29:35 +0200

tools/memory-model: Remove ACCESS_ONCE() from model

Since commit:

b899a850431e2dd0 ("compiler.h: Remove ACCESS_ONCE()")

... there has been no definition of ACCESS_ONCE() in the kernel tree, and it has been necessary to use READ_ONCE() or WRITE_ONCE() instead.

Correspondingly, let's remove ACCESS_ONCE() from the kernel memory model.

---
 tools/memory-model/linux-kernel.bell | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/memory-model/linux-kernel.bell +1 -1
index 64f5740e0e75..b84fb2f67109 100644
@@ -13,7 +13,7 @@
 
 "Linux-kernel memory consistency model"
 
-enum Accesses = 'once (*READ_ONCE,WRITE_ONCE,ACCESS_ONCE*) ||
+enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) ||
 		'release (*smp_store_release*) ||
 		'acquire (*smp_load_acquire*) ||
 		'noreturn (* R of non-return RMW *)
#13 lore raw

PATCH 7/14 tools/memory-model: Make scripts executable

In reply to Paul E. McKenney

This commit makes the scripts executable to avoid the need for everyone to do so manually in their archive.

---
 tools/memory-model/scripts/checkalllitmus.sh | 2 +-
 tools/memory-model/scripts/checklitmus.sh    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 tools/memory-model/scripts/checkalllitmus.sh
 mode change 100644 => 100755 tools/memory-model/scripts/checklitmus.sh
tools/memory-model/scripts/checkalllitmus.sh +1 -1
old mode 100644
new mode 100755
index af0aa15ab84e..ca528f9a24d4
@@ -9,7 +9,7 @@
 # appended.
 #
 # Usage:
-#	sh checkalllitmus.sh [ directory ]
+#	checkalllitmus.sh [ directory ]
 #
 # The LINUX_HERD_OPTIONS environment variable may be used to specify
 # arguments to herd, whose default is defined by the checklitmus.sh script.
tools/memory-model/scripts/checklitmus.sh +1 -1
old mode 100644
new mode 100755
index e2e477472844..bf12a75c0719
@@ -8,7 +8,7 @@
 # with ".out" appended.
 #
 # Usage:
-#	sh checklitmus.sh file.litmus
+#	checklitmus.sh file.litmus
 #
 # The LINUX_HERD_OPTIONS environment variable may be used to specify
 # arguments to herd, which default to "-conf linux-kernel.cfg".  Thus,
Signature · 1 line
2.17.1
#14 lore raw

[tip:locking/core] tools/memory-model: Make scripts executable

tools/memory-model: Make scripts executable
Commit-ID:  24675bb554f9e3d0e2bd61f6a7d8da50d224c8ff
Gitweb:     https://git.kernel.org/tip/24675bb554f9e3d0e2bd61f6a7d8da50d224c8ff
Author:     Paul E. McKenney <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:05:58 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:17 +0200

tools/memory-model: Make scripts executable

This commit makes the scripts executable to avoid the need for everyone to do so manually in their archive.

---
 tools/memory-model/scripts/checkalllitmus.sh | 2 +-
 tools/memory-model/scripts/checklitmus.sh    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
tools/memory-model/scripts/checkalllitmus.sh +1 -1
old mode 100644
new mode 100755
index af0aa15ab84e..ca528f9a24d4
@@ -9,7 +9,7 @@
 # appended.
 #
 # Usage:
-#	sh checkalllitmus.sh [ directory ]
+#	checkalllitmus.sh [ directory ]
 #
 # The LINUX_HERD_OPTIONS environment variable may be used to specify
 # arguments to herd, whose default is defined by the checklitmus.sh script.
tools/memory-model/scripts/checklitmus.sh +1 -1
old mode 100644
new mode 100755
index e2e477472844..bf12a75c0719
@@ -8,7 +8,7 @@
 # with ".out" appended.
 #
 # Usage:
-#	sh checklitmus.sh file.litmus
+#	checklitmus.sh file.litmus
 #
 # The LINUX_HERD_OPTIONS environment variable may be used to specify
 # arguments to herd, which default to "-conf linux-kernel.cfg".  Thus,
#15 lore raw

PATCH 8/14 docs: atomic_ops: Describe atomic_set as a write operation

In reply to Paul E. McKenney

From: Jonathan Neuschäfer <[email protected]>

The atomic_set() and ATOMIC_INIT() operations are writes, so this commit changes their description from "reads" to "writes".

---
 Documentation/core-api/atomic_ops.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/core-api/atomic_ops.rst +1 -1
index 2e7165f86f55..724583453e1f 100644
@@ -29,7 +29,7 @@ updated by one CPU, local_t is probably more appropriate. Please see
 local_t.
 
 The first operations to implement for atomic_t's are the initializers and
-plain reads. ::
+plain writes. ::
 
 	#define ATOMIC_INIT(i)		{ (i) }
 	#define atomic_set(v, i)	((v)->counter = (i))
Signature · 1 line
2.17.1
#16 lore raw

PATCH 9/14 tools/memory-model: Add informal LKMM documentation to MAINTAINERS

In reply to Paul E. McKenney

The Linux-kernel memory model has been informal, with a number of text files documenting it. It would be good to make sure that these informal descriptions are kept up to date and/or pruned appropriately. This commit therefore brings more of those text files into the LKMM MAINTAINERS file entry.

Cc Alan Stern <[email protected]>
Cc Will Deacon <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Boqun Feng <[email protected]>
Cc Nicholas Piggin <[email protected]>
Cc David Howells <[email protected]>
Cc Jade Alglave <[email protected]>
Cc Luc Maranget <[email protected]>
Cc Akira Yokosawa <[email protected]>
Cc Daniel Lustig <[email protected]>
Cc "David S. Miller" <[email protected]>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)
MAINTAINERS +5 -0
index ac8ed55dbe9b..b60d6daad132 100644
@@ -8318,9 +8318,14 @@ M:	"Paul E. McKenney" <[email protected]>
 R:	Akira Yokosawa <[email protected]>
 R:	Daniel Lustig <[email protected]>
 L:	[email protected]
+L:	[email protected]
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:	tools/memory-model/
+F:	Documentation/atomic_bitops.txt
+F:	Documentation/atomic_t.txt
+F:	Documentation/core-api/atomic_ops.rst
+F:	Documentation/core-api/refcount-vs-atomic.rst
 F:	Documentation/memory-barriers.txt
 
 LINUX SECURITY MODULE (LSM) FRAMEWORK
Signature · 1 line
2.17.1
#17 lore raw

[tip:locking/core] tools/memory-model: Add informal LKMM documentation to MAINTAINERS

tools/memory-model: Add informal LKMM documentation to MAINTAINERS
Commit-ID:  70b83069f70d185356beba3202b9d167ee39f051
Gitweb:     https://git.kernel.org/tip/70b83069f70d185356beba3202b9d167ee39f051
Author:     Paul E. McKenney <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:06:00 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:32 +0200

tools/memory-model: Add informal LKMM documentation to MAINTAINERS

The Linux-kernel memory model has been informal, with a number of text files documenting it. It would be good to make sure that these informal descriptions are kept up to date and/or pruned appropriately. This commit therefore brings more of those text files into the LKMM MAINTAINERS file entry.

Cc Akira Yokosawa <[email protected]>
Cc Alan Stern <[email protected]>
Cc Boqun Feng <[email protected]>
Cc Daniel Lustig <[email protected]>
Cc David Howells <[email protected]>
Cc David S. Miller <[email protected]>
Cc Jade Alglave <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Luc Maranget <[email protected]>
Cc Nicholas Piggin <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Will Deacon <[email protected]>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)
MAINTAINERS +5 -0
index eb427596f3e0..900889a47627 100644
@@ -8318,9 +8318,14 @@ M:	"Paul E. McKenney" <[email protected]>
 R:	Akira Yokosawa <[email protected]>
 R:	Daniel Lustig <[email protected]>
 L:	[email protected]
+L:	[email protected]
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:	tools/memory-model/
+F:	Documentation/atomic_bitops.txt
+F:	Documentation/atomic_t.txt
+F:	Documentation/core-api/atomic_ops.rst
+F:	Documentation/core-api/refcount-vs-atomic.rst
 F:	Documentation/memory-barriers.txt
 
 LINUX SECURITY MODULE (LSM) FRAMEWORK
#18 lore raw

PATCH 10/14 sched: Use smp_mb() in wake_woken_function()

In reply to Paul E. McKenney

From: Andrea Parri <[email protected]>

wake_woken_function() synchronizes with wait_woken() as follows:

[wait_woken] [wake_woken_function]

  entry->flags &= ~wq_flag_woken;    condition = true;
  smp_mb();                          smp_wmb();
  if (condition)                     wq_entry->flags |= wq_flag_woken;
     break;

This commit replaces the above smp_wmb() with an smp_mb() in order to guarantee that either wait_woken() sees the wait condition being true or the store to wq_entry->flags in woken_wake_function() follows the store in wait_woken() in the coherence order (so that the former can eventually be observed by wait_woken()).

The commit also fixes a comment associated to set_current_state() in wait_woken(): the comment pairs the barrier in set_current_state() to the above smp_wmb(), while the actual pairing involves the barrier in set_current_state() and the barrier executed by the try_to_wake_up() in wake_woken_function().

---
 kernel/sched/wait.c | 47 ++++++++++++++++++++-------------------------
 1 file changed, 21 insertions(+), 26 deletions(-)
kernel/sched/wait.c +21 -26
index 928be527477e..a7a2aaa3026a 100644
@@ -392,35 +392,36 @@ static inline bool is_kthread_should_stop(void)
  *     if (condition)
  *         break;
  *
- *     p->state = mode;				condition = true;
- *     smp_mb(); // A				smp_wmb(); // C
- *     if (!wq_entry->flags & WQ_FLAG_WOKEN)	wq_entry->flags |= WQ_FLAG_WOKEN;
- *         schedule()				try_to_wake_up();
- *     p->state = TASK_RUNNING;		    ~~~~~~~~~~~~~~~~~~
- *     wq_entry->flags &= ~WQ_FLAG_WOKEN;		condition = true;
- *     smp_mb() // B				smp_wmb(); // C
- *						wq_entry->flags |= WQ_FLAG_WOKEN;
- * }
- * remove_wait_queue(&wq_head, &wait);
+ *     // in wait_woken()			// in woken_wake_function()
  *
+ *     p->state = mode;				wq_entry->flags |= WQ_FLAG_WOKEN;
+ *     smp_mb(); // A				try_to_wake_up():
+ *     if (!(wq_entry->flags & WQ_FLAG_WOKEN))	   <full barrier>
+ *         schedule()				   if (p->state & mode)
+ *     p->state = TASK_RUNNING;			      p->state = TASK_RUNNING;
+ *     wq_entry->flags &= ~WQ_FLAG_WOKEN;	~~~~~~~~~~~~~~~~~~
+ *     smp_mb(); // B				condition = true;
+ * }						smp_mb(); // C
+ * remove_wait_queue(&wq_head, &wait);		wq_entry->flags |= WQ_FLAG_WOKEN;
  */
 long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout)
 {
-	set_current_state(mode); /* A */
 	/*
-	 * The above implies an smp_mb(), which matches with the smp_wmb() from
-	 * woken_wake_function() such that if we observe WQ_FLAG_WOKEN we must
-	 * also observe all state before the wakeup.
+	 * The below executes an smp_mb(), which matches with the full barrier
+	 * executed by the try_to_wake_up() in woken_wake_function() such that
+	 * either we see the store to wq_entry->flags in woken_wake_function()
+	 * or woken_wake_function() sees our store to current->state.
 	 */
+	set_current_state(mode); /* A */
 	if (!(wq_entry->flags & WQ_FLAG_WOKEN) && !is_kthread_should_stop())
 		timeout = schedule_timeout(timeout);
 	__set_current_state(TASK_RUNNING);
 
 	/*
-	 * The below implies an smp_mb(), it too pairs with the smp_wmb() from
-	 * woken_wake_function() such that we must either observe the wait
-	 * condition being true _OR_ WQ_FLAG_WOKEN such that we will not miss
-	 * an event.
+	 * The below executes an smp_mb(), which matches with the smp_mb() (C)
+	 * in woken_wake_function() such that either we see the wait condition
+	 * being true or the store to wq_entry->flags in woken_wake_function()
+	 * follows ours in the coherence order.
 	 */
 	smp_store_mb(wq_entry->flags, wq_entry->flags & ~WQ_FLAG_WOKEN); /* B */
 
@@ -430,14 +431,8 @@ EXPORT_SYMBOL(wait_woken);
 
 int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key)
 {
-	/*
-	 * Although this function is called under waitqueue lock, LOCK
-	 * doesn't imply write barrier and the users expects write
-	 * barrier semantics on wakeup functions.  The following
-	 * smp_wmb() is equivalent to smp_wmb() in try_to_wake_up()
-	 * and is paired with smp_store_mb() in wait_woken().
-	 */
-	smp_wmb(); /* C */
+	/* Pairs with the smp_store_mb() in wait_woken(). */
+	smp_mb(); /* C */
 	wq_entry->flags |= WQ_FLAG_WOKEN;
 
 	return default_wake_function(wq_entry, mode, sync, key);
Signature · 1 line
2.17.1
#19 lore raw

[tip:locking/core] sched/core: Use smp_mb() in wake_woken_function()

sched/core: Use smp_mb() in wake_woken_function()
Commit-ID:  76e079fefc8f62bd9b2cd2950814d1ee806e31a5
Gitweb:     https://git.kernel.org/tip/76e079fefc8f62bd9b2cd2950814d1ee806e31a5
Author:     Andrea Parri <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:06:01 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:33 +0200

sched/core: Use smp_mb() in wake_woken_function()

wake_woken_function() synchronizes with wait_woken() as follows:

[wait_woken] [wake_woken_function]

  entry->flags &= ~wq_flag_woken;    condition = true;
  smp_mb();                          smp_wmb();
  if (condition)                     wq_entry->flags |= wq_flag_woken;
     break;

This commit replaces the above smp_wmb() with an smp_mb() in order to guarantee that either wait_woken() sees the wait condition being true or the store to wq_entry->flags in woken_wake_function() follows the store in wait_woken() in the coherence order (so that the former can eventually be observed by wait_woken()).

The commit also fixes a comment associated to set_current_state() in wait_woken(): the comment pairs the barrier in set_current_state() to the above smp_wmb(), while the actual pairing involves the barrier in set_current_state() and the barrier executed by the try_to_wake_up() in wake_woken_function().

---
 kernel/sched/wait.c | 47 +++++++++++++++++++++--------------------------
 1 file changed, 21 insertions(+), 26 deletions(-)
kernel/sched/wait.c +21 -26
index 928be527477e..a7a2aaa3026a 100644
@@ -392,35 +392,36 @@ static inline bool is_kthread_should_stop(void)
  *     if (condition)
  *         break;
  *
- *     p->state = mode;				condition = true;
- *     smp_mb(); // A				smp_wmb(); // C
- *     if (!wq_entry->flags & WQ_FLAG_WOKEN)	wq_entry->flags |= WQ_FLAG_WOKEN;
- *         schedule()				try_to_wake_up();
- *     p->state = TASK_RUNNING;		    ~~~~~~~~~~~~~~~~~~
- *     wq_entry->flags &= ~WQ_FLAG_WOKEN;		condition = true;
- *     smp_mb() // B				smp_wmb(); // C
- *						wq_entry->flags |= WQ_FLAG_WOKEN;
- * }
- * remove_wait_queue(&wq_head, &wait);
+ *     // in wait_woken()			// in woken_wake_function()
  *
+ *     p->state = mode;				wq_entry->flags |= WQ_FLAG_WOKEN;
+ *     smp_mb(); // A				try_to_wake_up():
+ *     if (!(wq_entry->flags & WQ_FLAG_WOKEN))	   <full barrier>
+ *         schedule()				   if (p->state & mode)
+ *     p->state = TASK_RUNNING;			      p->state = TASK_RUNNING;
+ *     wq_entry->flags &= ~WQ_FLAG_WOKEN;	~~~~~~~~~~~~~~~~~~
+ *     smp_mb(); // B				condition = true;
+ * }						smp_mb(); // C
+ * remove_wait_queue(&wq_head, &wait);		wq_entry->flags |= WQ_FLAG_WOKEN;
  */
 long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout)
 {
-	set_current_state(mode); /* A */
 	/*
-	 * The above implies an smp_mb(), which matches with the smp_wmb() from
-	 * woken_wake_function() such that if we observe WQ_FLAG_WOKEN we must
-	 * also observe all state before the wakeup.
+	 * The below executes an smp_mb(), which matches with the full barrier
+	 * executed by the try_to_wake_up() in woken_wake_function() such that
+	 * either we see the store to wq_entry->flags in woken_wake_function()
+	 * or woken_wake_function() sees our store to current->state.
 	 */
+	set_current_state(mode); /* A */
 	if (!(wq_entry->flags & WQ_FLAG_WOKEN) && !is_kthread_should_stop())
 		timeout = schedule_timeout(timeout);
 	__set_current_state(TASK_RUNNING);
 
 	/*
-	 * The below implies an smp_mb(), it too pairs with the smp_wmb() from
-	 * woken_wake_function() such that we must either observe the wait
-	 * condition being true _OR_ WQ_FLAG_WOKEN such that we will not miss
-	 * an event.
+	 * The below executes an smp_mb(), which matches with the smp_mb() (C)
+	 * in woken_wake_function() such that either we see the wait condition
+	 * being true or the store to wq_entry->flags in woken_wake_function()
+	 * follows ours in the coherence order.
 	 */
 	smp_store_mb(wq_entry->flags, wq_entry->flags & ~WQ_FLAG_WOKEN); /* B */
 
@@ -430,14 +431,8 @@ EXPORT_SYMBOL(wait_woken);
 
 int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key)
 {
-	/*
-	 * Although this function is called under waitqueue lock, LOCK
-	 * doesn't imply write barrier and the users expects write
-	 * barrier semantics on wakeup functions.  The following
-	 * smp_wmb() is equivalent to smp_wmb() in try_to_wake_up()
-	 * and is paired with smp_store_mb() in wait_woken().
-	 */
-	smp_wmb(); /* C */
+	/* Pairs with the smp_store_mb() in wait_woken(). */
+	smp_mb(); /* C */
 	wq_entry->flags |= WQ_FLAG_WOKEN;
 
 	return default_wake_function(wq_entry, mode, sync, key);
#20 lore raw

PATCH 11/14 locking: Clarify requirements for smp_mb__after_spinlock()

In reply to Paul E. McKenney

From: Andrea Parri <[email protected]>

There are 11 interpretations of the requirements described in the header comment for smp_mb__after_spinlock(): one for each LKMM maintainer, and one currently encoded in the Cat file. Stick to the latter (until a more satisfactory solution is available).

This also reworks some snippets related to the barrier to illustrate the requirements and to link them to the idioms which are relied upon at its call sites.

---
 include/linux/spinlock.h | 53 +++++++++++++++++++++++++++-------------
 kernel/sched/core.c      | 41 ++++++++++++++++---------------
 2 files changed, 57 insertions(+), 37 deletions(-)
include/linux/spinlock.h +36 -17
index 1e8a46435838..d70a06ff2bdd 100644
@@ -114,29 +114,48 @@ do {								\
 #endif /*arch_spin_is_contended*/
 
 /*
- * This barrier must provide two things:
+ * smp_mb__after_spinlock() provides the equivalent of a full memory barrier
+ * between program-order earlier lock acquisitions and program-order later
+ * memory accesses.
  *
- *   - it must guarantee a STORE before the spin_lock() is ordered against a
- *     LOAD after it, see the comments at its two usage sites.
+ * This guarantees that the following two properties hold:
  *
- *   - it must ensure the critical section is RCsc.
+ *   1) Given the snippet:
  *
- * The latter is important for cases where we observe values written by other
- * CPUs in spin-loops, without barriers, while being subject to scheduling.
+ *	  { X = 0;  Y = 0; }
  *
- * CPU0			CPU1			CPU2
+ *	  CPU0				CPU1
  *
- *			for (;;) {
- *			  if (READ_ONCE(X))
- *			    break;
- *			}
- * X=1
- *			<sched-out>
- *						<sched-in>
- *						r = X;
+ *	  WRITE_ONCE(X, 1);		WRITE_ONCE(Y, 1);
+ *	  spin_lock(S);			smp_mb();
+ *	  smp_mb__after_spinlock();	r1 = READ_ONCE(X);
+ *	  r0 = READ_ONCE(Y);
+ *	  spin_unlock(S);
  *
- * without transitivity it could be that CPU1 observes X!=0 breaks the loop,
- * we get migrated and CPU2 sees X==0.
+ *      it is forbidden that CPU0 does not observe CPU1's store to Y (r0 = 0)
+ *      and CPU1 does not observe CPU0's store to X (r1 = 0); see the comments
+ *      preceding the call to smp_mb__after_spinlock() in __schedule() and in
+ *      try_to_wake_up().
+ *
+ *   2) Given the snippet:
+ *
+ *  { X = 0;  Y = 0; }
+ *
+ *  CPU0		CPU1				CPU2
+ *
+ *  spin_lock(S);	spin_lock(S);			r1 = READ_ONCE(Y);
+ *  WRITE_ONCE(X, 1);	smp_mb__after_spinlock();	smp_rmb();
+ *  spin_unlock(S);	r0 = READ_ONCE(X);		r2 = READ_ONCE(X);
+ *			WRITE_ONCE(Y, 1);
+ *			spin_unlock(S);
+ *
+ *      it is forbidden that CPU0's critical section executes before CPU1's
+ *      critical section (r0 = 1), CPU2 observes CPU1's store to Y (r1 = 1)
+ *      and CPU2 does not observe CPU0's store to X (r2 = 0); see the comments
+ *      preceding the calls to smp_rmb() in try_to_wake_up() for similar
+ *      snippets but "projected" onto two CPUs.
+ *
+ * Property (2) upgrades the lock to an RCsc lock.
  *
  * Since most load-store architectures implement ACQUIRE with an smp_mb() after
  * the LL/SC loop, they need no further barriers. Similarly all our TSO
kernel/sched/core.c +21 -20

57 lines not on this page · raw message

Signature · 1 line
2.17.1
#21 lore raw

[tip:locking/core] locking/spinlock, sched/core: Clarify requirements for smp_mb__after_spinlock()

locking/spinlock, sched/core: Clarify requirements for smp_mb__after_spinlock()
Commit-ID:  3d85b2703783636366560c94842affd8608ec9d1
Gitweb:     https://git.kernel.org/tip/3d85b2703783636366560c94842affd8608ec9d1
Author:     Andrea Parri <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:06:02 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:33 +0200

locking/spinlock, sched/core: Clarify requirements for smp_mb__after_spinlock()

There are 11 interpretations of the requirements described in the header comment for smp_mb__after_spinlock(): one for each LKMM maintainer, and one currently encoded in the Cat file. Stick to the latter (until a more satisfactory solution is available).

This also reworks some snippets related to the barrier to illustrate the requirements and to link them to the idioms which are relied upon at its call sites.

---
 include/linux/spinlock.h | 53 ++++++++++++++++++++++++++++++++----------------
 kernel/sched/core.c      | 41 +++++++++++++++++++------------------
 2 files changed, 57 insertions(+), 37 deletions(-)
include/linux/spinlock.h +36 -17
index fd57888d4942..3190997df9ca 100644
@@ -114,29 +114,48 @@ do {								\
 #endif /*arch_spin_is_contended*/
 
 /*
- * This barrier must provide two things:
+ * smp_mb__after_spinlock() provides the equivalent of a full memory barrier
+ * between program-order earlier lock acquisitions and program-order later
+ * memory accesses.
  *
- *   - it must guarantee a STORE before the spin_lock() is ordered against a
- *     LOAD after it, see the comments at its two usage sites.
+ * This guarantees that the following two properties hold:
  *
- *   - it must ensure the critical section is RCsc.
+ *   1) Given the snippet:
  *
- * The latter is important for cases where we observe values written by other
- * CPUs in spin-loops, without barriers, while being subject to scheduling.
+ *	  { X = 0;  Y = 0; }
  *
- * CPU0			CPU1			CPU2
+ *	  CPU0				CPU1
  *
- *			for (;;) {
- *			  if (READ_ONCE(X))
- *			    break;
- *			}
- * X=1
- *			<sched-out>
- *						<sched-in>
- *						r = X;
+ *	  WRITE_ONCE(X, 1);		WRITE_ONCE(Y, 1);
+ *	  spin_lock(S);			smp_mb();
+ *	  smp_mb__after_spinlock();	r1 = READ_ONCE(X);
+ *	  r0 = READ_ONCE(Y);
+ *	  spin_unlock(S);
  *
- * without transitivity it could be that CPU1 observes X!=0 breaks the loop,
- * we get migrated and CPU2 sees X==0.
+ *      it is forbidden that CPU0 does not observe CPU1's store to Y (r0 = 0)
+ *      and CPU1 does not observe CPU0's store to X (r1 = 0); see the comments
+ *      preceding the call to smp_mb__after_spinlock() in __schedule() and in
+ *      try_to_wake_up().
+ *
+ *   2) Given the snippet:
+ *
+ *  { X = 0;  Y = 0; }
+ *
+ *  CPU0		CPU1				CPU2
+ *
+ *  spin_lock(S);	spin_lock(S);			r1 = READ_ONCE(Y);
+ *  WRITE_ONCE(X, 1);	smp_mb__after_spinlock();	smp_rmb();
+ *  spin_unlock(S);	r0 = READ_ONCE(X);		r2 = READ_ONCE(X);
+ *			WRITE_ONCE(Y, 1);
+ *			spin_unlock(S);
+ *
+ *      it is forbidden that CPU0's critical section executes before CPU1's
+ *      critical section (r0 = 1), CPU2 observes CPU1's store to Y (r1 = 1)
+ *      and CPU2 does not observe CPU0's store to X (r2 = 0); see the comments
+ *      preceding the calls to smp_rmb() in try_to_wake_up() for similar
+ *      snippets but "projected" onto two CPUs.
+ *
+ * Property (2) upgrades the lock to an RCsc lock.
  *
  * Since most load-store architectures implement ACQUIRE with an smp_mb() after
  * the LL/SC loop, they need no further barriers. Similarly all our TSO
kernel/sched/core.c +21 -20

57 lines not on this page · raw message

#22 lore raw

PATCH 12/14 doc: Update wake_up() & co. memory-barrier guarantees

In reply to Paul E. McKenney

From: Andrea Parri <[email protected]>

Both the implementation and the users' expectation [1] for the various wakeup primitives have evolved over time, but the documentation has not kept up with these changes: brings it into 2018.

[1] http://lkml.kernel.org/r/[email protected]

[ aparri: Apply feedback from Alan Stern. ]
Cc Alan Stern <[email protected]>
Cc Will Deacon <[email protected]>
Cc Boqun Feng <[email protected]>
Cc Nicholas Piggin <[email protected]>
Cc David Howells <[email protected]>
Cc Jade Alglave <[email protected]>
Cc Luc Maranget <[email protected]>
Cc Akira Yokosawa <[email protected]>
Cc Daniel Lustig <[email protected]>
Cc Jonathan Corbet <[email protected]>
Cc Ingo Molnar <[email protected]>
---
 Documentation/memory-barriers.txt | 43 +++++++++++++++++++------------
 include/linux/sched.h             |  4 +--
 kernel/sched/completion.c         |  8 +++---
 kernel/sched/core.c               | 30 +++++++++------------
 kernel/sched/wait.c               |  8 +++---
 5 files changed, 49 insertions(+), 44 deletions(-)
Documentation/memory-barriers.txt +27 -16
index a02d6bbfc9d0..0d8d7ef131e9 100644
@@ -2179,32 +2179,41 @@ or:
 	event_indicated = 1;
 	wake_up_process(event_daemon);
 
-A write memory barrier is implied by wake_up() and co.  if and only if they
-wake something up.  The barrier occurs before the task state is cleared, and so
-sits between the STORE to indicate the event and the STORE to set TASK_RUNNING:
+A general memory barrier is executed by wake_up() if it wakes something up.
+If it doesn't wake anything up then a memory barrier may or may not be
+executed; you must not rely on it.  The barrier occurs before the task state
+is accessed, in particular, it sits between the STORE to indicate the event
+and the STORE to set TASK_RUNNING:
 
-	CPU 1				CPU 2
+	CPU 1 (Sleeper)			CPU 2 (Waker)
 	===============================	===============================
 	set_current_state();		STORE event_indicated
 	  smp_store_mb();		wake_up();
-	    STORE current->state	  <write barrier>
-	    <general barrier>		  STORE current->state
-	LOAD event_indicated
+	    STORE current->state	  ...
+	    <general barrier>		  <general barrier>
+	LOAD event_indicated		  if ((LOAD task->state) & TASK_NORMAL)
+					    STORE task->state
 
-To repeat, this write memory barrier is present if and only if something
-is actually awakened.  To see this, consider the following sequence of
-events, where X and Y are both initially zero:
+where "task" is the thread being woken up and it equals CPU 1's "current".
+
+To repeat, a general memory barrier is guaranteed to be executed by wake_up()
+if something is actually awakened, but otherwise there is no such guarantee.
+To see this, consider the following sequence of events, where X and Y are both
+initially zero:
 
 	CPU 1				CPU 2
 	===============================	===============================
-	X = 1;				STORE event_indicated
+	X = 1;				Y = 1;
 	smp_mb();			wake_up();
-	Y = 1;				wait_event(wq, Y == 1);
-	wake_up();			  load from Y sees 1, no memory barrier
-					load from X might see 0
+	LOAD Y				LOAD X
+
+If a wakeup does occur, one (at least) of the two loads must see 1.  If, on
+the other hand, a wakeup does not occur, both loads might see 0.
 
-In contrast, if a wakeup does occur, CPU 2's load from X would be guaranteed
-to see 1.
+wake_up_process() always executes a general memory barrier.  The barrier again
+occurs before the task state is accessed.  In particular, if the wake_up() in
+the previous snippet were replaced by a call to wake_up_process() then one of
+the two loads would be guaranteed to see 1.
 
 The available waker functions include:
 
@@ -2224,6 +2233,8 @@ The available waker functions include:
 	wake_up_poll();
 	wake_up_process();
 
+In terms of memory ordering, these functions all provide the same guarantees of
+a wake_up() (or stronger).
 
 [!] Note that the memory barriers implied by the sleeper and the waker do _not_
 order multiple stores before the wake-up with respect to loads of those stored
include/linux/sched.h +2 -2
index 87bf02d93a27..ddfdeb632f74 100644
@@ -167,8 +167,8 @@ struct task_group;
  *   need_sleep = false;
  *   wake_up_state(p, TASK_UNINTERRUPTIBLE);
  *
- * Where wake_up_state() (and all other wakeup primitives) imply enough
- * barriers to order the store of the variable against wakeup.
+ * where wake_up_state() executes a full memory barrier before accessing the
+ * task state.
  *
  * Wakeup will do: if (@state & p->state) p->state = TASK_RUNNING, that is,
  * once it observes the TASK_UNINTERRUPTIBLE store the waking CPU can issue a
kernel/sched/completion.c +4 -4
index e426b0cb9ac6..a1ad5b7d5521 100644
@@ -22,8 +22,8 @@
  *
  * See also complete_all(), wait_for_completion() and related routines.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  */
 void complete(struct completion *x)
 {
@@ -44,8 +44,8 @@ EXPORT_SYMBOL(complete);
  *
  * This will wake up all threads waiting on this particular completion event.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  *
  * Since complete_all() sets the completion of @x permanently to done
  * to allow multiple waiters to finish, a call to reinit_completion()
kernel/sched/core.c +12 -18
index 7db0662360f1..940dfdae41b5 100644
@@ -413,8 +413,8 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task)
 	 * its already queued (either by us or someone else) and will get the
 	 * wakeup due to that.
 	 *
-	 * This cmpxchg() implies a full barrier, which pairs with the write
-	 * barrier implied by the wakeup in wake_up_q().
+	 * This cmpxchg() executes a full barrier, which pairs with the full
+	 * barrier executed by the wakeup in wake_up_q().
 	 */
 	if (cmpxchg(&node->next, NULL, WAKE_Q_TAIL))
 		return;
@@ -442,8 +442,8 @@ void wake_up_q(struct wake_q_head *head)
 		task->wake_q.next = NULL;
 
 		/*
-		 * wake_up_process() implies a wmb() to pair with the queueing
-		 * in wake_q_add() so as not to miss wakeups.
+		 * wake_up_process() executes a full barrier, which pairs with
+		 * the queueing in wake_q_add() so as not to miss wakeups.
 		 */
 		wake_up_process(task);
 		put_task_struct(task);
@@ -1880,8 +1880,7 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
  *     rq(c1)->lock (if not at the same time, then in that order).
  *  C) LOCK of the rq(c1)->lock scheduling in task
  *
- * Transitivity guarantees that B happens after A and C after B.
- * Note: we only require RCpc transitivity.
+ * Release/acquire chaining guarantees that B happens after A and C after B.
  * Note: the CPU doing B need not be c0 or c1
  *
  * Example:
@@ -1943,16 +1942,9 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
  *   UNLOCK rq(0)->lock
  *
  *
- * However; for wakeups there is a second guarantee we must provide, namely we
- * must observe the state that lead to our wakeup. That is, not only must our
- * task observe its own prior state, it must also observe the stores prior to
- * its wakeup.
- *
- * This means that any means of doing remote wakeups must order the CPU doing
- * the wakeup against the CPU the task is going to end up running on. This,
- * however, is already required for the regular Program-Order guarantee above,
- * since the waking CPU is the one issueing the ACQUIRE (smp_cond_load_acquire).
- *
+ * However, for wakeups there is a second guarantee we must provide, namely we
+ * must ensure that CONDITION=1 done by the caller can not be reordered with
+ * accesses to the task state; see try_to_wake_up() and set_current_state().
  */
 
 /**
@@ -1968,6 +1960,9 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
  * Atomic against schedule() which would dequeue a task, also see
  * set_current_state().
  *
+ * This function executes a full memory barrier before accessing the task
+ * state; see set_current_state().
+ *
  * Return: %true if @p->state changes (an actual wakeup was done),
  *	   %false otherwise.
  */
@@ -2142,8 +2137,7 @@ static void try_to_wake_up_local(struct task_struct *p, struct rq_flags *rf)
  *
  * Return: 1 if the process was woken up, 0 if it was already running.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * This function executes a full memory barrier before accessing the task state.
  */
 int wake_up_process(struct task_struct *p)
 {
kernel/sched/wait.c +4 -4
index a7a2aaa3026a..870f97b313e3 100644
@@ -134,8 +134,8 @@ static void __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int
  * @nr_exclusive: how many wake-one or wake-many threads to wake up
  * @key: is directly passed to the wakeup function
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  */
 void __wake_up(struct wait_queue_head *wq_head, unsigned int mode,
 			int nr_exclusive, void *key)
@@ -180,8 +180,8 @@ EXPORT_SYMBOL_GPL(__wake_up_locked_key_bookmark);
  *
  * On UP it can prevent extra preemption.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  */
 void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode,
 			int nr_exclusive, void *key)
Signature · 1 line
2.17.1
#23 lore raw

[tip:locking/core] sched/Documentation: Update wake_up() & co. memory-barrier guarantees

sched/Documentation: Update wake_up() & co. memory-barrier guarantees
Commit-ID:  7696f9910a9a40b8a952f57d3428515fabd2d889
Gitweb:     https://git.kernel.org/tip/7696f9910a9a40b8a952f57d3428515fabd2d889
Author:     Andrea Parri <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:06:03 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:34 +0200

sched/Documentation: Update wake_up() & co. memory-barrier guarantees

Both the implementation and the users' expectation [1] for the various wakeup primitives have evolved over time, but the documentation has not kept up with these changes: brings it into 2018.

[1] http://lkml.kernel.org/r/[email protected]

Also applied feedback from Alan Stern.

---
 Documentation/memory-barriers.txt | 43 ++++++++++++++++++++++++---------------
 include/linux/sched.h             |  4 ++--
 kernel/sched/completion.c         |  8 ++++----
 kernel/sched/core.c               | 30 +++++++++++----------------
 kernel/sched/wait.c               |  8 ++++----
 5 files changed, 49 insertions(+), 44 deletions(-)
Documentation/memory-barriers.txt +27 -16
index a02d6bbfc9d0..0d8d7ef131e9 100644
@@ -2179,32 +2179,41 @@ or:
 	event_indicated = 1;
 	wake_up_process(event_daemon);
 
-A write memory barrier is implied by wake_up() and co.  if and only if they
-wake something up.  The barrier occurs before the task state is cleared, and so
-sits between the STORE to indicate the event and the STORE to set TASK_RUNNING:
+A general memory barrier is executed by wake_up() if it wakes something up.
+If it doesn't wake anything up then a memory barrier may or may not be
+executed; you must not rely on it.  The barrier occurs before the task state
+is accessed, in particular, it sits between the STORE to indicate the event
+and the STORE to set TASK_RUNNING:
 
-	CPU 1				CPU 2
+	CPU 1 (Sleeper)			CPU 2 (Waker)
 	===============================	===============================
 	set_current_state();		STORE event_indicated
 	  smp_store_mb();		wake_up();
-	    STORE current->state	  <write barrier>
-	    <general barrier>		  STORE current->state
-	LOAD event_indicated
+	    STORE current->state	  ...
+	    <general barrier>		  <general barrier>
+	LOAD event_indicated		  if ((LOAD task->state) & TASK_NORMAL)
+					    STORE task->state
 
-To repeat, this write memory barrier is present if and only if something
-is actually awakened.  To see this, consider the following sequence of
-events, where X and Y are both initially zero:
+where "task" is the thread being woken up and it equals CPU 1's "current".
+
+To repeat, a general memory barrier is guaranteed to be executed by wake_up()
+if something is actually awakened, but otherwise there is no such guarantee.
+To see this, consider the following sequence of events, where X and Y are both
+initially zero:
 
 	CPU 1				CPU 2
 	===============================	===============================
-	X = 1;				STORE event_indicated
+	X = 1;				Y = 1;
 	smp_mb();			wake_up();
-	Y = 1;				wait_event(wq, Y == 1);
-	wake_up();			  load from Y sees 1, no memory barrier
-					load from X might see 0
+	LOAD Y				LOAD X
+
+If a wakeup does occur, one (at least) of the two loads must see 1.  If, on
+the other hand, a wakeup does not occur, both loads might see 0.
 
-In contrast, if a wakeup does occur, CPU 2's load from X would be guaranteed
-to see 1.
+wake_up_process() always executes a general memory barrier.  The barrier again
+occurs before the task state is accessed.  In particular, if the wake_up() in
+the previous snippet were replaced by a call to wake_up_process() then one of
+the two loads would be guaranteed to see 1.
 
 The available waker functions include:
 
@@ -2224,6 +2233,8 @@ The available waker functions include:
 	wake_up_poll();
 	wake_up_process();
 
+In terms of memory ordering, these functions all provide the same guarantees of
+a wake_up() (or stronger).
 
 [!] Note that the memory barriers implied by the sleeper and the waker do _not_
 order multiple stores before the wake-up with respect to loads of those stored
include/linux/sched.h +2 -2
index 43731fe51c97..05cd419f962d 100644
@@ -167,8 +167,8 @@ struct task_group;
  *   need_sleep = false;
  *   wake_up_state(p, TASK_UNINTERRUPTIBLE);
  *
- * Where wake_up_state() (and all other wakeup primitives) imply enough
- * barriers to order the store of the variable against wakeup.
+ * where wake_up_state() executes a full memory barrier before accessing the
+ * task state.
  *
  * Wakeup will do: if (@state & p->state) p->state = TASK_RUNNING, that is,
  * once it observes the TASK_UNINTERRUPTIBLE store the waking CPU can issue a
kernel/sched/completion.c +4 -4
index e426b0cb9ac6..a1ad5b7d5521 100644
@@ -22,8 +22,8 @@
  *
  * See also complete_all(), wait_for_completion() and related routines.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  */
 void complete(struct completion *x)
 {
@@ -44,8 +44,8 @@ EXPORT_SYMBOL(complete);
  *
  * This will wake up all threads waiting on this particular completion event.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  *
  * Since complete_all() sets the completion of @x permanently to done
  * to allow multiple waiters to finish, a call to reinit_completion()
kernel/sched/core.c +12 -18
index 0c5ec2abdf93..a0065c84e73f 100644
@@ -412,8 +412,8 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task)
 	 * its already queued (either by us or someone else) and will get the
 	 * wakeup due to that.
 	 *
-	 * This cmpxchg() implies a full barrier, which pairs with the write
-	 * barrier implied by the wakeup in wake_up_q().
+	 * This cmpxchg() executes a full barrier, which pairs with the full
+	 * barrier executed by the wakeup in wake_up_q().
 	 */
 	if (cmpxchg(&node->next, NULL, WAKE_Q_TAIL))
 		return;
@@ -441,8 +441,8 @@ void wake_up_q(struct wake_q_head *head)
 		task->wake_q.next = NULL;
 
 		/*
-		 * wake_up_process() implies a wmb() to pair with the queueing
-		 * in wake_q_add() so as not to miss wakeups.
+		 * wake_up_process() executes a full barrier, which pairs with
+		 * the queueing in wake_q_add() so as not to miss wakeups.
 		 */
 		wake_up_process(task);
 		put_task_struct(task);
@@ -1879,8 +1879,7 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
  *     rq(c1)->lock (if not at the same time, then in that order).
  *  C) LOCK of the rq(c1)->lock scheduling in task
  *
- * Transitivity guarantees that B happens after A and C after B.
- * Note: we only require RCpc transitivity.
+ * Release/acquire chaining guarantees that B happens after A and C after B.
  * Note: the CPU doing B need not be c0 or c1
  *
  * Example:
@@ -1942,16 +1941,9 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
  *   UNLOCK rq(0)->lock
  *
  *
- * However; for wakeups there is a second guarantee we must provide, namely we
- * must observe the state that lead to our wakeup. That is, not only must our
- * task observe its own prior state, it must also observe the stores prior to
- * its wakeup.
- *
- * This means that any means of doing remote wakeups must order the CPU doing
- * the wakeup against the CPU the task is going to end up running on. This,
- * however, is already required for the regular Program-Order guarantee above,
- * since the waking CPU is the one issueing the ACQUIRE (smp_cond_load_acquire).
- *
+ * However, for wakeups there is a second guarantee we must provide, namely we
+ * must ensure that CONDITION=1 done by the caller can not be reordered with
+ * accesses to the task state; see try_to_wake_up() and set_current_state().
  */
 
 /**
@@ -1967,6 +1959,9 @@ static void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
  * Atomic against schedule() which would dequeue a task, also see
  * set_current_state().
  *
+ * This function executes a full memory barrier before accessing the task
+ * state; see set_current_state().
+ *
  * Return: %true if @p->state changes (an actual wakeup was done),
  *	   %false otherwise.
  */
@@ -2141,8 +2136,7 @@ out:
  *
  * Return: 1 if the process was woken up, 0 if it was already running.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * This function executes a full memory barrier before accessing the task state.
  */
 int wake_up_process(struct task_struct *p)
 {
kernel/sched/wait.c +4 -4
index a7a2aaa3026a..870f97b313e3 100644
@@ -134,8 +134,8 @@ static void __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int
  * @nr_exclusive: how many wake-one or wake-many threads to wake up
  * @key: is directly passed to the wakeup function
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  */
 void __wake_up(struct wait_queue_head *wq_head, unsigned int mode,
 			int nr_exclusive, void *key)
@@ -180,8 +180,8 @@ EXPORT_SYMBOL_GPL(__wake_up_locked_key_bookmark);
  *
  * On UP it can prevent extra preemption.
  *
- * It may be assumed that this function implies a write memory barrier before
- * changing the task state if and only if any tasks are woken up.
+ * If this function wakes up a task, it executes a full memory barrier before
+ * accessing the task state.
  */
 void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode,
 			int nr_exclusive, void *key)
#24 lore raw

PATCH 13/14 memory-model/Documentation: Fix typo, smb->smp

In reply to Paul E. McKenney

From: Yauheni Kaliuta <[email protected]>

The tools/memory-model/Documentation/explanation.txt file says "For each other CPU C', smb_wmb() forces all po-earlier stores" This commit therefore replaces the "smb_wmb()" with "smp_wmb()".

---
 tools/memory-model/Documentation/explanation.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/memory-model/Documentation/explanation.txt +1 -1
index 1b09f3175a1f..0cbd1ef8f86d 100644
@@ -804,7 +804,7 @@ type of fence:
 Second, some types of fence affect the way the memory subsystem
 propagates stores.  When a fence instruction is executed on CPU C:
 
-	For each other CPU C', smb_wmb() forces all po-earlier stores
+	For each other CPU C', smp_wmb() forces all po-earlier stores
 	on C to propagate to C' before any po-later stores do.
 
 	For each other CPU C', any store which propagates to C before
Signature · 1 line
2.17.1
#25 lore raw

[tip:locking/core] tools/memory-model/Documentation: Fix typo, smb->smp

tools/memory-model/Documentation: Fix typo, smb->smp
Commit-ID:  0fcff1715bec7593a0ba86f3fef46cd89af37a8b
Gitweb:     https://git.kernel.org/tip/0fcff1715bec7593a0ba86f3fef46cd89af37a8b
Author:     Yauheni Kaliuta <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:06:04 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:35 +0200

tools/memory-model/Documentation: Fix typo, smb->smp

The tools/memory-model/Documentation/explanation.txt file says "For each other CPU C', smb_wmb() forces all po-earlier stores" This commit therefore replaces the "smb_wmb()" with "smp_wmb()".

---
 tools/memory-model/Documentation/explanation.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/memory-model/Documentation/explanation.txt +1 -1
index 1b09f3175a1f..0cbd1ef8f86d 100644
@@ -804,7 +804,7 @@ type of fence:
 Second, some types of fence affect the way the memory subsystem
 propagates stores.  When a fence instruction is executed on CPU C:
 
-	For each other CPU C', smb_wmb() forces all po-earlier stores
+	For each other CPU C', smp_wmb() forces all po-earlier stores
 	on C to propagate to C' before any po-later stores do.
 
 	For each other CPU C', any store which propagates to C before
#26 lore raw

PATCH 14/14 tools/memory-model: Rename litmus tests to comply to norm7

In reply to Paul E. McKenney

From: Andrea Parri <[email protected]>

norm7 produces the 'normalized' name of a litmus test, when the test can be generated from a single cycle that passes through each process exactly once. The commit renames such tests in order to comply to the naming scheme implemented by this tool.

Cc Will Deacon <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Boqun Feng <[email protected]>
Cc Nicholas Piggin <[email protected]>
Cc David Howells <[email protected]>
Cc Jade Alglave <[email protected]>
Cc Luc Maranget <[email protected]>
Cc "Paul E. McKenney" <[email protected]>
Cc Akira Yokosawa <[email protected]>
---
 tools/memory-model/Documentation/recipes.txt  |  8 ++++----
 tools/memory-model/README                     | 20 +++++++++----------
 ... => IRIW+fencembonceonces+OnceOnce.litmus} |  2 +-
 ...=> LB+fencembonceonce+ctrlonceonce.litmus} |  2 +-
 ...+fencewmbonceonce+fencermbonceonce.litmus} |  2 +-
 ...onces.litmus => R+fencembonceonces.litmus} |  2 +-
 tools/memory-model/litmus-tests/README        | 16 +++++++--------
 ...> S+fencewmbonceonce+poacquireonce.litmus} |  2 +-
 ...nces.litmus => SB+fencembonceonces.litmus} |  2 +-
 ...ooncerelease+fencermbonceonce+Once.litmus} |  2 +-
 ...e+poacquirerelease+fencembonceonce.litmus} |  2 +-
 11 files changed, 30 insertions(+), 30 deletions(-)
 rename tools/memory-model/litmus-tests/{IRIW+mbonceonces+OnceOnce.litmus => IRIW+fencembonceonces+OnceOnce.litmus} (95%)
 rename tools/memory-model/litmus-tests/{LB+ctrlonceonce+mbonceonce.litmus => LB+fencembonceonce+ctrlonceonce.litmus} (95%)
 rename tools/memory-model/litmus-tests/{MP+wmbonceonce+rmbonceonce.litmus => MP+fencewmbonceonce+fencermbonceonce.litmus} (91%)
 rename tools/memory-model/litmus-tests/{R+mbonceonces.litmus => R+fencembonceonces.litmus} (95%)
 rename tools/memory-model/litmus-tests/{S+wmbonceonce+poacquireonce.litmus => S+fencewmbonceonce+poacquireonce.litmus} (90%)
 rename tools/memory-model/litmus-tests/{SB+mbonceonces.litmus => SB+fencembonceonces.litmus} (95%)
 rename tools/memory-model/litmus-tests/{WRC+pooncerelease+rmbonceonce+Once.litmus => WRC+pooncerelease+fencermbonceonce+Once.litmus} (93%)
 rename tools/memory-model/litmus-tests/{Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus => Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus} (94%)
tools/memory-model/Documentation/recipes.txt +4 -4
index 1fea8ef2b184..af72700cc20a 100644
@@ -126,7 +126,7 @@ However, it is not necessarily the case that accesses ordered by
 locking will be seen as ordered by CPUs not holding that lock.
 Consider this example:
 
-	/* See Z6.0+pooncelock+pooncelock+pombonce.litmus. */
+	/* See Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus. */
 	void CPU0(void)
 	{
 		spin_lock(&mylock);
@@ -292,7 +292,7 @@ and to use smp_load_acquire() instead of smp_rmb().  However, the older
 smp_wmb() and smp_rmb() APIs are still heavily used, so it is important
 to understand their use cases.  The general approach is shown below:
 
-	/* See MP+wmbonceonce+rmbonceonce.litmus. */
+	/* See MP+fencewmbonceonce+fencermbonceonce.litmus. */
 	void CPU0(void)
 	{
 		WRITE_ONCE(x, 1);
@@ -360,7 +360,7 @@ can be seen in the LB+poonceonces.litmus litmus test.
 One way of avoiding the counter-intuitive outcome is through the use of a
 control dependency paired with a full memory barrier:
 
-	/* See LB+ctrlonceonce+mbonceonce.litmus. */
+	/* See LB+fencembonceonce+ctrlonceonce.litmus. */
 	void CPU0(void)
 	{
 		r0 = READ_ONCE(x);
@@ -476,7 +476,7 @@ that one CPU first stores to one variable and then loads from a second,
 while another CPU stores to the second variable and then loads from the
 first.  Preserving order requires nothing less than full barriers:
 
-	/* See SB+mbonceonces.litmus. */
+	/* See SB+fencembonceonces.litmus. */
 	void CPU0(void)
 	{
 		WRITE_ONCE(x, 1);
tools/memory-model/README +10 -10
index 734f7feaa5dc..ee987ce20aae 100644
@@ -35,13 +35,13 @@ BASIC USAGE: HERD7
 The memory model is used, in conjunction with "herd7", to exhaustively
 explore the state space of small litmus tests.
 
-For example, to run SB+mbonceonces.litmus against the memory model:
+For example, to run SB+fencembonceonces.litmus against the memory model:
 
-  $ herd7 -conf linux-kernel.cfg litmus-tests/SB+mbonceonces.litmus
+  $ herd7 -conf linux-kernel.cfg litmus-tests/SB+fencembonceonces.litmus
 
 Here is the corresponding output:
 
-  Test SB+mbonceonces Allowed
+  Test SB+fencembonceonces Allowed
   States 3
   0:r0=0; 1:r0=1;
   0:r0=1; 1:r0=0;
@@ -50,8 +50,8 @@ Here is the corresponding output:
   Witnesses
   Positive: 0 Negative: 3
   Condition exists (0:r0=0 /\ 1:r0=0)
-  Observation SB+mbonceonces Never 0 3
-  Time SB+mbonceonces 0.01
+  Observation SB+fencembonceonces Never 0 3
+  Time SB+fencembonceonces 0.01
   Hash=d66d99523e2cac6b06e66f4c995ebb48
 
 The "Positive: 0 Negative: 3" and the "Never 0 3" each indicate that
@@ -67,16 +67,16 @@ BASIC USAGE: KLITMUS7
 The "klitmus7" tool converts a litmus test into a Linux kernel module,
 which may then be loaded and run.
 
-For example, to run SB+mbonceonces.litmus against hardware:
+For example, to run SB+fencembonceonces.litmus against hardware:
 
   $ mkdir mymodules
-  $ klitmus7 -o mymodules litmus-tests/SB+mbonceonces.litmus
+  $ klitmus7 -o mymodules litmus-tests/SB+fencembonceonces.litmus
   $ cd mymodules ; make
   $ sudo sh run.sh
 
 The corresponding output includes:
 
-  Test SB+mbonceonces Allowed
+  Test SB+fencembonceonces Allowed
   Histogram (3 states)
   644580  :>0:r0=1; 1:r0=0;
   644328  :>0:r0=0; 1:r0=1;
@@ -86,8 +86,8 @@ The corresponding output includes:
   Positive: 0, Negative: 2000000
   Condition exists (0:r0=0 /\ 1:r0=0) is NOT validated
   Hash=d66d99523e2cac6b06e66f4c995ebb48
-  Observation SB+mbonceonces Never 0 2000000
-  Time SB+mbonceonces 0.16
+  Observation SB+fencembonceonces Never 0 2000000
+  Time SB+fencembonceonces 0.16
 
 The "Positive: 0 Negative: 2000000" and the "Never 0 2000000" indicate
 that during two million trials, the state specified in this litmus
tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus renamed from tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus
rename to tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus
index 98a3716efa37..e729d2776e89 100644
@@ -1,4 +1,4 @@
-C IRIW+mbonceonces+OnceOnce
+C IRIW+fencembonceonces+OnceOnce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus renamed from tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus
rename to tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus
index de6708229dd1..4727f5aaf03b 100644
@@ -1,4 +1,4 @@
-C LB+ctrlonceonce+mbonceonce
+C LB+fencembonceonce+ctrlonceonce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus renamed from tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus +1 -1
similarity index 91%
rename from tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus
rename to tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus
index c078f38ff27a..a273da9faa6d 100644
@@ -1,4 +1,4 @@
-C MP+wmbonceonce+rmbonceonce
+C MP+fencewmbonceonce+fencermbonceonce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/R+fencembonceonces.litmus renamed from tools/memory-model/litmus-tests/R+mbonceonces.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/R+mbonceonces.litmus
rename to tools/memory-model/litmus-tests/R+fencembonceonces.litmus
index a0e884ad2132..222a0b850b4a 100644
@@ -1,4 +1,4 @@
-C R+mbonceonces
+C R+fencembonceonces
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/README +8 -8
index 00140aaf58b7..4581ec2d3c57 100644
@@ -18,7 +18,7 @@ CoWW+poonceonce.litmus
 	Test of write-write coherence, that is, whether or not two
 	successive writes to the same variable are ordered.
 
-IRIW+mbonceonces+OnceOnce.litmus
+IRIW+fencembonceonces+OnceOnce.litmus
 	Test of independent reads from independent writes with smp_mb()
 	between each pairs of reads.  In other words, is smp_mb()
 	sufficient to cause two different reading processes to agree on
@@ -47,7 +47,7 @@ ISA2+pooncerelease+poacquirerelease+poacquireonce.litmus
 	Can a release-acquire chain order a prior store against
 	a later load?
 
-LB+ctrlonceonce+mbonceonce.litmus
+LB+fencembonceonce+ctrlonceonce.litmus
 	Does a control dependency and an smp_mb() suffice for the
 	load-buffering litmus test, where each process reads from one
 	of two variables then writes to the other?
@@ -88,14 +88,14 @@ MP+porevlocks.litmus
 	As below, but with the first access of the writer process
 	and the second access of reader process protected by a lock.
 
-MP+wmbonceonce+rmbonceonce.litmus
+MP+fencewmbonceonce+fencermbonceonce.litmus
 	Does a smp_wmb() (between the stores) and an smp_rmb() (between
 	the loads) suffice for the message-passing litmus test, where one
 	process writes data and then a flag, and the other process reads
 	the flag and then the data.  (This is similar to the ISA2 tests,
 	but with two processes instead of three.)
 
-R+mbonceonces.litmus
+R+fencembonceonces.litmus
 	This is the fully ordered (via smp_mb()) version of one of
 	the classic counterintuitive litmus tests that illustrates the
 	effects of store propagation delays.
@@ -103,7 +103,7 @@ R+mbonceonces.litmus
 R+poonceonces.litmus
 	As above, but without the smp_mb() invocations.
 
-SB+mbonceonces.litmus
+SB+fencembonceonces.litmus
 	This is the fully ordered (again, via smp_mb() version of store
 	buffering, which forms the core of Dekker's mutual-exclusion
 	algorithm.
@@ -123,12 +123,12 @@ SB+rfionceonce-poonceonces.litmus
 S+poonceonces.litmus
 	As below, but without the smp_wmb() and acquire load.
 
-S+wmbonceonce+poacquireonce.litmus
+S+fencewmbonceonce+poacquireonce.litmus
 	Can a smp_wmb(), instead of a release, and an acquire order
 	a prior store against a subsequent store?
 
 WRC+poonceonces+Once.litmus
-WRC+pooncerelease+rmbonceonce+Once.litmus
+WRC+pooncerelease+fencermbonceonce+Once.litmus
 	These two are members of an extension of the MP litmus-test
 	class in which the first write is moved to a separate process.
 	The second is forbidden because smp_store_release() is
@@ -143,7 +143,7 @@ Z6.0+pooncelock+poonceLock+pombonce.litmus
 	As above, but with smp_mb__after_spinlock() immediately
 	following the spin_lock().
 
-Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus
+Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
 	Is the ordering provided by a release-acquire chain sufficient
 	to make ordering apparent to accesses by a process that does
 	not participate in that release-acquire chain?
tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus renamed from tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus +1 -1
similarity index 90%
rename from tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus
rename to tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus
index c53350205d28..18479823cd6c 100644
@@ -1,4 +1,4 @@
-C S+wmbonceonce+poacquireonce
+C S+fencewmbonceonce+poacquireonce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/SB+fencembonceonces.litmus renamed from tools/memory-model/litmus-tests/SB+mbonceonces.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/SB+mbonceonces.litmus
rename to tools/memory-model/litmus-tests/SB+fencembonceonces.litmus
index 74b874ffa8da..ed5fff18d223 100644
@@ -1,4 +1,4 @@
-C SB+mbonceonces
+C SB+fencembonceonces
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus renamed from tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus +1 -1
similarity index 93%
rename from tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus
rename to tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus
index ad3448b941e6..e9947250d7de 100644
@@ -1,4 +1,4 @@
-C WRC+pooncerelease+rmbonceonce+Once
+C WRC+pooncerelease+fencermbonceonce+Once
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus renamed from tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus +1 -1
similarity index 94%
rename from tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus
rename to tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
index a20fc3fafb53..88e70b87a683 100644
@@ -1,4 +1,4 @@
-C Z6.0+pooncerelease+poacquirerelease+mbonceonce
+C Z6.0+pooncerelease+poacquirerelease+fencembonceonce
 
 (*
  * Result: Sometimes
Signature · 1 line
2.17.1
#27 lore raw

[tip:locking/core] tools/memory-model: Rename litmus tests to comply to norm7

tools/memory-model: Rename litmus tests to comply to norm7
Commit-ID:  71b7ff5ebc9b1d5aa95eb48d6388234f1304fd19
Gitweb:     https://git.kernel.org/tip/71b7ff5ebc9b1d5aa95eb48d6388234f1304fd19
Author:     Andrea Parri <[email protected]>
AuthorDate: Mon, 16 Jul 2018 11:06:05 -0700
Committer:  Ingo Molnar <[email protected]>
CommitDate: Tue, 17 Jul 2018 09:30:36 +0200

tools/memory-model: Rename litmus tests to comply to norm7

norm7 produces the 'normalized' name of a litmus test, when the test can be generated from a single cycle that passes through each process exactly once. The commit renames such tests in order to comply to the naming scheme implemented by this tool.

---
 tools/memory-model/Documentation/recipes.txt         |  8 ++++----
 tools/memory-model/README                            | 20 ++++++++++----------
 ....litmus => IRIW+fencembonceonces+OnceOnce.litmus} |  2 +-
 ...litmus => LB+fencembonceonce+ctrlonceonce.litmus} |  2 +-
 ...s => MP+fencewmbonceonce+fencermbonceonce.litmus} |  2 +-
 ...+mbonceonces.litmus => R+fencembonceonces.litmus} |  2 +-
 tools/memory-model/litmus-tests/README               | 16 ++++++++--------
 ...itmus => S+fencewmbonceonce+poacquireonce.litmus} |  2 +-
 ...mbonceonces.litmus => SB+fencembonceonces.litmus} |  2 +-
 ...> WRC+pooncerelease+fencermbonceonce+Once.litmus} |  2 +-
 ...erelease+poacquirerelease+fencembonceonce.litmus} |  2 +-
 11 files changed, 30 insertions(+), 30 deletions(-)
tools/memory-model/Documentation/recipes.txt +4 -4
index 1fea8ef2b184..af72700cc20a 100644
@@ -126,7 +126,7 @@ However, it is not necessarily the case that accesses ordered by
 locking will be seen as ordered by CPUs not holding that lock.
 Consider this example:
 
-	/* See Z6.0+pooncelock+pooncelock+pombonce.litmus. */
+	/* See Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus. */
 	void CPU0(void)
 	{
 		spin_lock(&mylock);
@@ -292,7 +292,7 @@ and to use smp_load_acquire() instead of smp_rmb().  However, the older
 smp_wmb() and smp_rmb() APIs are still heavily used, so it is important
 to understand their use cases.  The general approach is shown below:
 
-	/* See MP+wmbonceonce+rmbonceonce.litmus. */
+	/* See MP+fencewmbonceonce+fencermbonceonce.litmus. */
 	void CPU0(void)
 	{
 		WRITE_ONCE(x, 1);
@@ -360,7 +360,7 @@ can be seen in the LB+poonceonces.litmus litmus test.
 One way of avoiding the counter-intuitive outcome is through the use of a
 control dependency paired with a full memory barrier:
 
-	/* See LB+ctrlonceonce+mbonceonce.litmus. */
+	/* See LB+fencembonceonce+ctrlonceonce.litmus. */
 	void CPU0(void)
 	{
 		r0 = READ_ONCE(x);
@@ -476,7 +476,7 @@ that one CPU first stores to one variable and then loads from a second,
 while another CPU stores to the second variable and then loads from the
 first.  Preserving order requires nothing less than full barriers:
 
-	/* See SB+mbonceonces.litmus. */
+	/* See SB+fencembonceonces.litmus. */
 	void CPU0(void)
 	{
 		WRITE_ONCE(x, 1);
tools/memory-model/README +10 -10
index 734f7feaa5dc..ee987ce20aae 100644
@@ -35,13 +35,13 @@ BASIC USAGE: HERD7
 The memory model is used, in conjunction with "herd7", to exhaustively
 explore the state space of small litmus tests.
 
-For example, to run SB+mbonceonces.litmus against the memory model:
+For example, to run SB+fencembonceonces.litmus against the memory model:
 
-  $ herd7 -conf linux-kernel.cfg litmus-tests/SB+mbonceonces.litmus
+  $ herd7 -conf linux-kernel.cfg litmus-tests/SB+fencembonceonces.litmus
 
 Here is the corresponding output:
 
-  Test SB+mbonceonces Allowed
+  Test SB+fencembonceonces Allowed
   States 3
   0:r0=0; 1:r0=1;
   0:r0=1; 1:r0=0;
@@ -50,8 +50,8 @@ Here is the corresponding output:
   Witnesses
   Positive: 0 Negative: 3
   Condition exists (0:r0=0 /\ 1:r0=0)
-  Observation SB+mbonceonces Never 0 3
-  Time SB+mbonceonces 0.01
+  Observation SB+fencembonceonces Never 0 3
+  Time SB+fencembonceonces 0.01
   Hash=d66d99523e2cac6b06e66f4c995ebb48
 
 The "Positive: 0 Negative: 3" and the "Never 0 3" each indicate that
@@ -67,16 +67,16 @@ BASIC USAGE: KLITMUS7
 The "klitmus7" tool converts a litmus test into a Linux kernel module,
 which may then be loaded and run.
 
-For example, to run SB+mbonceonces.litmus against hardware:
+For example, to run SB+fencembonceonces.litmus against hardware:
 
   $ mkdir mymodules
-  $ klitmus7 -o mymodules litmus-tests/SB+mbonceonces.litmus
+  $ klitmus7 -o mymodules litmus-tests/SB+fencembonceonces.litmus
   $ cd mymodules ; make
   $ sudo sh run.sh
 
 The corresponding output includes:
 
-  Test SB+mbonceonces Allowed
+  Test SB+fencembonceonces Allowed
   Histogram (3 states)
   644580  :>0:r0=1; 1:r0=0;
   644328  :>0:r0=0; 1:r0=1;
@@ -86,8 +86,8 @@ The corresponding output includes:
   Positive: 0, Negative: 2000000
   Condition exists (0:r0=0 /\ 1:r0=0) is NOT validated
   Hash=d66d99523e2cac6b06e66f4c995ebb48
-  Observation SB+mbonceonces Never 0 2000000
-  Time SB+mbonceonces 0.16
+  Observation SB+fencembonceonces Never 0 2000000
+  Time SB+fencembonceonces 0.16
 
 The "Positive: 0 Negative: 2000000" and the "Never 0 2000000" indicate
 that during two million trials, the state specified in this litmus
tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus renamed from tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus
rename to tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus
index 98a3716efa37..e729d2776e89 100644
@@ -1,4 +1,4 @@
-C IRIW+mbonceonces+OnceOnce
+C IRIW+fencembonceonces+OnceOnce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus renamed from tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus
rename to tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus
index de6708229dd1..4727f5aaf03b 100644
@@ -1,4 +1,4 @@
-C LB+ctrlonceonce+mbonceonce
+C LB+fencembonceonce+ctrlonceonce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus renamed from tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus +1 -1
similarity index 91%
rename from tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus
rename to tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus
index c078f38ff27a..a273da9faa6d 100644
@@ -1,4 +1,4 @@
-C MP+wmbonceonce+rmbonceonce
+C MP+fencewmbonceonce+fencermbonceonce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/R+fencembonceonces.litmus renamed from tools/memory-model/litmus-tests/R+mbonceonces.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/R+mbonceonces.litmus
rename to tools/memory-model/litmus-tests/R+fencembonceonces.litmus
index a0e884ad2132..222a0b850b4a 100644
@@ -1,4 +1,4 @@
-C R+mbonceonces
+C R+fencembonceonces
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/README +8 -8
index 00140aaf58b7..4581ec2d3c57 100644
@@ -18,7 +18,7 @@ CoWW+poonceonce.litmus
 	Test of write-write coherence, that is, whether or not two
 	successive writes to the same variable are ordered.
 
-IRIW+mbonceonces+OnceOnce.litmus
+IRIW+fencembonceonces+OnceOnce.litmus
 	Test of independent reads from independent writes with smp_mb()
 	between each pairs of reads.  In other words, is smp_mb()
 	sufficient to cause two different reading processes to agree on
@@ -47,7 +47,7 @@ ISA2+pooncerelease+poacquirerelease+poacquireonce.litmus
 	Can a release-acquire chain order a prior store against
 	a later load?
 
-LB+ctrlonceonce+mbonceonce.litmus
+LB+fencembonceonce+ctrlonceonce.litmus
 	Does a control dependency and an smp_mb() suffice for the
 	load-buffering litmus test, where each process reads from one
 	of two variables then writes to the other?
@@ -88,14 +88,14 @@ MP+porevlocks.litmus
 	As below, but with the first access of the writer process
 	and the second access of reader process protected by a lock.
 
-MP+wmbonceonce+rmbonceonce.litmus
+MP+fencewmbonceonce+fencermbonceonce.litmus
 	Does a smp_wmb() (between the stores) and an smp_rmb() (between
 	the loads) suffice for the message-passing litmus test, where one
 	process writes data and then a flag, and the other process reads
 	the flag and then the data.  (This is similar to the ISA2 tests,
 	but with two processes instead of three.)
 
-R+mbonceonces.litmus
+R+fencembonceonces.litmus
 	This is the fully ordered (via smp_mb()) version of one of
 	the classic counterintuitive litmus tests that illustrates the
 	effects of store propagation delays.
@@ -103,7 +103,7 @@ R+mbonceonces.litmus
 R+poonceonces.litmus
 	As above, but without the smp_mb() invocations.
 
-SB+mbonceonces.litmus
+SB+fencembonceonces.litmus
 	This is the fully ordered (again, via smp_mb() version of store
 	buffering, which forms the core of Dekker's mutual-exclusion
 	algorithm.
@@ -123,12 +123,12 @@ SB+rfionceonce-poonceonces.litmus
 S+poonceonces.litmus
 	As below, but without the smp_wmb() and acquire load.
 
-S+wmbonceonce+poacquireonce.litmus
+S+fencewmbonceonce+poacquireonce.litmus
 	Can a smp_wmb(), instead of a release, and an acquire order
 	a prior store against a subsequent store?
 
 WRC+poonceonces+Once.litmus
-WRC+pooncerelease+rmbonceonce+Once.litmus
+WRC+pooncerelease+fencermbonceonce+Once.litmus
 	These two are members of an extension of the MP litmus-test
 	class in which the first write is moved to a separate process.
 	The second is forbidden because smp_store_release() is
@@ -143,7 +143,7 @@ Z6.0+pooncelock+poonceLock+pombonce.litmus
 	As above, but with smp_mb__after_spinlock() immediately
 	following the spin_lock().
 
-Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus
+Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
 	Is the ordering provided by a release-acquire chain sufficient
 	to make ordering apparent to accesses by a process that does
 	not participate in that release-acquire chain?
tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus renamed from tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus +1 -1
similarity index 90%
rename from tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus
rename to tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus
index c53350205d28..18479823cd6c 100644
@@ -1,4 +1,4 @@
-C S+wmbonceonce+poacquireonce
+C S+fencewmbonceonce+poacquireonce
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/SB+fencembonceonces.litmus renamed from tools/memory-model/litmus-tests/SB+mbonceonces.litmus +1 -1
similarity index 95%
rename from tools/memory-model/litmus-tests/SB+mbonceonces.litmus
rename to tools/memory-model/litmus-tests/SB+fencembonceonces.litmus
index 74b874ffa8da..ed5fff18d223 100644
@@ -1,4 +1,4 @@
-C SB+mbonceonces
+C SB+fencembonceonces
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus renamed from tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus +1 -1
similarity index 93%
rename from tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus
rename to tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus
index ad3448b941e6..e9947250d7de 100644
@@ -1,4 +1,4 @@
-C WRC+pooncerelease+rmbonceonce+Once
+C WRC+pooncerelease+fencermbonceonce+Once
 
 (*
  * Result: Never
tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus renamed from tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus +1 -1
similarity index 94%
rename from tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus
rename to tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus
index a20fc3fafb53..88e70b87a683 100644
@@ -1,4 +1,4 @@
-C Z6.0+pooncerelease+poacquirerelease+mbonceonce
+C Z6.0+pooncerelease+poacquirerelease+fencembonceonce
 
 (*
  * Result: Sometimes