diff options
author | Boqun Feng <boqun.feng@gmail.com> | 2018-03-09 09:14:51 +0800 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2018-05-15 10:26:07 -0700 |
commit | 55ebfce0605a4dce35467dfb1dc1b3ad26fe9f86 (patch) | |
tree | 18e8badda41172f8c3527929fcc8e0e776a3c22b /kernel/rcu/rcu_segcblist.h | |
parent | 7be8c56f8f8a58af92f8791c5a09d48e342d7101 (diff) | |
download | talos-obmc-linux-55ebfce0605a4dce35467dfb1dc1b3ad26fe9f86.tar.gz talos-obmc-linux-55ebfce0605a4dce35467dfb1dc1b3ad26fe9f86.zip |
rcu: exp: Protect all sync_rcu_preempt_exp_done() with rcu_node lock
Currently some callsites of sync_rcu_preempt_exp_done() are not called
with the corresponding rcu_node's ->lock held, which could introduces
bugs as per Paul:
o CPU 0 in sync_rcu_preempt_exp_done() reads ->exp_tasks and
sees that it is NULL.
o CPU 1 blocks within an RCU read-side critical section, so
it enqueues the task and points ->exp_tasks at it and
clears CPU 1's bit in ->expmask.
o All other CPUs clear their bits in ->expmask.
o CPU 0 reads ->expmask, sees that it is zero, so incorrectly
concludes that all quiescent states have completed, despite
the fact that ->exp_tasks is non-NULL.
To fix this, sync_rcu_preempt_exp_unlocked() is introduced to replace
lockless callsites of sync_rcu_preempt_exp_done().
Further, a lockdep annotation is added into sync_rcu_preempt_exp_done()
to prevent mis-use in the future.
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Tested-by: Nicholas Piggin <npiggin@gmail.com>
Diffstat (limited to 'kernel/rcu/rcu_segcblist.h')
0 files changed, 0 insertions, 0 deletions