06 Oct, 2019

1 commit

  • Currently the Linux Kernel Memory Model gives an incorrect response
    for the following litmus test:

    C plain-WWC

    {}

    P0(int *x)
    {
    WRITE_ONCE(*x, 2);
    }

    P1(int *x, int *y)
    {
    int r1;
    int r2;
    int r3;

    r1 = READ_ONCE(*x);
    if (r1 == 2) {
    smp_rmb();
    r2 = *x;
    }
    smp_rmb();
    r3 = READ_ONCE(*x);
    WRITE_ONCE(*y, r3 - 1);
    }

    P2(int *x, int *y)
    {
    int r4;

    r4 = READ_ONCE(*y);
    if (r4 > 0)
    WRITE_ONCE(*x, 1);
    }

    exists (x=2 /\ 1:r2=2 /\ 2:r4=1)

    The memory model says that the plain read of *x in P1 races with the
    WRITE_ONCE(*x) in P2.

    The problem is that we have a write W and a read R related by neither
    fre or rfe, but rather W ->coe W' ->rfe R, where W' is an intermediate
    write (the WRITE_ONCE() in P0). In this situation there is no
    particular ordering between W and R, so either a wr-vis link from W to
    R or an rw-xbstar link from R to W would prove that the accesses
    aren't concurrent.

    But the LKMM only looks for a wr-vis link, which is equivalent to
    assuming that W must execute before R. This is not necessarily true
    on non-multicopy-atomic systems, as the WWC pattern demonstrates.

    This patch changes the LKMM to accept either a wr-vis or a reverse
    rw-xbstar link as a proof of non-concurrency.

    Signed-off-by: Alan Stern
    Acked-by: Andrea Parri
    Signed-off-by: Paul E. McKenney

    Alan Stern
     

25 Jun, 2019

1 commit

  • Herbert Xu recently reported a problem concerning RCU and compiler
    barriers. In the course of discussing the problem, he put forth a
    litmus test which illustrated a serious defect in the Linux Kernel
    Memory Model's data-race-detection code [1].

    The defect was that the LKMM assumed visibility and executes-before
    ordering of plain accesses had to be mediated by marked accesses. In
    Herbert's litmus test this wasn't so, and the LKMM claimed the litmus
    test was allowed and contained a data race although neither is true.

    In fact, plain accesses can be ordered by fences even in the absence
    of marked accesses. In most cases this doesn't matter, because most
    fences only order accesses within a single thread. But the rcu-fence
    relation is different; it can order (and induce visibility between)
    accesses in different threads -- events which otherwise might be
    concurrent. This makes it relevant to data-race detection.

    This patch makes two changes to the memory model to incorporate the
    new insight:

    If a store is separated by a fence from another access,
    the store is necessarily visible to the other access (as
    reflected in the ww-vis and wr-vis relations). Similarly,
    if a load is separated by a fence from another access then
    the load necessarily executes before the other access (as
    reflected in the rw-xbstar relation).

    If a store is separated by a strong fence from a marked access
    then it is necessarily visible to any access that executes
    after the marked access (as reflected in the ww-vis and wr-vis
    relations).

    With these changes, the LKMM gives the desired result for Herbert's
    litmus test and other related ones [2].

    [1] https://lore.kernel.org/lkml/Pine.LNX.4.44L0.1906041026570.1731-100000@iolanthe.rowland.org/

    [2] https://github.com/paulmckrcu/litmus/blob/master/manual/plain/C-S-rcunoderef-1.litmus
    https://github.com/paulmckrcu/litmus/blob/master/manual/plain/C-S-rcunoderef-2.litmus
    https://github.com/paulmckrcu/litmus/blob/master/manual/plain/C-S-rcunoderef-3.litmus
    https://github.com/paulmckrcu/litmus/blob/master/manual/plain/C-S-rcunoderef-4.litmus
    https://github.com/paulmckrcu/litmus/blob/master/manual/plain/strong-vis.litmus

    Reported-by: Herbert Xu
    Signed-off-by: Alan Stern
    Acked-by: Andrea Parri
    Signed-off-by: Paul E. McKenney
    Tested-by: Akira Yokosawa

    Alan Stern
     

22 Jun, 2019

2 commits

  • The rcu-fence relation in the Linux Kernel Memory Model is not well
    named. It doesn't act like any other fence relation, in that it does
    not relate events before a fence to events after that fence. All it
    does is relate certain RCU events to one another (those that are
    ordered by the RCU Guarantee); this induces an actual
    strong-fence-like relation linking events preceding the first RCU
    event to those following the second.

    This patch renames rcu-fence, now called rcu-order. It adds a new
    definition of rcu-fence, something which should have been present all
    along because it is used in the rb relation. And it modifies the
    fence and strong-fence relations by making them incorporate the new
    rcu-fence.

    As a result of this change, there is no longer any need to define
    full-fence in the section for detecting data races. It can simply be
    replaced by the updated strong-fence relation.

    This change should have no effect on the operation of the memory model.

    Signed-off-by: Alan Stern
    Acked-by: Andrea Parri
    Signed-off-by: Paul E. McKenney

    Alan Stern
     
  • Commit 66be4e66a7f4 ("rcu: locking and unlocking need to always be at
    least barriers") added compiler barriers back into rcu_read_lock() and
    rcu_read_unlock(). Furthermore, srcu_read_lock() and
    srcu_read_unlock() have always contained compiler barriers.

    The Linux Kernel Memory Model ought to know about these barriers.
    This patch adds them into the memory model.

    Signed-off-by: Alan Stern
    Acked-by: Andrea Parri
    Signed-off-by: Paul E. McKenney

    Alan Stern
     

28 May, 2019

3 commits

  • This patch adds data-race detection to the Linux-Kernel Memory Model.
    As part of this effort, support is added for:

    compiler barriers (the barrier() function), and

    a new Preserved Program Order term: (addr ; [Plain] ; wmb)

    Data races are marked with a special Flag warning in herd. It is
    not guaranteed that the model will provide accurate predictions when a
    data race is present.

    The patch does not include documentation for the data-race detection
    facility. The basic design has been explained in various emails, and
    a separate documentation patch will be submitted later.

    This work is based on an earlier formulation of data races for the
    LKMM by Andrea Parri.

    Signed-off-by: Alan Stern
    Reviewed-by: Andrea Parri
    Signed-off-by: Paul E. McKenney

    Alan Stern
     
  • This patch adds definitions for marked and plain accesses to the
    Linux-Kernel Memory Model. It also modifies the definitions of the
    existing parts of the model (including the cumul-fence, prop, hb, pb,
    and rb relations) so as to make them apply only to marked accesses.

    Signed-off-by: Alan Stern
    Reviewed-by: Andrea Parri
    Signed-off-by: Paul E. McKenney

    Alan Stern
     
  • This patch makes some slight alterations to linux-kernel.cat in
    preparation for adding support for data-race detection to the
    Linux-Kernel Memory Model.

    The definitions of relations involved in Acquire, Release, and
    unlock-lock ordering are moved up earlier in the source file.

    The rmb relation is factored through the new R4rmb class: the
    class of reads to which rmb will apply.

    The definition of the fence relation is moved earlier, and it
    is split up into read- and write-fences (rmb and wmb) and all
    the others.

    This should not make any functional changes.

    Signed-off-by: Alan Stern
    Reviewed-by: Andrea Parri
    Signed-off-by: Paul E. McKenney

    Alan Stern
     

19 Mar, 2019

5 commits

  • Currently, herdtools version information appears no fewer than three
    times in the LKMM source, which is difficult to maintain. This commit
    therefore places the required version in one place, namely the
    tools/memory-model/README file.

    Signed-off-by: Andrea Parri
    Signed-off-by: Paul E. McKenney
    Acked-by: Alan Stern

    Andrea Parri
     
  • This commit checks that the return value of srcu_read_lock() is passed
    to the matching srcu_read_unlock(), where "matching" is determined by
    nesting. This check operates as follows:

    1. srcu_read_lock() creates an integer token, which is stored into
    the generated events.
    2. srcu_read_unlock() records its second (token) argument into the
    generated event.
    3. A new herd primitive 'different-values' filters out pairs of events
    with identical values from the relation passed as its argument.
    4. The bell file applies the above primitive to the (srcu)
    read-side-critical-section relation 'srcu-rscs' and flags non-empty
    results.

    BEWARE: Works only with herd version 7.51+6 and onwards.

    Signed-off-by: Luc Maranget
    Signed-off-by: Paul E. McKenney
    [ paulmck: Apply Andrea Parri's off-list feedback. ]
    Acked-by: Alan Stern

    Luc Maranget
     
  • Add support for SRCU. Herd creates srcu events and linux-kernel.def
    associates them with three possible annotations (srcu-lock,
    srcu-unlock, and sync-srcu) corresponding to the API routines
    srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu().

    The linux-kernel.bell file now declares the annotations
    and determines matching lock/unlock pairs delimiting SRCU read-side
    critical sections, and it also checks for synchronize_srcu() calls
    inside an RCU critical section (which would generate a "sleeping in
    atomic context" error in real kernel code). The linux-kernel.cat file
    now adds SRCU-induced ordering, analogous to the existing RCU-induced
    ordering, to the gp and rcu-fence relations.

    Curiously enough, these small changes to the model's .cat code are all
    that is needed to describe SRCU.

    Portions of this patch (linux-kernel.def and the first hunk in
    linux-kernel.bell) were written by Luc Maranget.

    Signed-off-by: Alan Stern
    CC: Luc Maranget
    Signed-off-by: Paul E. McKenney
    Tested-by: Andrea Parri

    Alan Stern
     
  • In preparation for adding support for SRCU, refactor the definitions
    of rcu-fence, rcu-rscsi, rcu-link, and rb by moving the po and po?
    terms from the first two to the second two. An rcu-gp relation is
    added; it is equivalent to gp with the po and po? terms removed.

    This is necessary because for SRCU, we will have to use the loc
    relation to check that the terms at the start and end of each disjunct
    in the definition of rcu-fence refer to the same srcu_struct
    location. If these terms are hidden behind po and po?, there's no way
    to carry out this check.

    Signed-off-by: Alan Stern
    Signed-off-by: Paul E. McKenney
    Tested-by: Andrea Parri

    Alan Stern
     
  • In preparation for adding support for SRCU, rename "crit" to
    "rcu-rscs", rename "rscs" to "rcu-rscsi", and remove the restriction
    to only the outermost level of nesting.

    The name change is needed for disambiguating RCU read-side critical
    sections from SRCU read-side critical sections. Adding the "i" at the
    end of "rcu-rscsi" emphasizes that the relation is inverted; it links
    rcu_read_unlock() events to their corresponding preceding
    rcu_read_lock() events.

    The restriction to outermost nesting levels was never essential; it
    was included mostly to show that it could be done. Rather than add
    equivalent unnecessary code for SRCU lock nesting, it seemed better to
    remove the existing code.

    Signed-off-by: Alan Stern
    Signed-off-by: Paul E. McKenney
    Tested-by: Andrea Parri

    Alan Stern
     

21 Jan, 2019

1 commit

  • The kernel documents smp_mb__after_unlock_lock() the following way:

    "Place this after a lock-acquisition primitive to guarantee that
    an UNLOCK+LOCK pair acts as a full barrier. This guarantee applies
    if the UNLOCK and LOCK are executed by the same CPU or if the
    UNLOCK and LOCK operate on the same lock variable."

    Formalize in LKMM the above guarantee by defining (new) mb-links according
    to the law:

    ([M] ; po ; [UL] ; (co | po) ; [LKW] ;
    fencerel(After-unlock-lock) ; [M])

    where the component ([UL] ; co ; [LKW]) identifies "UNLOCK+LOCK pairs on
    the same lock variable" and the component ([UL] ; po ; [LKW]) identifies
    "UNLOCK+LOCK pairs executed by the same CPU".

    In particular, the LKMM forbids the following two behaviors (the second
    litmus test below is based on:

    Documentation/RCU/Design/Memory-Ordering/Tree-RCU-Memory-Ordering.html

    c.f., Section "Tree RCU Grace Period Memory Ordering Building Blocks"):

    C after-unlock-lock-same-cpu

    (*
    * Result: Never
    *)

    {}

    P0(spinlock_t *s, spinlock_t *t, int *x, int *y)
    {
    int r0;

    spin_lock(s);
    WRITE_ONCE(*x, 1);
    spin_unlock(s);
    spin_lock(t);
    smp_mb__after_unlock_lock();
    r0 = READ_ONCE(*y);
    spin_unlock(t);
    }

    P1(int *x, int *y)
    {
    int r0;

    WRITE_ONCE(*y, 1);
    smp_mb();
    r0 = READ_ONCE(*x);
    }

    exists (0:r0=0 /\ 1:r0=0)

    C after-unlock-lock-same-lock-variable

    (*
    * Result: Never
    *)

    {}

    P0(spinlock_t *s, int *x, int *y)
    {
    int r0;

    spin_lock(s);
    WRITE_ONCE(*x, 1);
    r0 = READ_ONCE(*y);
    spin_unlock(s);
    }

    P1(spinlock_t *s, int *y, int *z)
    {
    int r0;

    spin_lock(s);
    smp_mb__after_unlock_lock();
    WRITE_ONCE(*y, 1);
    r0 = READ_ONCE(*z);
    spin_unlock(s);
    }

    P2(int *z, int *x)
    {
    int r0;

    WRITE_ONCE(*z, 1);
    smp_mb();
    r0 = READ_ONCE(*x);
    }

    exists (0:r0=0 /\ 1:r0=0 /\ 2:r0=0)

    Signed-off-by: Andrea Parri
    Signed-off-by: Paul E. McKenney
    Cc: Akira Yokosawa
    Cc: Alan Stern
    Cc: Boqun Feng
    Cc: Daniel Lustig
    Cc: David Howells
    Cc: Jade Alglave
    Cc: Linus Torvalds
    Cc: Luc Maranget
    Cc: Nicholas Piggin
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Will Deacon
    Cc: linux-arch@vger.kernel.org
    Cc: parri.andrea@gmail.com
    Link: http://lkml.kernel.org/r/20181203230451.28921-1-paulmck@linux.ibm.com
    Signed-off-by: Ingo Molnar

    Andrea Parri
     

02 Oct, 2018

1 commit

  • More than one kernel developer has expressed the opinion that the LKMM
    should enforce ordering of writes by locking. In other words, given
    the following code:

    WRITE_ONCE(x, 1);
    spin_unlock(&s):
    spin_lock(&s);
    WRITE_ONCE(y, 1);

    the stores to x and y should be propagated in order to all other CPUs,
    even though those other CPUs might not access the lock s. In terms of
    the memory model, this means expanding the cumul-fence relation.

    Locks should also provide read-read (and read-write) ordering in a
    similar way. Given:

    READ_ONCE(x);
    spin_unlock(&s);
    spin_lock(&s);
    READ_ONCE(y); // or WRITE_ONCE(y, 1);

    the load of x should be executed before the load of (or store to) y.
    The LKMM already provides this ordering, but it provides it even in
    the case where the two accesses are separated by a release/acquire
    pair of fences rather than unlock/lock. This would prevent
    architectures from using weakly ordered implementations of release and
    acquire, which seems like an unnecessary restriction. The patch
    therefore removes the ordering requirement from the LKMM for that
    case.

    There are several arguments both for and against this change. Let us
    refer to these enhanced ordering properties by saying that the LKMM
    would require locks to be RCtso (a bit of a misnomer, but analogous to
    RCpc and RCsc) and it would require ordinary acquire/release only to
    be RCpc. (Note: In the following, the phrase "all supported
    architectures" is meant not to include RISC-V. Although RISC-V is
    indeed supported by the kernel, the implementation is still somewhat
    in a state of flux and therefore statements about it would be
    premature.)

    Pros:

    The kernel already provides RCtso ordering for locks on all
    supported architectures, even though this is not stated
    explicitly anywhere. Therefore the LKMM should formalize it.

    In theory, guaranteeing RCtso ordering would reduce the need
    for additional barrier-like constructs meant to increase the
    ordering strength of locks.

    Will Deacon and Peter Zijlstra are strongly in favor of
    formalizing the RCtso requirement. Linus Torvalds and Will
    would like to go even further, requiring locks to have RCsc
    behavior (ordering preceding writes against later reads), but
    they recognize that this would incur a noticeable performance
    degradation on the POWER architecture. Linus also points out
    that people have made the mistake, in the past, of assuming
    that locking has stronger ordering properties than is
    currently guaranteed, and this change would reduce the
    likelihood of such mistakes.

    Not requiring ordinary acquire/release to be any stronger than
    RCpc may prove advantageous for future architectures, allowing
    them to implement smp_load_acquire() and smp_store_release()
    with more efficient machine instructions than would be
    possible if the operations had to be RCtso. Will and Linus
    approve this rationale, hypothetical though it is at the
    moment (it may end up affecting the RISC-V implementation).
    The same argument may or may not apply to RMW-acquire/release;
    see also the second Con entry below.

    Linus feels that locks should be easy for people to use
    without worrying about memory consistency issues, since they
    are so pervasive in the kernel, whereas acquire/release is
    much more of an "experts only" tool. Requiring locks to be
    RCtso is a step in this direction.

    Cons:

    Andrea Parri and Luc Maranget think that locks should have the
    same ordering properties as ordinary acquire/release (indeed,
    Luc points out that the names "acquire" and "release" derive
    from the usage of locks). Andrea points out that having
    different ordering properties for different forms of acquires
    and releases is not only unnecessary, it would also be
    confusing and unmaintainable.

    Locks are constructed from lower-level primitives, typically
    RMW-acquire (for locking) and ordinary release (for unlock).
    It is illogical to require stronger ordering properties from
    the high-level operations than from the low-level operations
    they comprise. Thus, this change would make

    while (cmpxchg_acquire(&s, 0, 1) != 0)
    cpu_relax();

    an incorrect implementation of spin_lock(&s) as far as the
    LKMM is concerned. In theory this weakness can be ameliorated
    by changing the LKMM even further, requiring
    RMW-acquire/release also to be RCtso (which it already is on
    all supported architectures).

    As far as I know, nobody has singled out any examples of code
    in the kernel that actually relies on locks being RCtso.
    (People mumble about RCU and the scheduler, but nobody has
    pointed to any actual code. If there are any real cases,
    their number is likely quite small.) If RCtso ordering is not
    needed, why require it?

    A handful of locking constructs (qspinlocks, qrwlocks, and
    mcs_spinlocks) are built on top of smp_cond_load_acquire()
    instead of an RMW-acquire instruction. It currently provides
    only the ordinary acquire semantics, not the stronger ordering
    this patch would require of locks. In theory this could be
    ameliorated by requiring smp_cond_load_acquire() in
    combination with ordinary release also to be RCtso (which is
    currently true on all supported architectures).

    On future weakly ordered architectures, people may be able to
    implement locks in a non-RCtso fashion with significant
    performance improvement. Meeting the RCtso requirement would
    necessarily add run-time overhead.

    Overall, the technical aspects of these arguments seem relatively
    minor, and it appears mostly to boil down to a matter of opinion.
    Since the opinions of senior kernel maintainers such as Linus,
    Peter, and Will carry more weight than those of Luc and Andrea, this
    patch changes the model in accordance with the maintainers' wishes.

    Signed-off-by: Alan Stern
    Signed-off-by: Paul E. McKenney
    Reviewed-by: Will Deacon
    Reviewed-by: Andrea Parri
    Acked-by: Peter Zijlstra (Intel)
    Cc: Alexander Shishkin
    Cc: Arnaldo Carvalho de Melo
    Cc: Jiri Olsa
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Stephane Eranian
    Cc: Thomas Gleixner
    Cc: Vince Weaver
    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: npiggin@gmail.com
    Cc: parri.andrea@gmail.com
    Link: http://lkml.kernel.org/r/20180926182920.27644-2-paulmck@linux.ibm.com
    Signed-off-by: Ingo Molnar

    Alan Stern
     

15 May, 2018

3 commits

  • ASPLOS 2018 was held in March: make sure this is reflected in
    header comments and references.

    Signed-off-by: Andrea Parri
    Signed-off-by: Paul E. McKenney
    Cc: Akira Yokosawa
    Cc: Alan Stern
    Cc: Andrew Morton
    Cc: Boqun Feng
    Cc: David Howells
    Cc: Jade Alglave
    Cc: Linus Torvalds
    Cc: Luc Maranget
    Cc: Nicholas Piggin
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Will Deacon
    Cc: linux-arch@vger.kernel.org
    Cc: parri.andrea@gmail.com
    Link: http://lkml.kernel.org/r/1526340837-12222-18-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Andrea Parri
     
  • This patch reorganizes the definition of rb in the Linux Kernel Memory
    Consistency Model. The relation is now expressed in terms of
    rcu-fence, which consists of a sequence of gp and rscs links separated
    by rcu-link links, in which the number of occurrences of gp is >= the
    number of occurrences of rscs.

    Arguments similar to those published in
    http://diy.inria.fr/linux/long.pdf show that rcu-fence behaves like an
    inter-CPU strong fence. Furthermore, the definition of rb in terms of
    rcu-fence is highly analogous to the definition of pb in terms of
    strong-fence, which can help explain why rcu-path expresses a form of
    temporal ordering.

    This change should not affect the semantics of the memory model, just
    its internal organization.

    Signed-off-by: Alan Stern
    Signed-off-by: Paul E. McKenney
    Reviewed-by: Boqun Feng
    Reviewed-by: Andrea Parri
    Cc: Andrew Morton
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Will Deacon
    Cc: akiyks@gmail.com
    Cc: dhowells@redhat.com
    Cc: j.alglave@ucl.ac.uk
    Cc: linux-arch@vger.kernel.org
    Cc: luc.maranget@inria.fr
    Cc: npiggin@gmail.com
    Link: http://lkml.kernel.org/r/1526340837-12222-2-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Alan Stern
     
  • This patch makes a simple non-functional change to the RCU portion of
    the Linux Kernel Memory Consistency Model by renaming the "link" and
    "rcu-path" relations to "rcu-link" and "rb", respectively.

    The name "link" was an unfortunate choice, because it was too generic
    and subject to confusion with other meanings of the same word, which
    occur quite often in LKMM documentation. The name "rcu-path" is not
    very appropriate, because the relation is analogous to the
    happens-before (hb) and propagates-before (pb) relations -- although
    that fact won't become apparent until the second patch in this series.

    Signed-off-by: Alan Stern
    Signed-off-by: Paul E. McKenney
    Acked-by: Andrea Parri
    Cc: Andrew Morton
    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Will Deacon
    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: npiggin@gmail.com
    Link: http://lkml.kernel.org/r/1526340837-12222-1-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Alan Stern
     

21 Feb, 2018

3 commits

  • Since commit 76ebbe78f739 ("locking/barriers: Add implicit
    smp_read_barrier_depends() to READ_ONCE()") was merged for the 4.15
    kernel, it has not been necessary to use smp_read_barrier_depends().
    Similarly, commit 59ecbbe7b31c ("locking/barriers: Kill
    lockless_dereference()") removed lockless_dereference() from the
    kernel.

    Since these primitives are no longer part of the kernel, they do not
    belong in the Linux Kernel Memory Consistency Model. This patch
    removes them, along with the internal rb-dep relation, and updates the
    revelant documentation.

    Signed-off-by: Alan Stern
    Signed-off-by: Paul E. McKenney
    Acked-by: Peter Zijlstra
    Cc: Linus Torvalds
    Cc: Thomas Gleixner
    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: will.deacon@arm.com
    Link: http://lkml.kernel.org/r/1519169112-20593-12-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Alan Stern
     
  • Typical cat-language code uses hyphens for word separators in
    identifiers, but several LKMM identifiers use underscores instead.
    This commit therefore converts underscores to hyphens in the .bell-
    and .cat-file identifiers corresponding to smp_mb__before_atomic(),
    smp_mb__after_atomic(), and smp_mb__after_spinlock().

    Signed-off-by: Paul E. McKenney
    Acked-by: Peter Zijlstra
    Cc: Linus Torvalds
    Cc: Thomas Gleixner
    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-11-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Paul E. McKenney
     
  • Ingo pointed out that:

    "The "memory model" name is overly generic, ambiguous and somewhat
    misleading, as we usually mean the virtual memory layout/model
    when we say "memory model". GCC too uses it in that sense [...]"

    Make it clear that tools/memory-model/ uses the term "memory model" as
    shorthand for "memory consistency model" by calling out this convention
    in tools/memory-model/README.

    Stick to the original "memory model" term in sources' headers and for
    the subsystem name.

    Suggested-by: Ingo Molnar
    Signed-off-by: Andrea Parri
    Signed-off-by: Paul E. McKenney
    Acked-by: Peter Zijlstra
    Acked-by: Will Deacon
    Acked-by: Alan Stern
    Cc: Linus Torvalds
    Cc: Thomas Gleixner
    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
    Link: http://lkml.kernel.org/r/1519169112-20593-1-git-send-email-paulmck@linux.vnet.ibm.com
    Signed-off-by: Ingo Molnar

    Andrea Parri
     

25 Jan, 2018

1 commit

  • There is some reason to believe that Documentation/memory-barriers.txt
    could use some help, and a major purpose of this patch is to provide
    that help in the form of a design-time tool that can produce all valid
    executions of a small fragment of concurrent Linux-kernel code, which is
    called a "litmus test". This tool's functionality is roughly similar to
    a full state-space search. Please note that this is a design-time tool,
    not useful for regression testing. However, we hope that the underlying
    Linux-kernel memory model will be incorporated into other tools capable
    of analyzing large bodies of code for regression-testing purposes.

    The main tool is herd7, together with the linux-kernel.bell,
    linux-kernel.cat, linux-kernel.cfg, linux-kernel.def, and lock.cat files
    added by this patch. The herd7 executable takes the other files as input,
    and all of these files collectively define the Linux-kernel memory memory
    model. A brief description of each of these other files is provided
    in the README file. Although this tool does have its limitations,
    which are documented in the README file, it does improve on the version
    reported on in the LWN series (https://lwn.net/Articles/718628/ and
    https://lwn.net/Articles/720550/) by supporting locking and arithmetic,
    including a much wider variety of read-modify-write atomic operations.
    Please note that herd7 is not part of this submission, but is freely
    available from http://diy.inria.fr/sources/index.html (and via "git"
    at https://github.com/herd/herdtools7).

    A second tool is klitmus7, which converts litmus tests to loadable
    kernel modules for direct testing. As with herd7, the klitmus7
    code is freely available from http://diy.inria.fr/sources/index.html
    (and via "git" at https://github.com/herd/herdtools7).

    Of course, litmus tests are not always the best way to fully understand a
    memory model, so this patch also includes Documentation/explanation.txt,
    which describes the memory model in detail. In addition,
    Documentation/recipes.txt provides example known-good and known-bad use
    cases for those who prefer working by example.

    This patch also includes a few sample litmus tests, and a great many
    more litmus tests are available at https://github.com/paulmckrcu/litmus.

    This patch was the result of a most excellent collaboration founded
    by Jade Alglave and also including Alan Stern, Andrea Parri, and Luc
    Maranget. For more details on the history of this collaboration, please
    refer to the Linux-kernel memory model presentations at 2016 LinuxCon EU,
    2016 Kernel Summit, 2016 Linux Plumbers Conference, 2017 linux.conf.au,
    or 2017 Linux Plumbers Conference microconference. However, one aspect
    of the history does bear repeating due to weak copyright tracking earlier
    in this project, which extends back to early 2015. This weakness came
    to light in late 2017 after an LKMM presentation by Paul in which an
    audience member noted the similarity of some LKMM code to code in early
    published papers. This prompted a copyright review.

    From Alan Stern:

    To say that the model was mine is not entirely accurate.
    Pieces of it (especially the Scpv and Atomic axioms) were taken
    directly from Jade's models. And of course the Happens-before
    and Propagation relations and axioms were heavily based on
    Jade and Luc's work, even though they weren't identical to the
    earlier versions. Only the RCU portion was completely original.

    . . .

    One can make a much better case that I wrote the bulk of lock.cat.
    However, it was inspired by Luc's earlier version (and still
    shares some elements in common), and of course it benefited from
    feedback and testing from all members of our group.

    The model prior to Alan's was Luc Maranget's. From Luc:

    I totally agree on Alan Stern's account of the linux kernel model
    genesis. I thank him for his acknowledgments of my participation
    to previous model drafts. I'd like to complete Alan Stern's
    statement: any bell cat code I have written has its roots in
    discussions with Jade Alglave and Paul McKenney. Moreover I
    have borrowed cat and bell code written by Jade Alglave freely.

    This copyright review therefore resulted in late adds to the copyright
    statements of several files.

    Discussion of v1 has raised several issues, which we do not believe should
    block acceptance given that this level of change will be ongoing, just
    as it has been with memory-barriers.txt:

    o Under what conditions should ordering provided by pure locking
    be seen by CPUs not holding the relevant lock(s)? In particular,
    should the message-passing pattern be forbidden?

    o Should examples involving C11 release sequences be forbidden?
    Note that this C11 is still a moving target for this issue:
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0735r0.html

    o Some details of the handling of internal dependencies for atomic
    read-modify-write atomic operations are still subject to debate.

    o Changes recently accepted into mainline greatly reduce the need
    to handle DEC Alpha as a special case. These changes add an
    smp_read_barrier_depends() to READ_ONCE(), thus causing Alpha
    to respect ordering of dependent reads. If these changes stick,
    the memory model can be simplified accordingly.

    o Will changes be required to accommodate RISC-V?

    Differences from v1:
    (http://lkml.kernel.org/r/20171113184031.GA26302@linux.vnet.ibm.com)

    o Add SPDX notations to .bell and .cat files, replacing
    textual license statements.

    o Add reference to upcoming ASPLOS paper to .bell and .cat files.

    o Updated identifier names in .bell and .cat files to match those
    used in the ASPLOS paper.

    o Updates to READMEs and other documentation based on review
    feedback.

    o Added a memory-ordering cheatsheet.

    o Update sigs to new Co-Developed-by and add acks and
    reviewed-bys.

    o Simplify rules detecting nested RCU read-side critical sections.

    o Update copyright statements as noted above.

    Co-Developed-by: Alan Stern
    Co-Developed-by: Andrea Parri
    Co-Developed-by: Jade Alglave
    Co-Developed-by: Luc Maranget
    Co-Developed-by: "Paul E. McKenney"
    Signed-off-by: Alan Stern
    Signed-off-by: Andrea Parri
    Signed-off-by: Jade Alglave
    Signed-off-by: Luc Maranget
    Signed-off-by: "Paul E. McKenney"
    Reviewed-by: Boqun Feng
    Acked-by: Will Deacon
    Acked-by: Peter Zijlstra
    Acked-by: Nicholas Piggin
    Acked-by: David Howells
    Acked-by: "Reshetova, Elena"
    Acked-by: Michal Hocko
    Acked-by: Akira Yokosawa
    Cc:

    Paul E. McKenney