Skip to content

Commit

Permalink
Merge tag 'rcu-urgent.2022.10.20a' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/paulmck/linux-rcu

Pull RCU fix from Paul McKenney:
 "Fix a regression caused by commit bf95b2b ("rcu: Switch polled
  grace-period APIs to ->gp_seq_polled"), which could incorrectly leave
  interrupts enabled after an early-boot call to synchronize_rcu().

  Such synchronize_rcu() calls must acquire leaf rcu_node locks in order
  to properly interact with polled grace periods, but the code did not
  take into account the possibility of synchronize_rcu() being invoked
  from the portion of the boot sequence during which interrupts are
  disabled.

  This commit therefore switches the lock acquisition and release from
  irq to irqsave/irqrestore"

* tag 'rcu-urgent.2022.10.20a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
  rcu: Keep synchronize_rcu() from enabling irqs in early boot
  • Loading branch information
Linus Torvalds committed Oct 24, 2022
2 parents 2a91e89 + 31d8aaa commit f6602a9
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions kernel/rcu/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,30 +1403,32 @@ static void rcu_poll_gp_seq_end(unsigned long *snap)
// where caller does not hold the root rcu_node structure's lock.
static void rcu_poll_gp_seq_start_unlocked(unsigned long *snap)
{
unsigned long flags;
struct rcu_node *rnp = rcu_get_root();

if (rcu_init_invoked()) {
lockdep_assert_irqs_enabled();
raw_spin_lock_irq_rcu_node(rnp);
raw_spin_lock_irqsave_rcu_node(rnp, flags);
}
rcu_poll_gp_seq_start(snap);
if (rcu_init_invoked())
raw_spin_unlock_irq_rcu_node(rnp);
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
}

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

if (rcu_init_invoked()) {
lockdep_assert_irqs_enabled();
raw_spin_lock_irq_rcu_node(rnp);
raw_spin_lock_irqsave_rcu_node(rnp, flags);
}
rcu_poll_gp_seq_end(snap);
if (rcu_init_invoked())
raw_spin_unlock_irq_rcu_node(rnp);
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
}

/*
Expand Down

0 comments on commit f6602a9

Please sign in to comment.