Commit 293f5bc2 authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

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: default avatarFrederic Weisbecker <frederic@kernel.org>
Signed-off-by: default avatarPaul 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: default avatarAndrea Parri <parri.andrea@gmail.com>
parent d2c470c4
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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)
----------------------------
+34 −0
Original line number Diff line number Diff line
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)
+30 −0
Original line number Diff line number Diff line
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)
+33 −0
Original line number Diff line number Diff line
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)
+30 −0
Original line number Diff line number Diff line
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)