|
@@ -633,7 +633,19 @@ void wake_up_nohz_cpu(int cpu)
|
|
|
static inline bool got_nohz_idle_kick(void)
|
|
|
{
|
|
|
int cpu = smp_processor_id();
|
|
|
- return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
|
|
|
+
|
|
|
+ if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (idle_cpu(cpu) && !need_resched())
|
|
|
+ return true;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We can't run Idle Load Balance on this CPU for this time so we
|
|
|
+ * cancel it and clear NOHZ_BALANCE_KICK
|
|
|
+ */
|
|
|
+ clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
#else /* CONFIG_NO_HZ_COMMON */
|
|
@@ -1393,8 +1405,9 @@ static void sched_ttwu_pending(void)
|
|
|
|
|
|
void scheduler_ipi(void)
|
|
|
{
|
|
|
- if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()
|
|
|
- && !tick_nohz_full_cpu(smp_processor_id()))
|
|
|
+ if (llist_empty(&this_rq()->wake_list)
|
|
|
+ && !tick_nohz_full_cpu(smp_processor_id())
|
|
|
+ && !got_nohz_idle_kick())
|
|
|
return;
|
|
|
|
|
|
/*
|
|
@@ -1417,7 +1430,7 @@ void scheduler_ipi(void)
|
|
|
/*
|
|
|
* Check if someone kicked us for doing the nohz idle load balance.
|
|
|
*/
|
|
|
- if (unlikely(got_nohz_idle_kick() && !need_resched())) {
|
|
|
+ if (unlikely(got_nohz_idle_kick())) {
|
|
|
this_rq()->idle_balance = 1;
|
|
|
raise_softirq_irqoff(SCHED_SOFTIRQ);
|
|
|
}
|