To support onlining multiple CPUs concurrently, change rcu_state.n_online_cpus updates to be atomic. Note, it's ok for rcu_blocking_is_gp() to do a atomic_read(&rcu_state.n_online_cpus), as the value of .n_online_cpus switches from 1->2, in rcutree_prepare_cpu(), which runs before the new CPU comes online. Similarly 2->1 transition happens from rcutree_dead_cpu(), which executes after the CPU is offlined, and runs on the last online CPU. Signed-off-by: Neeraj Upadhyay <quic_neeraju@xxxxxxxxxxx> --- kernel/rcu/tree.c | 6 +++--- kernel/rcu/tree.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 3da7826865f7..c1db01c4ea39 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2460,7 +2460,7 @@ int rcutree_dead_cpu(unsigned int cpu) if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) return 0; - WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus - 1); + atomic_dec(&rcu_state.n_online_cpus); /* Adjust any no-longer-needed kthreads. */ rcu_boost_kthread_setaffinity(rnp, -1); // Stop-machine done, so allow nohz_full to disable tick. @@ -3740,7 +3740,7 @@ static int rcu_blocking_is_gp(void) * in the code, without the need for additional memory barriers. * Those memory barriers are provided by CPU-hotplug code. */ - ret = READ_ONCE(rcu_state.n_online_cpus) <= 1; + ret = atomic_read(&rcu_state.n_online_cpus) <= 1; preempt_enable(); return ret; } @@ -4199,7 +4199,7 @@ int rcutree_prepare_cpu(unsigned int cpu) raw_spin_unlock_irqrestore_rcu_node(rnp, flags); rcu_spawn_one_boost_kthread(rnp); rcu_spawn_cpu_nocb_kthread(cpu); - WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus + 1); + atomic_inc(&rcu_state.n_online_cpus); return 0; } diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 4b889081f4f4..f1017e7e1e9e 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h @@ -299,7 +299,7 @@ struct rcu_state { /* Hierarchy levels (+1 to */ /* shut bogus gcc warning) */ int ncpus; /* # CPUs seen so far. */ - int n_online_cpus; /* # CPUs online for RCU. */ + atomic_t n_online_cpus; /* # CPUs online for RCU. */ /* The following fields are guarded by the root rcu_node's lock. */ -- 2.17.1