Documentation/litmus-tests: Demonstrate unordered failing cmpxchg
authorPaul E. McKenney <paulmck@kernel.org>
Thu, 1 Feb 2024 19:17:54 +0000 (11:17 -0800)
committerPaul E. McKenney <paulmck@kernel.org>
Mon, 6 May 2024 21:28:54 +0000 (14:28 -0700)
This commit adds four litmus tests showing that a failing cmpxchg()
operation is unordered unless followed by an smp_mb__after_atomic()
operation.

Suggested-by: Frederic Weisbecker <frederic@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Will Deacon <will@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Jade Alglave <j.alglave@ucl.ac.uk>
Cc: Luc Maranget <luc.maranget@inria.fr>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Akira Yokosawa <akiyks@gmail.com>
Cc: Daniel Lustig <dlustig@nvidia.com>
Cc: Joel Fernandes <joel@joelfernandes.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: <linux-arch@vger.kernel.org>
Cc: <linux-doc@vger.kernel.org>
Acked-by: Andrea Parri <parri.andrea@gmail.com>
Documentation/litmus-tests/README
Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-1.litmus [new file with mode: 0644]
Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-2.litmus [new file with mode: 0644]
Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-1.litmus [new file with mode: 0644]
Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-2.litmus [new file with mode: 0644]

index 26ca56df02125c4a59eadfa8d54a49363f86cffa..6c666f3422ea3a3cf3b3f214c950ea2163d1a8fa 100644 (file)
@@ -21,6 +21,22 @@ Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus
     Test that atomic_set() cannot break the atomicity of atomic RMWs.
     NOTE: Require herd7 7.56 or later which supports "(void)expr".
 
+cmpxchg-fail-ordered-1.litmus
+    Demonstrate that a failing cmpxchg() operation acts as a full barrier
+    when followed by smp_mb__after_atomic().
+
+cmpxchg-fail-ordered-2.litmus
+    Demonstrate that a failing cmpxchg() operation acts as an acquire
+    operation when followed by smp_mb__after_atomic().
+
+cmpxchg-fail-unordered-1.litmus
+    Demonstrate that a failing cmpxchg() operation does not act as a
+    full barrier.
+
+cmpxchg-fail-unordered-2.litmus
+    Demonstrate that a failing cmpxchg() operation does not act as an
+    acquire operation.
+
 
 locking (/locking directory)
 ----------------------------
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-1.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-1.litmus
new file mode 100644 (file)
index 0000000..3df1d14
--- /dev/null
@@ -0,0 +1,34 @@
+C cmpxchg-fail-ordered-1
+
+(*
+ * Result: Never
+ *
+ * Demonstrate that a failing cmpxchg() operation will act as a full
+ * barrier when followed by smp_mb__after_atomic().
+ *)
+
+{}
+
+P0(int *x, int *y, int *z)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(z, 1, 0);
+       smp_mb__after_atomic();
+       r0 = READ_ONCE(*y);
+}
+
+P1(int *x, int *y, int *z)
+{
+       int r0;
+
+       WRITE_ONCE(*y, 1);
+       r1 = cmpxchg(z, 1, 0);
+       smp_mb__after_atomic();
+       r0 = READ_ONCE(*x);
+}
+
+locations[0:r1;1:r1]
+exists (0:r0=0 /\ 1:r0=0)
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-2.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-2.litmus
new file mode 100644 (file)
index 0000000..5414604
--- /dev/null
@@ -0,0 +1,30 @@
+C cmpxchg-fail-ordered-2
+
+(*
+ * Result: Never
+ *
+ * Demonstrate use of smp_mb__after_atomic() to make a failing cmpxchg
+ * operation have acquire ordering.
+ *)
+
+{}
+
+P0(int *x, int *y)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(y, 0, 1);
+}
+
+P1(int *x, int *y)
+{
+       int r0;
+
+       r1 = cmpxchg(y, 0, 1);
+       smp_mb__after_atomic();
+       r2 = READ_ONCE(*x);
+}
+
+exists (0:r1=0 /\ 1:r1=1 /\ 1:r2=0)
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-1.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-1.litmus
new file mode 100644 (file)
index 0000000..a727ce2
--- /dev/null
@@ -0,0 +1,33 @@
+C cmpxchg-fail-unordered-1
+
+(*
+ * Result: Sometimes
+ *
+ * Demonstrate that a failing cmpxchg() operation does not act as a
+ * full barrier.  (In contrast, a successful cmpxchg() does act as a
+ * full barrier.)
+ *)
+
+{}
+
+P0(int *x, int *y, int *z)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(z, 1, 0);
+       r0 = READ_ONCE(*y);
+}
+
+P1(int *x, int *y, int *z)
+{
+       int r0;
+
+       WRITE_ONCE(*y, 1);
+       r1 = cmpxchg(z, 1, 0);
+       r0 = READ_ONCE(*x);
+}
+
+locations[0:r1;1:r1]
+exists (0:r0=0 /\ 1:r0=0)
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-2.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-2.litmus
new file mode 100644 (file)
index 0000000..a245bac
--- /dev/null
@@ -0,0 +1,30 @@
+C cmpxchg-fail-unordered-2
+
+(*
+ * Result: Sometimes
+ *
+ * Demonstrate that a failing cmpxchg() operation does not act as either
+ * an acquire release operation.  (In contrast, a successful cmpxchg()
+ * does act as both an acquire and a release operation.)
+ *)
+
+{}
+
+P0(int *x, int *y)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(y, 0, 1);
+}
+
+P1(int *x, int *y)
+{
+       int r0;
+
+       r1 = cmpxchg(y, 0, 1);
+       r2 = READ_ONCE(*x);
+}
+
+exists (0:r1=0 /\ 1:r1=1 /\ 1:r2=0)