Skip to content

Commit 54b55b5

Browse files
joelagnelpaulmckrcu
authored andcommitted
rcu: Fix late wakeup when flush of bypass cblist happens (v6)
When the bypass cblist gets too big or its timeout has occurred, it is flushed into the main cblist. However, the bypass timer is still running and the behavior is that it would eventually expire and wake the GP thread. Since we are going to use the bypass cblist for lazy CBs, do the wakeup soon as the flush for "too big or too long" bypass list happens. Otherwise, long delays can happen for callbacks which get promoted from lazy to non-lazy. This is a good thing to do anyway (regardless of future lazy patches), since it makes the behavior consistent with behavior of other code paths where flushing into the ->cblist makes the GP kthread into a non-sleeping state quickly. [ Frederic Weisbec: changes to not do wake up GP thread unless needed, comment changes ]. Reviewed-by: Frederic Weisbecker <[email protected]> Signed-off-by: Joel Fernandes (Google) <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent dbef46a commit 54b55b5

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

kernel/rcu/tree_nocb.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,9 @@ static bool rcu_nocb_try_bypass(struct rcu_data *rdp, struct rcu_head *rhp,
433433
if ((ncbs && j != READ_ONCE(rdp->nocb_bypass_first)) ||
434434
ncbs >= qhimark) {
435435
rcu_nocb_lock(rdp);
436+
*was_alldone = !rcu_segcblist_pend_cbs(&rdp->cblist);
437+
436438
if (!rcu_nocb_flush_bypass(rdp, rhp, j)) {
437-
*was_alldone = !rcu_segcblist_pend_cbs(&rdp->cblist);
438439
if (*was_alldone)
439440
trace_rcu_nocb_wake(rcu_state.name, rdp->cpu,
440441
TPS("FirstQ"));
@@ -447,7 +448,12 @@ static bool rcu_nocb_try_bypass(struct rcu_data *rdp, struct rcu_head *rhp,
447448
rcu_advance_cbs_nowake(rdp->mynode, rdp);
448449
rdp->nocb_gp_adv_time = j;
449450
}
450-
rcu_nocb_unlock_irqrestore(rdp, flags);
451+
452+
// The flush succeeded and we moved CBs into the regular list.
453+
// Don't wait for the wake up timer as it may be too far ahead.
454+
// Wake up the GP thread now instead, if the cblist was empty.
455+
__call_rcu_nocb_wake(rdp, *was_alldone, flags);
456+
451457
return true; // Callback already enqueued.
452458
}
453459

0 commit comments

Comments
 (0)