Skip to content

Commit 31d8aaa

Browse files
committed
rcu: Keep synchronize_rcu() from enabling irqs in early boot
Making polled RCU grace periods account for expedited grace periods required acquiring the leaf rcu_node structure's lock during early boot, but after rcu_init() was called. This lock is irq-disabled, but the code incorrectly assumes that irqs are always disabled when invoking synchronize_rcu(). The exception is early boot before the scheduler has started, which means that upon return from synchronize_rcu(), irqs will be incorrectly enabled. This commit fixes this bug by using irqsave/irqrestore locking primitives. Fixes: bf95b2b ("rcu: Switch polled grace-period APIs to ->gp_seq_polled") Reported-by: Steven Rostedt <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 9abf231 commit 31d8aaa

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

kernel/rcu/tree.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,30 +1403,32 @@ static void rcu_poll_gp_seq_end(unsigned long *snap)
14031403
// where caller does not hold the root rcu_node structure's lock.
14041404
static void rcu_poll_gp_seq_start_unlocked(unsigned long *snap)
14051405
{
1406+
unsigned long flags;
14061407
struct rcu_node *rnp = rcu_get_root();
14071408

14081409
if (rcu_init_invoked()) {
14091410
lockdep_assert_irqs_enabled();
1410-
raw_spin_lock_irq_rcu_node(rnp);
1411+
raw_spin_lock_irqsave_rcu_node(rnp, flags);
14111412
}
14121413
rcu_poll_gp_seq_start(snap);
14131414
if (rcu_init_invoked())
1414-
raw_spin_unlock_irq_rcu_node(rnp);
1415+
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
14151416
}
14161417

14171418
// Make the polled API aware of the end of a grace period, but where
14181419
// caller does not hold the root rcu_node structure's lock.
14191420
static void rcu_poll_gp_seq_end_unlocked(unsigned long *snap)
14201421
{
1422+
unsigned long flags;
14211423
struct rcu_node *rnp = rcu_get_root();
14221424

14231425
if (rcu_init_invoked()) {
14241426
lockdep_assert_irqs_enabled();
1425-
raw_spin_lock_irq_rcu_node(rnp);
1427+
raw_spin_lock_irqsave_rcu_node(rnp, flags);
14261428
}
14271429
rcu_poll_gp_seq_end(snap);
14281430
if (rcu_init_invoked())
1429-
raw_spin_unlock_irq_rcu_node(rnp);
1431+
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
14301432
}
14311433

14321434
/*

0 commit comments

Comments
 (0)