mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 13:43:51 +00:00
rcu: Permit start_poll_synchronize_rcu_expedited() to be invoked early
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>
This commit is contained in:
parent
46103fe01b
commit
7ea91307ad
@ -4942,9 +4942,8 @@ void __init rcu_init(void)
|
|||||||
else
|
else
|
||||||
qovld_calc = qovld;
|
qovld_calc = qovld;
|
||||||
|
|
||||||
// Kick-start any polled grace periods that started early.
|
// Kick-start in case any polled grace periods started early.
|
||||||
if (!(per_cpu_ptr(&rcu_data, cpu)->mynode->exp_seq_poll_rq & 0x1))
|
(void)start_poll_synchronize_rcu_expedited();
|
||||||
(void)start_poll_synchronize_rcu_expedited();
|
|
||||||
|
|
||||||
rcu_test_sync_prims();
|
rcu_test_sync_prims();
|
||||||
}
|
}
|
||||||
|
@ -1066,9 +1066,10 @@ unsigned long start_poll_synchronize_rcu_expedited(void)
|
|||||||
if (rcu_init_invoked())
|
if (rcu_init_invoked())
|
||||||
raw_spin_lock_irqsave(&rnp->exp_poll_lock, flags);
|
raw_spin_lock_irqsave(&rnp->exp_poll_lock, flags);
|
||||||
if (!poll_state_synchronize_rcu(s)) {
|
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);
|
queue_work(rcu_gp_wq, &rnp->exp_poll_wq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rcu_init_invoked())
|
if (rcu_init_invoked())
|
||||||
raw_spin_unlock_irqrestore(&rnp->exp_poll_lock, flags);
|
raw_spin_unlock_irqrestore(&rnp->exp_poll_lock, flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user