sched: ratelimit nohz Entering nohz code on every micro-idle is too expensive to bear. Signed-off-by: Mike Galbraith --- include/linux/sched.h | 5 +++++ kernel/sched/core.c | 8 ++++++++ kernel/time/tick-sched.c | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2286,6 +2286,11 @@ static inline int set_cpus_allowed_ptr(s #ifdef CONFIG_NO_HZ_COMMON void calc_load_enter_idle(void); void calc_load_exit_idle(void); +#ifdef CONFIG_SMP +extern int sched_needs_cpu(int cpu); +#else +static inline int sched_needs_cpu(int cpu) { return 0; } +#endif #else static inline void calc_load_enter_idle(void) { } static inline void calc_load_exit_idle(void) { } --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -577,6 +577,14 @@ static inline bool got_nohz_idle_kick(vo return false; } +int sched_needs_cpu(int cpu) +{ + if (tick_nohz_full_cpu(cpu)) + return 0; + + return cpu_rq(cpu)->avg_idle < sysctl_sched_migration_cost; +} + #else /* CONFIG_NO_HZ_COMMON */ static inline bool got_nohz_idle_kick(void) --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -676,7 +676,7 @@ static ktime_t tick_nohz_stop_sched_tick } while (read_seqretry(&jiffies_lock, seq)); ts->last_jiffies = basejiff; - if (rcu_needs_cpu(basemono, &next_rcu) || + if (sched_needs_cpu(cpu) || rcu_needs_cpu(basemono, &next_rcu) || arch_needs_cpu() || irq_work_needs_cpu()) { next_tick = basemono + TICK_NSEC; } else {