By moving the call to update_blocked_averages outside of rebalance_domains, we can avoid the use of CPU_MAX_IDLE_TYPES as a marker for aborting the load balance.
Vincent, if you agree with this I'll squash it into the parent before posting to LKML --- kernel/sched/fair.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index cf27fa6548af..9085caf49c76 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -8816,19 +8816,6 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle) int need_serialize, need_decay = 0; u64 max_cost = 0;
- update_blocked_averages(cpu); - -#ifdef CONFIG_NO_HZ_COMMON - if ((idle == CPU_MAX_IDLE_TYPES) || - test_bit(NOHZ_STATS_KICK, nohz_flags(cpu))) { - /* - * We only want to update blocked load and shares which has - * just been done above - */ - return; - } -#endif - rcu_read_lock(); for_each_domain(cpu, sd) { /* @@ -8954,15 +8941,6 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) nohz.next_update = jiffies + msecs_to_jiffies(LOAD_AVG_PERIOD); rcu_read_unlock();
- /* - * This idle load balance softirq has been triggered only to update the - * blocked load and shares of ilde CPUs. Set the idle state to an - * undefined state to the load balance will be aborted just after the - * update of blocked load - */ - if (test_bit(NOHZ_STATS_KICK, nohz_flags(this_cpu))) - idle = CPU_MAX_IDLE_TYPES; - for_each_cpu(balance_cpu, nohz.idle_cpus_mask) { if (balance_cpu == this_cpu || !idle_cpu(balance_cpu)) continue; @@ -8989,7 +8967,15 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) cpu_load_update_idle(rq); rq_unlock_irq(rq, &rf);
- rebalance_domains(rq, idle); + update_blocked_averages(balance_cpu); + /* + * This idle load balance softirq may have been + * triggered only to update the blocked load and shares + * of idle CPUs (which we have just done for + * balance_cpu). In that case skip the actual balance. + */ + if (!test_bit(NOHZ_STATS_KICK, nohz_flags(this_cpu))) + rebalance_domains(rq, idle); }
if (time_after(next_balance, rq->next_balance)) { @@ -9123,7 +9109,9 @@ static __latent_entropy void run_rebalance_domains(struct softirq_action *h) * and abort nohz_idle_balance altogether if we pull some load. */ nohz_idle_balance(this_rq, idle); - rebalance_domains(this_rq, idle); + update_blocked_averages(this_rq->cpu); + if (!test_bit(NOHZ_STATS_KICK, nohz_flags(this_rq->cpu))) + rebalance_domains(this_rq, idle); #ifdef CONFIG_NO_HZ_COMMON clear_bit(NOHZ_STATS_KICK, nohz_flags(this_rq->cpu)); #endif -- 2.14.1