1

Documentation/litmus-tests: Demonstrate unordered failing cmpxchg

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>
This commit is contained in:
Paul E. McKenney 2024-02-01 11:17:54 -08:00
parent d2c470c491
commit 293f5bc271
5 changed files with 143 additions and 0 deletions

View 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)
----------------------------

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)