rcu: Permit start_poll_synchronize_rcu_expedited() to be invoked early
authorZqiang <qiang1.zhang@intel.com>
Thu, 12 Jan 2023 18:48:29 +0000 (10:48 -0800)
committerJoel Fernandes (Google) <joel@joelfernandes.org>
Wed, 5 Apr 2023 13:47:44 +0000 (13:47 +0000)
According to the commit log of the patch that added it to the kernel,
start_poll_synchronize_rcu_expedited() can be invoked very early, as
in long before rcu_init() has been invoked.  But before rcu_init(),
the rcu_data structure's ->mynode field has not yet been initialized.
This means that the start_poll_synchronize_rcu_expedited() function's
attempt to set the CPU's leaf rcu_node structure's ->exp_seq_poll_rq
field will result in a segmentation fault.

This commit therefore causes start_poll_synchronize_rcu_expedited() to
set ->exp_seq_poll_rq only after rcu_init() has initialized all CPUs'
rcu_data structures' ->mynode fields.  It also removes the check from
the rcu_init() function so that start_poll_synchronize_rcu_expedited(
is unconditionally invoked.  Yes, this might result in an unnecessary
boot-time grace period, but this is down in the noise.

Signed-off-by: Zqiang <qiang1.zhang@intel.com>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
kernel/rcu/tree.c
kernel/rcu/tree_exp.h

index e80e8f128c57f4acbc5f3ab1d549edbe0a806554..90d54571126a26b35d747a2eecbd78e0f8d5b1a0 100644 (file)
@@ -4942,9 +4942,8 @@ void __init rcu_init(void)
        else
                qovld_calc = qovld;
 
-       // Kick-start any polled grace periods that started early.
-       if (!(per_cpu_ptr(&rcu_data, cpu)->mynode->exp_seq_poll_rq & 0x1))
-               (void)start_poll_synchronize_rcu_expedited();
+       // Kick-start in case any polled grace periods started early.
+       (void)start_poll_synchronize_rcu_expedited();
 
        rcu_test_sync_prims();
 }
index 7cc4856da0817c35d6292e6e55c0fbc095c5c20e..5343f32e7d67e1d445b3fd6b0acc76e60c2b20df 100644 (file)
@@ -1066,9 +1066,10 @@ unsigned long start_poll_synchronize_rcu_expedited(void)
        if (rcu_init_invoked())
                raw_spin_lock_irqsave(&rnp->exp_poll_lock, flags);
        if (!poll_state_synchronize_rcu(s)) {
-               rnp->exp_seq_poll_rq = s;
-               if (rcu_init_invoked())
+               if (rcu_init_invoked()) {
+                       rnp->exp_seq_poll_rq = s;
                        queue_work(rcu_gp_wq, &rnp->exp_poll_wq);
+               }
        }
        if (rcu_init_invoked())
                raw_spin_unlock_irqrestore(&rnp->exp_poll_lock, flags);