Skip to content

Commit 09e077c

Browse files
paulmckrcuurezki
authored andcommitted
rcu: Mark loads from rcu_state.n_online_cpus
The rcu_state.n_online_cpus value is only ever updated by CPU-hotplug operations, which are serialized. However, this value is read locklessly. This commit therefore marks those reads. While in the area, it also adds ASSERT_EXCLUSIVE_WRITER() calls just in case parallel CPU hotplug becomes a thing. Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
1 parent a542d11 commit 09e077c

2 files changed

Lines changed: 7 additions & 3 deletions

File tree

kernel/rcu/tree.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4328,7 +4328,7 @@ EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online);
43284328
// whether spinlocks may be acquired safely.
43294329
static bool rcu_init_invoked(void)
43304330
{
4331-
return !!rcu_state.n_online_cpus;
4331+
return !!READ_ONCE(rcu_state.n_online_cpus);
43324332
}
43334333

43344334
/*
@@ -4538,6 +4538,7 @@ int rcutree_prepare_cpu(unsigned int cpu)
45384538
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
45394539
rcu_spawn_rnp_kthreads(rnp);
45404540
rcu_spawn_cpu_nocb_kthread(cpu);
4541+
ASSERT_EXCLUSIVE_WRITER(rcu_state.n_online_cpus);
45414542
WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus + 1);
45424543

45434544
return 0;
@@ -4806,6 +4807,7 @@ void rcutree_migrate_callbacks(int cpu)
48064807
*/
48074808
int rcutree_dead_cpu(unsigned int cpu)
48084809
{
4810+
ASSERT_EXCLUSIVE_WRITER(rcu_state.n_online_cpus);
48094811
WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus - 1);
48104812
// Stop-machine done, so allow nohz_full to disable tick.
48114813
tick_dep_clear(TICK_DEP_BIT_RCU);

kernel/rcu/tree_stall.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,8 @@ static void print_other_cpu_stall(unsigned long gp_seq, unsigned long gps)
628628
totqlen += rcu_get_n_cbs_cpu(cpu);
629629
pr_err("\t(detected by %d, t=%ld jiffies, g=%ld, q=%lu ncpus=%d)\n",
630630
smp_processor_id(), (long)(jiffies - gps),
631-
(long)rcu_seq_current(&rcu_state.gp_seq), totqlen, rcu_state.n_online_cpus);
631+
(long)rcu_seq_current(&rcu_state.gp_seq), totqlen,
632+
data_race(rcu_state.n_online_cpus)); // Diagnostic read
632633
if (ndetected) {
633634
rcu_dump_cpu_stacks();
634635

@@ -689,7 +690,8 @@ static void print_cpu_stall(unsigned long gps)
689690
totqlen += rcu_get_n_cbs_cpu(cpu);
690691
pr_err("\t(t=%lu jiffies g=%ld q=%lu ncpus=%d)\n",
691692
jiffies - gps,
692-
(long)rcu_seq_current(&rcu_state.gp_seq), totqlen, rcu_state.n_online_cpus);
693+
(long)rcu_seq_current(&rcu_state.gp_seq), totqlen,
694+
data_race(rcu_state.n_online_cpus)); // Diagnostic read
693695

694696
rcu_check_gp_kthread_expired_fqs_timer();
695697
rcu_check_gp_kthread_starvation();

0 commit comments

Comments
 (0)