diff options
Diffstat (limited to 'kernel/sched/idle.c')
-rw-r--r-- | kernel/sched/idle.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index ac6d5176463d..f0b1548d6c22 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -208,6 +208,9 @@ exit_idle: */ static void do_idle(void) { + int cpu = smp_processor_id(); + bool pending = false; + /* * If the arch has a polling bit, we maintain an invariant: * @@ -218,13 +221,16 @@ static void do_idle(void) */ __current_set_polling(); - tick_nohz_idle_enter(); + if (unlikely(softirq_pending(cpu))) + pending = true; + else + tick_nohz_idle_enter(); while (!need_resched()) { check_pgt_cache(); rmb(); - if (cpu_is_offline(smp_processor_id())) { + if (cpu_is_offline(cpu)) { cpuhp_report_idle_dead(); arch_cpu_idle_dead(); } @@ -253,7 +259,8 @@ static void do_idle(void) * an IPI to fold the state for us. */ preempt_set_need_resched(); - tick_nohz_idle_exit(); + if (!pending) + tick_nohz_idle_exit(); __current_clr_polling(); /* |