EXP litmus_tests: Add comments explaining tests' purposes
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Tue, 20 Feb 2018 23:25:04 +0000 (15:25 -0800)
committerIngo Molnar <mingo@kernel.org>
Wed, 21 Feb 2018 08:58:13 +0000 (09:58 +0100)
This commit adds comments to the litmus tests summarizing what these
tests are intended to demonstrate.

[ paulmck: Apply Andrea's and Alan's feedback. ]
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: akiyks@gmail.com
Cc: boqun.feng@gmail.com
Cc: dhowells@redhat.com
Cc: j.alglave@ucl.ac.uk
Cc: linux-arch@vger.kernel.org
Cc: luc.maranget@inria.fr
Cc: nborisov@suse.com
Cc: npiggin@gmail.com
Cc: parri.andrea@gmail.com
Cc: stern@rowland.harvard.edu
Cc: will.deacon@arm.com
Link: http://lkml.kernel.org/r/1519169112-20593-4-git-send-email-paulmck@linux.vnet.ibm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
28 files changed:
tools/memory-model/litmus-tests/CoRR+poonceonce+Once.litmus
tools/memory-model/litmus-tests/CoRW+poonceonce+Once.litmus
tools/memory-model/litmus-tests/CoWR+poonceonce+Once.litmus
tools/memory-model/litmus-tests/CoWW+poonceonce.litmus
tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus
tools/memory-model/litmus-tests/IRIW+poonceonces+OnceOnce.litmus
tools/memory-model/litmus-tests/ISA2+poonceonces.litmus
tools/memory-model/litmus-tests/ISA2+pooncerelease+poacquirerelease+poacquireonce.litmus
tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus
tools/memory-model/litmus-tests/LB+poacquireonce+pooncerelease.litmus
tools/memory-model/litmus-tests/LB+poonceonces.litmus
tools/memory-model/litmus-tests/MP+onceassign+derefonce.litmus
tools/memory-model/litmus-tests/MP+polocks.litmus
tools/memory-model/litmus-tests/MP+poonceonces.litmus
tools/memory-model/litmus-tests/MP+pooncerelease+poacquireonce.litmus
tools/memory-model/litmus-tests/MP+porevlocks.litmus
tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus
tools/memory-model/litmus-tests/R+mbonceonces.litmus
tools/memory-model/litmus-tests/R+poonceonces.litmus
tools/memory-model/litmus-tests/S+poonceonces.litmus
tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus
tools/memory-model/litmus-tests/SB+mbonceonces.litmus
tools/memory-model/litmus-tests/SB+poonceonces.litmus
tools/memory-model/litmus-tests/WRC+poonceonces+Once.litmus
tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus
tools/memory-model/litmus-tests/Z6.0+pooncelock+poonceLock+pombonce.litmus
tools/memory-model/litmus-tests/Z6.0+pooncelock+pooncelock+pombonce.litmus
tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus

index 5b83d57f6ac52e568a282aa1968ad481536a1486..967f9f2a6226ba62ed593e6aff9e99d1fae02c85 100644 (file)
@@ -1,5 +1,12 @@
 C CoRR+poonceonce+Once
 
+(*
+ * Result: Never
+ *
+ * Test of read-read coherence, that is, whether or not two successive
+ * reads from the same variable are ordered.
+ *)
+
 {}
 
 P0(int *x)
index fab91c13d52cc9bfcf2d451049512a9d7406b0ff..4635739f3974dd76925b2a20f874f03a2e55ce5f 100644 (file)
@@ -1,5 +1,12 @@
 C CoRW+poonceonce+Once
 
+(*
+ * Result: Never
+ *
+ * Test of read-write coherence, that is, whether or not a read from
+ * a given variable and a later write to that same variable are ordered.
+ *)
+
 {}
 
 P0(int *x)
index 6a35ec2042ea22832bf7d29edde77edd69d006c2..bb068c92d8da27fad692b9d168875bc9c5de815c 100644 (file)
@@ -1,5 +1,12 @@
 C CoWR+poonceonce+Once
 
+(*
+ * Result: Never
+ *
+ * Test of write-read coherence, that is, whether or not a write to a
+ * given variable and a later read from that same variable are ordered.
+ *)
+
 {}
 
 P0(int *x)
index 32a96b832021be87c9cc89059a029a4166de8fc5..0d9f0a9587996cd37950a7fd4e12eed1e7a7faf9 100644 (file)
@@ -1,5 +1,12 @@
 C CoWW+poonceonce
 
+(*
+ * Result: Never
+ *
+ * Test of write-write coherence, that is, whether or not two successive
+ * writes to the same variable are ordered.
+ *)
+
 {}
 
 P0(int *x)
index 7eba2c68992bea8e2d5d6725a4bec894974cf3d5..50d5db9ea983b59cc4caf2c4def91c71da35f7ba 100644 (file)
@@ -1,5 +1,15 @@
 C IRIW+mbonceonces+OnceOnce
 
+(*
+ * Result: Never
+ *
+ * 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 the order of a pair
+ * of writes, where each write is to a different variable by a different
+ * process?
+ *)
+
 {}
 
 P0(int *x)
index b0556c6c75d4163840e7776b8336a734ab622654..4b54dd6a6cd9464ace77b470fc38f4ef86ce5cef 100644 (file)
@@ -1,5 +1,15 @@
 C IRIW+poonceonces+OnceOnce
 
+(*
+ * Result: Sometimes
+ *
+ * Test of independent reads from independent writes with nothing
+ * between each pairs of reads.  In other words, is anything at all
+ * needed to cause two different reading processes to agree on the order
+ * of a pair of writes, where each write is to a different variable by a
+ * different process?
+ *)
+
 {}
 
 P0(int *x)
index 9a1a233d70c392f864acbe0e585e6f0a358d5baa..b321aa6f4ea52d4125b750cd6517d1feddb522d0 100644 (file)
@@ -1,5 +1,14 @@
 C ISA2+poonceonces
 
+(*
+ * Result: Sometimes
+ *
+ * Given a release-acquire chain ordering the first process's store
+ * against the last process's load, is ordering preserved if all of the
+ * smp_store_release() invocations are replaced by WRITE_ONCE() and all
+ * of the smp_load_acquire() invocations are replaced by READ_ONCE()?
+ *)
+
 {}
 
 P0(int *x, int *y)
index 235195e87d4e60171ae4269702d3782f3905798c..025b0462ec9bcdb56c35150ab52716aea1b1589c 100644 (file)
@@ -1,5 +1,16 @@
 C ISA2+pooncerelease+poacquirerelease+poacquireonce
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that a release-acquire chain suffices
+ * to order P0()'s initial write against P2()'s final read.  The reason
+ * that the release-acquire chain suffices is because in all but one
+ * case (P2() to P0()), each process reads from the preceding process's
+ * write.  In memory-model-speak, there is only one non-reads-from
+ * (AKA non-rf) link, so release-acquire is all that is needed.
+ *)
+
 {}
 
 P0(int *x, int *y)
index dd5ac3a8974a875d960bc3b76276ef47112fd958..de6708229dd11b075a95c3aaa938675b340c3005 100644 (file)
@@ -1,5 +1,16 @@
 C LB+ctrlonceonce+mbonceonce
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that lightweight ordering suffices for
+ * the load-buffering pattern, in other words, preventing all processes
+ * reading from the preceding process's write.  In this example, the
+ * combination of a control dependency and a full memory barrier are enough
+ * to do the trick.  (But the full memory barrier could be replaced with
+ * another control dependency and order would still be maintained.)
+ *)
+
 {}
 
 P0(int *x, int *y)
index 47bd61319d93a6cdfe67e7adc4d8f0c0c4a09e8f..07b9904b0e49f058f8b0f7505078ffb213aa5a6c 100644 (file)
@@ -1,5 +1,13 @@
 C LB+poacquireonce+pooncerelease
 
+(*
+ * Result: Never
+ *
+ * Does a release-acquire pair suffice for the load-buffering litmus
+ * test, where each process reads from one of two variables then writes
+ * to the other?
+ *)
+
 {}
 
 P0(int *x, int *y)
index a5cdf027e34b2b04581168928e35f7317572ccdc..74c49cb3c37bf78df023689161b09678f78ce2a1 100644 (file)
@@ -1,5 +1,12 @@
 C LB+poonceonces
 
+(*
+ * Result: Sometimes
+ *
+ * Can the counter-intuitive outcome for the load-buffering pattern
+ * be prevented even with no explicit ordering?
+ *)
+
 {}
 
 P0(int *x, int *y)
index 1a2fe583038155249d7730488446d889d1a581db..97731b4bbdd8eb1d15685162665c5d27b18ed970 100644 (file)
@@ -1,4 +1,13 @@
-C MP+onceassign+derefonce.litmus
+C MP+onceassign+derefonce
+
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that rcu_assign_pointer() and
+ * rcu_dereference() suffice to ensure that an RCU reader will not see
+ * pre-initialization garbage when it traverses an RCU-protected data
+ * structure containing a newly inserted element.
+ *)
 
 {
 y=z;
index 5fe6f1e3c452b30350d28af65462d6cf8ce0aadd..712a4fcdf6ce88f35e533d84e143777b37906123 100644 (file)
@@ -1,5 +1,16 @@
 C MP+polocks
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates how lock acquisitions and releases can
+ * stand in for smp_load_acquire() and smp_store_release(), respectively.
+ * In other words, when holding a given lock (or indeed after releasing a
+ * given lock), a CPU is not only guaranteed to see the accesses that other
+ * CPUs made while previously holding that lock, it is also guaranteed
+ * to see all prior accesses by those other CPUs.
+ *)
+
 {}
 
 P0(int *x, int *y, spinlock_t *mylock)
index 46e1ac7ba126d387f63fa5eca08b3ab3c66975e9..b2b60b84fb9dc70536c4c4a12adf3ea922f00c8a 100644 (file)
@@ -1,5 +1,12 @@
 C MP+poonceonces
 
+(*
+ * Result: Maybe
+ *
+ * Can the counter-intuitive message-passing outcome be prevented with
+ * no ordering at all?
+ *)
+
 {}
 
 P0(int *x, int *y)
index 0b00cc7293bab952e44edf4db3e91f0646c4e7b8..d52c68429722646edf72e8aebf7723cfb6c4323d 100644 (file)
@@ -1,5 +1,13 @@
 C MP+pooncerelease+poacquireonce
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that smp_store_release() and
+ * smp_load_acquire() provide sufficient ordering for the message-passing
+ * pattern.
+ *)
+
 {}
 
 P0(int *x, int *y)
index 90d011c34f33170076761432926b91209320992a..72c9276b363ee4cea6194aec7253707cc5e3f853 100644 (file)
@@ -1,5 +1,16 @@
 C MP+porevlocks
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates how lock acquisitions and releases can
+ * stand in for smp_load_acquire() and smp_store_release(), respectively.
+ * In other words, when holding a given lock (or indeed after releasing a
+ * given lock), a CPU is not only guaranteed to see the accesses that other
+ * CPUs made while previously holding that lock, it is also guaranteed to
+ * see all prior accesses by those other CPUs.
+ *)
+
 {}
 
 P0(int *x, int *y, spinlock_t *mylock)
index 604ad41ea0c2be5e255ee8c93daa5d6e38b1bdc6..c078f38ff27ac40fedd34c937ed2d471827d4b56 100644 (file)
@@ -1,5 +1,13 @@
 C MP+wmbonceonce+rmbonceonce
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that smp_wmb() and smp_rmb() provide
+ * sufficient ordering for the message-passing pattern.  However, it
+ * is usually better to use smp_store_release() and smp_load_acquire().
+ *)
+
 {}
 
 P0(int *x, int *y)
index e69b9e3e9436dbfb39557661899033e0c61bee87..a0e884ad213210bd0bf149d3a9a9c08805e4cfa6 100644 (file)
@@ -1,5 +1,14 @@
 C R+mbonceonces
 
+(*
+ * Result: Never
+ *
+ * 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.  Note that weakening either of the barriers would
+ * cause the resulting test to be allowed.
+ *)
+
 {}
 
 P0(int *x, int *y)
index f7a12e00f82d5c093102d9abd4fe9520eee3d12b..5386f128a131dfa50852e6fc5869700d0fe09d17 100644 (file)
@@ -1,5 +1,13 @@
 C R+poonceonces
 
+(*
+ * Result: Sometimes
+ *
+ * This is the unordered (thus lacking smp_mb()) version of one of the
+ * classic counterintuitive litmus tests that illustrates the effects of
+ * store propagation delays.
+ *)
+
 {}
 
 P0(int *x, int *y)
index d0d541c8ec7dbf887d19e346c66f0f5e1f28a223..8c9c2f81a58055cdba5eeea5c502ef24d9416a69 100644 (file)
@@ -1,5 +1,14 @@
 C S+poonceonces
 
+(*
+ * Result: Sometimes
+ *
+ * Starting with a two-process release-acquire chain ordering P0()'s
+ * first store against P1()'s final load, if the smp_store_release()
+ * is replaced by WRITE_ONCE() and the smp_load_acquire() replaced by
+ * READ_ONCE(), is ordering preserved?
+ *)
+
 {}
 
 P0(int *x, int *y)
index 1d292d0d6603e868bd8a494736611721a7f8d17d..c53350205d282a35afea68db4b94dad73bc6fdef 100644 (file)
@@ -1,5 +1,12 @@
 C S+wmbonceonce+poacquireonce
 
+(*
+ * Result: Never
+ *
+ * Can a smp_wmb(), instead of a release, and an acquire order a prior
+ * store against a subsequent store?
+ *)
+
 {}
 
 P0(int *x, int *y)
index b76caa5af1af35a1c0dcee4ef097de22214bd577..74b874ffa8dadce5c9bb66015555dff7749d4b9e 100644 (file)
@@ -1,5 +1,14 @@
 C SB+mbonceonces
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates that full memory barriers suffice to
+ * order the store-buffering pattern, where each process writes to the
+ * variable that the preceding process reads.  (Locking and RCU can also
+ * suffice, but not much else.)
+ *)
+
 {}
 
 P0(int *x, int *y)
index c1797e03807e47995589c54e6ea1d8c9e1da3e80..10d550730b25fdd800f2dd5ec8a9f0e555d65415 100644 (file)
@@ -1,5 +1,13 @@
 C SB+poonceonces
 
+(*
+ * Result: Sometimes
+ *
+ * This litmus test demonstrates that at least some ordering is required
+ * to order the store-buffering pattern, where each process writes to the
+ * variable that the preceding process reads.
+ *)
+
 {}
 
 P0(int *x, int *y)
index f5e7c92f61cc8b7f6208e8d2c8bee259a13ab183..6a2bc12a1af1ad6b6bf75c5a902e01acd54f3af7 100644 (file)
@@ -1,5 +1,13 @@
 C WRC+poonceonces+Once
 
+(*
+ * Result: Sometimes
+ *
+ * This litmus test is an extension of the message-passing pattern,
+ * where the first write is moved to a separate process.  Note that this
+ * test has no ordering at all.
+ *)
+
 {}
 
 P0(int *x)
index e3d0018025dd1f527aede9e8e5bb6734e89ad0c3..97fcbffde9a0784d25cdaac59d27ff0a8f82a553 100644 (file)
@@ -1,5 +1,13 @@
 C WRC+pooncerelease+rmbonceonce+Once
 
+(*
+ * Result: Never
+ *
+ * This litmus test is an extension of the message-passing pattern, where
+ * the first write is moved to a separate process.  Because it features
+ * a release and a read memory barrier, it should be forbidden.
+ *)
+
 {}
 
 P0(int *x)
index 9c2cb53e6ef01053718d76d9f1df539effcc6a25..415248fb669902a9b1c77e0abf905fabfc9634f5 100644 (file)
@@ -1,5 +1,14 @@
 C Z6.0+pooncelock+poonceLock+pombonce
 
+(*
+ * Result: Never
+ *
+ * This litmus test demonstrates how smp_mb__after_spinlock() may be
+ * used to ensure that accesses in different critical sections for a
+ * given lock running on different CPUs are nevertheless seen in order
+ * by CPUs not holding that lock.
+ *)
+
 {}
 
 P0(int *x, int *y, spinlock_t *mylock)
index c9a1f1a49ae17d4d96e6a0870c37477e7a589d0e..10a2aa04cd078d9b55898887bb4373437b7b9288 100644 (file)
@@ -1,5 +1,13 @@
 C Z6.0+pooncelock+pooncelock+pombonce
 
+(*
+ * Result: Sometimes
+ *
+ * This example demonstrates that a pair of accesses made by different
+ * processes each while holding a given lock will not necessarily be
+ * seen as ordered by a third process not holding that lock.
+ *)
+
 {}
 
 P0(int *x, int *y, spinlock_t *mylock)
index 25409a0335146146638bae8f18cbaae2fa349fdc..a20fc3fafb536d511ae4fc38aade1c32fb744f65 100644 (file)
@@ -1,5 +1,19 @@
 C Z6.0+pooncerelease+poacquirerelease+mbonceonce
 
+(*
+ * Result: Sometimes
+ *
+ * This litmus test shows that a release-acquire chain, while sufficient
+ * when there is but one non-reads-from (AKA non-rf) link, does not suffice
+ * if there is more than one.  Of the three processes, only P1() reads from
+ * P0's write, which means that there are two non-rf links: P1() to P2()
+ * is a write-to-write link (AKA a "coherence" or just "co" link) and P2()
+ * to P0() is a read-to-write link (AKA a "from-reads" or just "fr" link).
+ * When there are two or more non-rf links, you typically will need one
+ * full barrier for each non-rf link.  (Exceptions include some cases
+ * involving locking.)
+ *)
+
 {}
 
 P0(int *x, int *y)