Commit c1b14609 authored by Marco Elver's avatar Marco Elver Committed by Paul E. McKenney

tools/memory-model: Fix "conflict" definition

The definition of "conflict" should not include the type of access nor
whether the accesses are concurrent or not, which this patch addresses.
The definition of "data race" remains unchanged.

The definition of "conflict" as we know it and is cited by various
papers on memory consistency models appeared in [1]: "Two accesses to
the same variable conflict if at least one is a write; two operations
conflict if they execute conflicting accesses."

The LKMM as well as the C11 memory model are adaptations of
data-race-free, which are based on the work in [2]. Necessarily, we need
both conflicting data operations (plain) and synchronization operations
(marked). For example, C11's definition is based on [3], which defines a
"data race" as: "Two memory operations conflict if they access the same
memory location, and at least one of them is a store, atomic store, or
atomic read-modify-write operation. In a sequentially consistent
execution, two memory operations from different threads form a type 1
data race if they conflict, at least one of them is a data operation,
and they are adjacent in <T (i.e., they may be executed concurrently)."

[1] D. Shasha, M. Snir, "Efficient and Correct Execution of Parallel
    Programs that Share Memory", 1988.
	URL: http://snir.cs.illinois.edu/listed/J21.pdf

[2] S. Adve, "Designing Memory Consistency Models for Shared-Memory
    Multiprocessors", 1993.
	URL: http://sadve.cs.illinois.edu/Publications/thesis.pdf

[3] H.-J. Boehm, S. Adve, "Foundations of the C++ Concurrency Memory
    Model", 2008.
	URL: https://www.hpl.hp.com/techreports/2008/HPL-2008-56.pdfSigned-off-by: default avatarMarco Elver <elver@google.com>
Co-developed-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Acked-by: default avatarAndrea Parri <parri.andrea@gmail.com>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent 38908de9
...@@ -1987,28 +1987,36 @@ outcome undefined. ...@@ -1987,28 +1987,36 @@ outcome undefined.
In technical terms, the compiler is allowed to assume that when the In technical terms, the compiler is allowed to assume that when the
program executes, there will not be any data races. A "data race" program executes, there will not be any data races. A "data race"
occurs when two conflicting memory accesses execute concurrently; occurs when there are two memory accesses such that:
two memory accesses "conflict" if:
they access the same location, 1. they access the same location,
they occur on different CPUs (or in different threads on the 2. at least one of them is a store,
same CPU),
at least one of them is a plain access, 3. at least one of them is plain,
and at least one of them is a store. 4. they occur on different CPUs (or in different threads on the
same CPU), and
The LKMM tries to determine whether a program contains two conflicting 5. they execute concurrently.
accesses which may execute concurrently; if it does then the LKMM says
there is a potential data race and makes no predictions about the
program's outcome.
Determining whether two accesses conflict is easy; you can see that In the literature, two accesses are said to "conflict" if they satisfy
all the concepts involved in the definition above are already part of 1 and 2 above. We'll go a little farther and say that two accesses
the memory model. The hard part is telling whether they may execute are "race candidates" if they satisfy 1 - 4. Thus, whether or not two
concurrently. The LKMM takes a conservative attitude, assuming that race candidates actually do race in a given execution depends on
accesses may be concurrent unless it can prove they cannot. whether they are concurrent.
The LKMM tries to determine whether a program contains race candidates
which may execute concurrently; if it does then the LKMM says there is
a potential data race and makes no predictions about the program's
outcome.
Determining whether two accesses are race candidates is easy; you can
see that all the concepts involved in the definition above are already
part of the memory model. The hard part is telling whether they may
execute concurrently. The LKMM takes a conservative attitude,
assuming that accesses may be concurrent unless it can prove they
are not.
If two memory accesses aren't concurrent then one must execute before If two memory accesses aren't concurrent then one must execute before
the other. Therefore the LKMM decides two accesses aren't concurrent the other. Therefore the LKMM decides two accesses aren't concurrent
...@@ -2171,8 +2179,8 @@ again, now using plain accesses for buf: ...@@ -2171,8 +2179,8 @@ again, now using plain accesses for buf:
} }
This program does not contain a data race. Although the U and V This program does not contain a data race. Although the U and V
accesses conflict, the LKMM can prove they are not concurrent as accesses are race candidates, the LKMM can prove they are not
follows: concurrent as follows:
The smp_wmb() fence in P0 is both a compiler barrier and a The smp_wmb() fence in P0 is both a compiler barrier and a
cumul-fence. It guarantees that no matter what hash of cumul-fence. It guarantees that no matter what hash of
...@@ -2326,12 +2334,11 @@ could now perform the load of x before the load of ptr (there might be ...@@ -2326,12 +2334,11 @@ could now perform the load of x before the load of ptr (there might be
a control dependency but no address dependency at the machine level). a control dependency but no address dependency at the machine level).
Finally, it turns out there is a situation in which a plain write does Finally, it turns out there is a situation in which a plain write does
not need to be w-post-bounded: when it is separated from the not need to be w-post-bounded: when it is separated from the other
conflicting access by a fence. At first glance this may seem race-candidate access by a fence. At first glance this may seem
impossible. After all, to be conflicting the second access has to be impossible. After all, to be race candidates the two accesses must
on a different CPU from the first, and fences don't link events on be on different CPUs, and fences don't link events on different CPUs.
different CPUs. Well, normal fences don't -- but rcu-fence can! Well, normal fences don't -- but rcu-fence can! Here's an example:
Here's an example:
int x, y; int x, y;
...@@ -2367,7 +2374,7 @@ concurrent and there is no race, even though P1's plain store to y ...@@ -2367,7 +2374,7 @@ concurrent and there is no race, even though P1's plain store to y
isn't w-post-bounded by any marked accesses. isn't w-post-bounded by any marked accesses.
Putting all this material together yields the following picture. For Putting all this material together yields the following picture. For
two conflicting stores W and W', where W ->co W', the LKMM says the race-candidate stores W and W', where W ->co W', the LKMM says the
stores don't race if W can be linked to W' by a stores don't race if W can be linked to W' by a
w-post-bounded ; vis ; w-pre-bounded w-post-bounded ; vis ; w-pre-bounded
...@@ -2380,8 +2387,8 @@ sequence, and if W' is plain then they also have to be linked by a ...@@ -2380,8 +2387,8 @@ sequence, and if W' is plain then they also have to be linked by a
w-post-bounded ; vis ; r-pre-bounded w-post-bounded ; vis ; r-pre-bounded
sequence. For a conflicting load R and store W, the LKMM says the two sequence. For race-candidate load R and store W, the LKMM says the
accesses don't race if R can be linked to W by an two accesses don't race if R can be linked to W by an
r-post-bounded ; xb* ; w-pre-bounded r-post-bounded ; xb* ; w-pre-bounded
...@@ -2413,20 +2420,20 @@ is, the rules governing the memory subsystem's choice of a store to ...@@ -2413,20 +2420,20 @@ is, the rules governing the memory subsystem's choice of a store to
satisfy a load request and its determination of where a store will satisfy a load request and its determination of where a store will
fall in the coherence order): fall in the coherence order):
If R and W conflict and it is possible to link R to W by one If R and W are race candidates and it is possible to link R to
of the xb* sequences listed above, then W ->rfe R is not W by one of the xb* sequences listed above, then W ->rfe R is
allowed (i.e., a load cannot read from a store that it not allowed (i.e., a load cannot read from a store that it
executes before, even if one or both is plain). executes before, even if one or both is plain).
If W and R conflict and it is possible to link W to R by one If W and R are race candidates and it is possible to link W to
of the vis sequences listed above, then R ->fre W is not R by one of the vis sequences listed above, then R ->fre W is
allowed (i.e., if a store is visible to a load then the load not allowed (i.e., if a store is visible to a load then the
must read from that store or one coherence-after it). load must read from that store or one coherence-after it).
If W and W' conflict and it is possible to link W to W' by one If W and W' are race candidates and it is possible to link W
of the vis sequences listed above, then W' ->co W is not to W' by one of the vis sequences listed above, then W' ->co W
allowed (i.e., if one store is visible to a second then the is not allowed (i.e., if one store is visible to a second then
second must come after the first in the coherence order). the second must come after the first in the coherence order).
This is the extent to which the LKMM deals with plain accesses. This is the extent to which the LKMM deals with plain accesses.
Perhaps it could say more (for example, plain accesses might Perhaps it could say more (for example, plain accesses might
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment