Skip to content

Commit

Permalink
rcu: decrease rcu_report_exp_rnp coupling with scheduler
Browse files Browse the repository at this point in the history
PREEMPT_RCU read-side critical sections blocking an expedited grace
period invoke rcu_report_exp_rnp().  When the last such critical section
has completed, rcu_report_exp_rnp() invokes the scheduler to wake up the
task that invoked synchronize_rcu_expedited() -- needlessly holding the
root rcu_node structure's lock while doing so, thus needlessly providing
a way for RCU and the scheduler to deadlock.

This commit therefore releases the root rcu_node structure's lock before
calling wake_up().

Reported-by: Ed Tomlinson <[email protected]>
Signed-off-by: Paul E. McKenney <[email protected]>
  • Loading branch information
paulmck committed Jul 20, 2011
1 parent b0d3041 commit 131906b
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions kernel/rcutree_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,9 +695,12 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)

raw_spin_lock_irqsave(&rnp->lock, flags);
for (;;) {
if (!sync_rcu_preempt_exp_done(rnp))
if (!sync_rcu_preempt_exp_done(rnp)) {
raw_spin_unlock_irqrestore(&rnp->lock, flags);
break;
}
if (rnp->parent == NULL) {
raw_spin_unlock_irqrestore(&rnp->lock, flags);
wake_up(&sync_rcu_preempt_exp_wq);
break;
}
Expand All @@ -707,7 +710,6 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
raw_spin_lock(&rnp->lock); /* irqs already disabled */
rnp->expmask &= ~mask;
}
raw_spin_unlock_irqrestore(&rnp->lock, flags);
}

/*
Expand Down

0 comments on commit 131906b

Please sign in to comment.