summaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 4cdc91cf48f6..9e49af00ae3e 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1404,6 +1404,18 @@ void wake_up_idle_cpu(int cpu)
1404 smp_send_reschedule(cpu); 1404 smp_send_reschedule(cpu);
1405} 1405}
1406 1406
1407static inline bool got_nohz_idle_kick(void)
1408{
1409 return idle_cpu(smp_processor_id()) && this_rq()->nohz_balance_kick;
1410}
1411
1412#else /* CONFIG_NO_HZ */
1413
1414static inline bool got_nohz_idle_kick(void)
1415{
1416 return false;
1417}
1418
1407#endif /* CONFIG_NO_HZ */ 1419#endif /* CONFIG_NO_HZ */
1408 1420
1409static u64 sched_avg_period(void) 1421static u64 sched_avg_period(void)
@@ -2717,7 +2729,7 @@ static void sched_ttwu_pending(void)
2717 2729
2718void scheduler_ipi(void) 2730void scheduler_ipi(void)
2719{ 2731{
2720 if (llist_empty(&this_rq()->wake_list)) 2732 if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick())
2721 return; 2733 return;
2722 2734
2723 /* 2735 /*
@@ -2735,6 +2747,12 @@ void scheduler_ipi(void)
2735 */ 2747 */
2736 irq_enter(); 2748 irq_enter();
2737 sched_ttwu_pending(); 2749 sched_ttwu_pending();
2750
2751 /*
2752 * Check if someone kicked us for doing the nohz idle load balance.
2753 */
2754 if (unlikely(got_nohz_idle_kick() && !need_resched()))
2755 raise_softirq_irqoff(SCHED_SOFTIRQ);
2738 irq_exit(); 2756 irq_exit();
2739} 2757}
2740 2758
@@ -8288,7 +8306,6 @@ void __init sched_init(void)
8288 rq_attach_root(rq, &def_root_domain); 8306 rq_attach_root(rq, &def_root_domain);
8289#ifdef CONFIG_NO_HZ 8307#ifdef CONFIG_NO_HZ
8290 rq->nohz_balance_kick = 0; 8308 rq->nohz_balance_kick = 0;
8291 init_sched_softirq_csd(&per_cpu(remote_sched_softirq_cb, i));
8292#endif 8309#endif
8293#endif 8310#endif
8294 init_rq_hrtick(rq); 8311 init_rq_hrtick(rq);