• Alan Stern's avatar
    tools: memory-model: Add rmw-sequences to the LKMM · ebd50e29
    Alan Stern authored
    Viktor (as relayed by Jonas) has pointed out a weakness in the Linux
    Kernel Memory Model.  Namely, the memory ordering properties of atomic
    operations are not monotonic: An atomic op with full-barrier semantics
    does not always provide ordering as strong as one with release-barrier
    semantics.
    
    The following litmus test illustrates the problem:
    
    --------------------------------------------------
    C atomics-not-monotonic
    
    {}
    
    P0(int *x, atomic_t *y)
    {
    	WRITE_ONCE(*x, 1);
    	smp_wmb();
    	atomic_set(y, 1);
    }
    
    P1(atomic_t *y)
    {
    	int r1;
    
    	r1 = atomic_inc_return(y);
    }
    
    P2(int *x, atomic_t *y)
    {
    	int r2;
    	int r3;
    
    	r2 = atomic_read(y);
    	smp_rmb();
    	r3 = READ_ONCE(*x);
    }
    
    exists (2:r2=2 /\ 2:r3=0)
    --------------------------------------------------
    
    The litmus test is allowed as shown with atomic_inc_return(), which
    has full-barrier semantics.  But if the operation is changed to
    atomic_inc_return_release(), which only has release-barrier semantics,
    the litmus test is forbidden.  Clearly this violates monotonicity.
    
    The reason is because the LKMM treats full-barrier atomic ops as if
    they were written:
    
    	mb();
    	load();
    	store();
    	mb();
    
    (where the load() and store() are the two parts of an atomic RMW op),
    whereas it treats release-barrier atomic ops as if they were written:
    
    	load();
    	release_barrier();
    	store();
    
    The difference is that here the release barrier orders the load part
    of the atomic op before the store part with A-cumulativity, whereas
    the mb()'s above do not.  This means that release-barrier atomics can
    effectively extend the cumul-fence relation but full-barrier atomics
    cannot.
    
    To resolve this problem we introduce the rmw-sequence relation,
    representing an arbitrarily long sequence of atomic RMW operations in
    which each operation reads from the previous one, and explicitly allow
    it to extend cumul-fence.  This modification of the memory model is
    sound; it holds for PPC because of B-cumulativity, it holds for TSO
    and ARM64 because of other-multicopy atomicity, and we can assume that
    atomic ops on all other architectures will be implemented so as to
    make it hold for them.
    
    For similar reasons we also allow rmw-sequence to extend the
    w-post-bounded relation, which is analogous to cumul-fence in some
    ways.
    Reported-by: default avatarViktor Vafeiadis <viktor@mpi-sws.org>
    Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    Reviewed-by: default avatarJonas Oberhauser <jonas.oberhauser@huawei.com>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    ebd50e29
linux-kernel.cat 7.12 KB