123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- ============
- LITMUS TESTS
- ============
- CoRR+poonceonce+Once.litmus
- Test of read-read coherence, that is, whether or not two
- successive reads from the same variable are ordered.
- CoRW+poonceonce+Once.litmus
- Test of read-write coherence, that is, whether or not a read
- from a given variable followed by a write to that same variable
- are ordered.
- CoWR+poonceonce+Once.litmus
- Test of write-read coherence, that is, whether or not a write
- to a given variable followed by a read from that same variable
- are ordered.
- CoWW+poonceonce.litmus
- Test of write-write coherence, that is, whether or not two
- successive writes to the same variable are ordered.
- 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
- the order of a pair of writes, where each write is to a different
- variable by a different process? This litmus test is forbidden
- by LKMM's propagation rule.
- IRIW+poonceonces+OnceOnce.litmus
- 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?
- ISA2+pooncelock+pooncelock+pombonce.litmus
- Tests whether the ordering provided by a lock-protected S
- litmus test is visible to an external process whose accesses are
- separated by smp_mb(). This addition of an external process to
- S is otherwise known as ISA2.
- ISA2+poonceonces.litmus
- As below, but with store-release replaced with WRITE_ONCE()
- and load-acquire replaced with READ_ONCE().
- ISA2+pooncerelease+poacquirerelease+poacquireonce.litmus
- Can a release-acquire chain order a prior store against
- a later load?
- 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?
- LB+poacquireonce+pooncerelease.litmus
- 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?
- LB+poonceonces.litmus
- As above, but with store-release replaced with WRITE_ONCE()
- and load-acquire replaced with READ_ONCE().
- LB+unlocklockonceonce+poacquireonce.litmus
- Does a unlock+lock pair provides ordering guarantee between a
- load and a store?
- MP+onceassign+derefonce.litmus
- As below, but with rcu_assign_pointer() and an rcu_dereference().
- MP+polockmbonce+poacquiresilsil.litmus
- Protect the access with a lock and an smp_mb__after_spinlock()
- in one process, and use an acquire load followed by a pair of
- spin_is_locked() calls in the other process.
- MP+polockonce+poacquiresilsil.litmus
- Protect the access with a lock in one process, and use an
- acquire load followed by a pair of spin_is_locked() calls
- in the other process.
- MP+polocks.litmus
- As below, but with the second access of the writer process
- and the first access of reader process protected by a lock.
- MP+poonceonces.litmus
- As below, but without the smp_rmb() and smp_wmb().
- MP+pooncerelease+poacquireonce.litmus
- As below, but with a release-acquire chain.
- 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+unlocklockonceonce+fencermbonceonce.litmus
- Does a unlock+lock pair provides ordering guarantee between a
- store and another store?
- 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+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.
- R+poonceonces.litmus
- As above, but without the smp_mb() invocations.
- 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.
- 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.
- 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+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
- A-cumulative in LKMM.
- Z6.0+pooncelock+pooncelock+pombonce.litmus
- Is the ordering provided by a spin_unlock() and a subsequent
- spin_lock() sufficient to make ordering apparent to accesses
- by a process not holding the lock?
- Z6.0+pooncelock+poonceLock+pombonce.litmus
- As above, but with smp_mb__after_spinlock() immediately
- following the spin_lock().
- 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?
- A great many more litmus tests are available here:
- https://github.com/paulmckrcu/litmus
- ==================
- LITMUS TEST NAMING
- ==================
- Litmus tests are usually named based on their contents, which means that
- looking at the name tells you what the litmus test does. The naming
- scheme covers litmus tests having a single cycle that passes through
- each process exactly once, so litmus tests not fitting this description
- are named on an ad-hoc basis.
- The structure of a litmus-test name is the litmus-test class, a plus
- sign ("+"), and one string for each process, separated by plus signs.
- The end of the name is ".litmus".
- The litmus-test classes may be found in the infamous test6.pdf:
- https://www.cl.cam.ac.uk/~pes20/ppc-supplemental/test6.pdf
- Each class defines the pattern of accesses and of the variables accessed.
- For example, if the one process writes to a pair of variables, and
- the other process reads from these same variables, the corresponding
- litmus-test class is "MP" (message passing), which may be found on the
- left-hand end of the second row of tests on page one of test6.pdf.
- The strings used to identify the actions carried out by each process are
- complex due to a desire to have short(er) names. Thus, there is a tool to
- generate these strings from a given litmus test's actions. For example,
- consider the processes from SB+rfionceonce-poonceonces.litmus:
- 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);
- }
- The next step is to construct a space-separated list of descriptors,
- interleaving descriptions of the relation between a pair of consecutive
- accesses with descriptions of the second access in the pair.
- P0()'s WRITE_ONCE() is read by its first READ_ONCE(), which is a
- reads-from link (rf) and internal to the P0() process. This is
- "rfi", which is an abbreviation for "reads-from internal". Because
- some of the tools string these abbreviations together with space
- characters separating processes, the first character is capitalized,
- resulting in "Rfi".
- P0()'s second access is a READ_ONCE(), as opposed to (for example)
- smp_load_acquire(), so next is "Once". Thus far, we have "Rfi Once".
- P0()'s third access is also a READ_ONCE(), but to y rather than x.
- This is related to P0()'s second access by program order ("po"),
- to a different variable ("d"), and both accesses are reads ("RR").
- The resulting descriptor is "PodRR". Because P0()'s third access is
- READ_ONCE(), we add another "Once" descriptor.
- A from-read ("fre") relation links P0()'s third to P1()'s first
- access, and the resulting descriptor is "Fre". P1()'s first access is
- WRITE_ONCE(), which as before gives the descriptor "Once". The string
- thus far is thus "Rfi Once PodRR Once Fre Once".
- The remainder of P1() is similar to P0(), which means we add
- "Rfi Once PodRR Once". Another fre links P1()'s last access to
- P0()'s first access, which is WRITE_ONCE(), so we add "Fre Once".
- The full string is thus:
- Rfi Once PodRR Once Fre Once Rfi Once PodRR Once Fre Once
- This string can be given to the "norm7" and "classify7" tools to
- produce the name:
- $ norm7 -bell linux-kernel.bell \
- Rfi Once PodRR Once Fre Once Rfi Once PodRR Once Fre Once | \
- sed -e 's/:.*//g'
- SB+rfionceonce-poonceonces
- Adding the ".litmus" suffix: SB+rfionceonce-poonceonces.litmus
- The descriptors that describe connections between consecutive accesses
- within the cycle through a given litmus test can be provided by the herd7
- tool (Rfi, Po, Fre, and so on) or by the linux-kernel.bell file (Once,
- Release, Acquire, and so on).
- To see the full list of descriptors, execute the following command:
- $ diyone7 -bell linux-kernel.bell -show edges
|