• Linus Torvalds's avatar
    rcu: locking and unlocking need to always be at least barriers · f0d1e74c
    Linus Torvalds authored
    commit 66be4e66a7f422128748e3c3ef6ee72b20a6197b upstream.
    
    Herbert Xu pointed out that commit bb73c52b ("rcu: Don't disable
    preemption for Tiny and Tree RCU readers") was incorrect in making the
    preempt_disable/enable() be conditional on CONFIG_PREEMPT_COUNT.
    
    If CONFIG_PREEMPT_COUNT isn't enabled, the preemption enable/disable is
    a no-op, but still is a compiler barrier.
    
    And RCU locking still _needs_ that compiler barrier.
    
    It is simply fundamentally not true that RCU locking would be a complete
    no-op: we still need to guarantee (for example) that things that can
    trap and cause preemption cannot migrate into the RCU locked region.
    
    The way we do that is by making it a barrier.
    
    See for example commit 386afc91 ("spinlocks and preemption points
    need to be at least compiler barriers") from back in 2013 that had
    similar issues with spinlocks that become no-ops on UP: they must still
    constrain the compiler from moving other operations into the critical
    region.
    
    Now, it is true that a lot of RCU operations already use READ_ONCE() and
    WRITE_ONCE() (which in practice likely would never be re-ordered wrt
    anything remotely interesting), but it is also true that that is not
    globally the case, and that it's not even necessarily always possible
    (ie bitfields etc).
    Reported-by: 's avatarHerbert Xu <herbert@gondor.apana.org.au>
    Fixes: bb73c52b ("rcu: Don't disable preemption for Tiny and Tree RCU readers")
    Cc: stable@kernel.org
    Cc: Boqun Feng <boqun.feng@gmail.com>
    Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Signed-off-by: 's avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    f0d1e74c
Name
Last commit
Last update
Documentation Loading commit data...
arch Loading commit data...
block Loading commit data...
certs Loading commit data...
crypto Loading commit data...
drivers Loading commit data...
firmware Loading commit data...
fs Loading commit data...
include Loading commit data...
init Loading commit data...
ipc Loading commit data...
kernel Loading commit data...
lib Loading commit data...
mm Loading commit data...
net Loading commit data...
samples Loading commit data...
scripts Loading commit data...
security Loading commit data...
sound Loading commit data...
tools Loading commit data...
usr Loading commit data...
virt Loading commit data...
.get_maintainer.ignore Loading commit data...
.gitignore Loading commit data...
.mailmap Loading commit data...
COPYING Loading commit data...
CREDITS Loading commit data...
Kbuild Loading commit data...
Kconfig Loading commit data...
MAINTAINERS Loading commit data...
Makefile Loading commit data...
README Loading commit data...
REPORTING-BUGS Loading commit data...