Commit be94ecf7 authored by Paul Heidekrüger's avatar Paul Heidekrüger Committed by Paul E. McKenney
Browse files

tools/memory-model: Clarify LKMM's limitations in litmus-tests.txt

As discussed, clarify LKMM not recognizing certain kinds of orderings.
In particular, highlight the fact that LKMM might deliberately make
weaker guarantees than compilers and architectures.

[ paulmck: Fix whitespace issue noted by checkpatch.pl. ]

Link: https://lore.kernel.org/all/YpoW1deb%2FQeeszO1@ethstick13.dse.in.tum.de/T/#u


Co-developed-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarPaul Heidekrüger <paul.heidekrueger@in.tum.de>
Reviewed-by: default avatarMarco Elver <elver@google.com>
Reviewed-by: default avatarJoel Fernandes (Google) <joel@joelfernandes.org>
Cc: Charalampos Mainas <charalampos.mainas@gmail.com>
Cc: Pramod Bhatotia <pramod.bhatotia@in.tum.de>
Cc: Soham Chakraborty <s.s.chakraborty@tudelft.nl>
Cc: Martin Fink <martin.fink@in.tum.de>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent f556082d
Loading
Loading
Loading
Loading
+27 −10
Original line number Original line Diff line number Diff line
@@ -946,22 +946,39 @@ Limitations of the Linux-kernel memory model (LKMM) include:
	carrying a dependency, then the compiler can break that dependency
	carrying a dependency, then the compiler can break that dependency
	by substituting a constant of that value.
	by substituting a constant of that value.


	Conversely, LKMM sometimes doesn't recognize that a particular
	Conversely, LKMM will sometimes overestimate the amount of
	optimization is not allowed, and as a result, thinks that a
	reordering compilers and CPUs can carry out, leading it to miss
	dependency is not present (because the optimization would break it).
	some pretty obvious cases of ordering.  A simple example is:
	The memory model misses some pretty obvious control dependencies
	because of this limitation.  A simple example is:


		r1 = READ_ONCE(x);
		r1 = READ_ONCE(x);
		if (r1 == 0)
		if (r1 == 0)
			smp_mb();
			smp_mb();
		WRITE_ONCE(y, 1);
		WRITE_ONCE(y, 1);


	There is a control dependency from the READ_ONCE to the WRITE_ONCE,
	The WRITE_ONCE() does not depend on the READ_ONCE(), and as a
	even when r1 is nonzero, but LKMM doesn't realize this and thinks
	result, LKMM does not claim ordering.  However, even though no
	that the write may execute before the read if r1 != 0.  (Yes, that
	dependency is present, the WRITE_ONCE() will not be executed before
	doesn't make sense if you think about it, but the memory model's
	the READ_ONCE().  There are two reasons for this:
	intelligence is limited.)

                The presence of the smp_mb() in one of the branches
                prevents the compiler from moving the WRITE_ONCE()
                up before the "if" statement, since the compiler has
                to assume that r1 will sometimes be 0 (but see the
                comment below);

                CPUs do not execute stores before po-earlier conditional
                branches, even in cases where the store occurs after the
                two arms of the branch have recombined.

	It is clear that it is not dangerous in the slightest for LKMM to
	make weaker guarantees than architectures.  In fact, it is
	desirable, as it gives compilers room for making optimizations.
	For instance, suppose that a 0 value in r1 would trigger undefined
	behavior elsewhere.  Then a clever compiler might deduce that r1
	can never be 0 in the if condition.  As a result, said clever
	compiler might deem it safe to optimize away the smp_mb(),
	eliminating the branch and any ordering an architecture would
	guarantee otherwise.


2.	Multiple access sizes for a single variable are not supported,
2.	Multiple access sizes for a single variable are not supported,
	and neither are misaligned or partially overlapping accesses.
	and neither are misaligned or partially overlapping accesses.