]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
rcu: Make rcu_state.n_online_cpus updates atomic
authorNeeraj Upadhyay <quic_neeraju@quicinc.com>
Mon, 13 Dec 2021 07:00:59 +0000 (12:30 +0530)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Tue, 14 Dec 2021 11:23:16 +0000 (11:23 +0000)
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@quicinc.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
kernel/rcu/tree.c
kernel/rcu/tree.h

index 9284abbcf8b29d7735a70640cc7ad2fbe750d70b..d84754711f2e3de8d9ef9c11aa1f15976a938eab 100644 (file)
@@ -2431,7 +2431,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.
@@ -3693,7 +3693,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;
 }
@@ -4161,7 +4161,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;
 }
index d7785f569a4e6ef5a9543c924d8e2cf3e1570d91..13d8a9d9bb227d2f45fe5ab34b7d04433002ebb1 100644 (file)
@@ -304,7 +304,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. */