Skip to content

Commit 3c8920e

Browse files
Frederic Weisbeckerpaulmckrcu
authored andcommitted
tick/nohz: Narrow down noise while setting current task's tick dependency
Setting a tick dependency on any task, including the case where a task sets that dependency on itself, triggers an IPI to all CPUs. That is of course suboptimal but it had previously not been an issue because it was only used by POSIX CPU timers on nohz_full, which apparently never occurs in latency-sensitive workloads in production. (Or users of such systems are suffering in silence on the one hand or venting their ire on the wrong people on the other.) But RCU now sets a task tick dependency on the current task in order to fix stall issues that can occur during RCU callback processing. Thus, RCU callback processing triggers frequent system-wide IPIs from nohz_full CPUs. This is quite counter-productive, after all, avoiding IPIs is what nohz_full is supposed to be all about. This commit therefore optimizes tasks' self-setting of a task tick dependency by using tick_nohz_full_kick() to avoid the system-wide IPI. Instead, only the execution of the one task is disturbed, which is acceptable given that this disturbance is well down into the noise compared to the degree to which the RCU callback processing itself disturbs execution. Fixes: 6a949b7 (rcu: Force on tick when invoking lots of callbacks) Reported-by: Matt Fleming <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]> Cc: [email protected] Cc: Paul E. McKenney <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 360fbbb commit 3c8920e

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

kernel/time/tick-sched.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,24 @@ void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
351351
EXPORT_SYMBOL_GPL(tick_nohz_dep_clear_cpu);
352352

353353
/*
354-
* Set a per-task tick dependency. Posix CPU timers need this in order to elapse
355-
* per task timers.
354+
* Set a per-task tick dependency. RCU need this. Also posix CPU timers
355+
* in order to elapse per task timers.
356356
*/
357357
void tick_nohz_dep_set_task(struct task_struct *tsk, enum tick_dep_bits bit)
358358
{
359-
/*
360-
* We could optimize this with just kicking the target running the task
361-
* if that noise matters for nohz full users.
362-
*/
363-
tick_nohz_dep_set_all(&tsk->tick_dep_mask, bit);
359+
if (!atomic_fetch_or(BIT(bit), &tsk->tick_dep_mask)) {
360+
if (tsk == current) {
361+
preempt_disable();
362+
tick_nohz_full_kick();
363+
preempt_enable();
364+
} else {
365+
/*
366+
* Some future tick_nohz_full_kick_task()
367+
* should optimize this.
368+
*/
369+
tick_nohz_full_kick_all();
370+
}
371+
}
364372
}
365373
EXPORT_SYMBOL_GPL(tick_nohz_dep_set_task);
366374

0 commit comments

Comments
 (0)