Skip to content

Commit a554ba2

Browse files
Frederic Weisbeckerpaulmckrcu
authored andcommitted
rcu: Apply callbacks processing time limit only on softirq
Time limit only makes sense when callbacks are serviced in softirq mode because: _ In case we need to get back to the scheduler, cond_resched_tasks_rcu_qs() is called after each callback. _ In case some other softirq vector needs the CPU, the call to local_bh_enable() before cond_resched_tasks_rcu_qs() takes care about them via a call to do_softirq(). Therefore, make sure the time limit only applies to softirq mode. Reviewed-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Cc: Valentin Schneider <valentin.schneider@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Josh Triplett <josh@joshtriplett.org> Cc: Joel Fernandes <joel@joelfernandes.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Neeraj Upadhyay <neeraju@codeaurora.org> Cc: Uladzislau Rezki <urezki@gmail.com> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
1 parent 3e61e95 commit a554ba2

1 file changed

Lines changed: 12 additions & 13 deletions

File tree

kernel/rcu/tree.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,7 +2488,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
24882488
div = READ_ONCE(rcu_divisor);
24892489
div = div < 0 ? 7 : div > sizeof(long) * 8 - 2 ? sizeof(long) * 8 - 2 : div;
24902490
bl = max(rdp->blimit, pending >> div);
2491-
if (unlikely(bl > 100)) {
2491+
if (in_serving_softirq() && unlikely(bl > 100)) {
24922492
long rrn = READ_ONCE(rcu_resched_ns);
24932493

24942494
rrn = rrn < NSEC_PER_MSEC ? NSEC_PER_MSEC : rrn > NSEC_PER_SEC ? NSEC_PER_SEC : rrn;
@@ -2528,25 +2528,24 @@ static void rcu_do_batch(struct rcu_data *rdp)
25282528
if (in_serving_softirq()) {
25292529
if (count >= bl && (need_resched() || !is_idle_task(current)))
25302530
break;
2531+
/*
2532+
* Make sure we don't spend too much time here and deprive other
2533+
* softirq vectors of CPU cycles.
2534+
*/
2535+
if (unlikely(tlimit)) {
2536+
/* only call local_clock() every 32 callbacks */
2537+
if (likely((count & 31) || local_clock() < tlimit))
2538+
continue;
2539+
/* Exceeded the time limit, so leave. */
2540+
break;
2541+
}
25312542
} else {
25322543
local_bh_enable();
25332544
lockdep_assert_irqs_enabled();
25342545
cond_resched_tasks_rcu_qs();
25352546
lockdep_assert_irqs_enabled();
25362547
local_bh_disable();
25372548
}
2538-
2539-
/*
2540-
* Make sure we don't spend too much time here and deprive other
2541-
* softirq vectors of CPU cycles.
2542-
*/
2543-
if (unlikely(tlimit)) {
2544-
/* only call local_clock() every 32 callbacks */
2545-
if (likely((count & 31) || local_clock() < tlimit))
2546-
continue;
2547-
/* Exceeded the time limit, so leave. */
2548-
break;
2549-
}
25502549
}
25512550

25522551
rcu_nocb_lock_irqsave(rdp, flags);

0 commit comments

Comments
 (0)