aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/core.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 36f85be2932b..d8f071cc9f51 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -633,7 +633,19 @@ void wake_up_nohz_cpu(int cpu)
633static inline bool got_nohz_idle_kick(void) 633static inline bool got_nohz_idle_kick(void)
634{ 634{
635 int cpu = smp_processor_id(); 635 int cpu = smp_processor_id();
636 return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)); 636
637 if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)))
638 return false;
639
640 if (idle_cpu(cpu) && !need_resched())
641 return true;
642
643 /*
644 * We can't run Idle Load Balance on this CPU for this time so we
645 * cancel it and clear NOHZ_BALANCE_KICK
646 */
647 clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
648 return false;
637} 649}
638 650
639#else /* CONFIG_NO_HZ_COMMON */ 651#else /* CONFIG_NO_HZ_COMMON */
@@ -1395,8 +1407,9 @@ static void sched_ttwu_pending(void)
1395 1407
1396void scheduler_ipi(void) 1408void scheduler_ipi(void)
1397{ 1409{
1398 if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick() 1410 if (llist_empty(&this_rq()->wake_list)
1399 && !tick_nohz_full_cpu(smp_processor_id())) 1411 && !tick_nohz_full_cpu(smp_processor_id())
1412 && !got_nohz_idle_kick())
1400 return; 1413 return;
1401 1414
1402 /* 1415 /*
@@ -1419,7 +1432,7 @@ void scheduler_ipi(void)
1419 /* 1432 /*
1420 * Check if someone kicked us for doing the nohz idle load balance. 1433 * Check if someone kicked us for doing the nohz idle load balance.
1421 */ 1434 */
1422 if (unlikely(got_nohz_idle_kick() && !need_resched())) { 1435 if (unlikely(got_nohz_idle_kick())) {
1423 this_rq()->idle_balance = 1; 1436 this_rq()->idle_balance = 1;
1424 raise_softirq_irqoff(SCHED_SOFTIRQ); 1437 raise_softirq_irqoff(SCHED_SOFTIRQ);
1425 } 1438 }