| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Morten Rasmussen <morten.rasmussen@arm.com> |
| Date: Thu, 2 Jul 2015 17:16:34 +0100 |
| Subject: ANDROID: sched: Prevent unnecessary active balance of single task in |
| sched group |
| |
| Scenarios with the busiest group having just one task and the local |
| being idle on topologies with sched groups with different numbers of |
| cpus manage to dodge all load-balance bailout conditions resulting the |
| nr_balance_failed counter to be incremented. This eventually causes a |
| pointless active migration of the task. This patch prevents this by not |
| incrementing the counter when the busiest group only has one task. |
| ASYM_PACKING migrations and migrations due to reduced capacity should |
| still take place as these are explicitly captured by |
| need_active_balance(). |
| |
| A better solution would be to not attempt the load-balance in the first |
| place, but that requires significant changes to the order of bailout |
| conditions and statistics gathering. |
| |
| Change-Id: I28f69c72febe0211decbe77b7bc3e48839d3d7b3 |
| cc: Ingo Molnar <mingo@redhat.com> |
| cc: Peter Zijlstra <peterz@infradead.org> |
| Signed-off-by: Morten Rasmussen <morten.rasmussen@arm.com> |
| Signed-off-by: Quentin Perret <quentin.perret@arm.com> |
| --- |
| kernel/sched/fair.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c |
| index eeaa334f8832..31b955a3133b 100644 |
| --- a/kernel/sched/fair.c |
| +++ b/kernel/sched/fair.c |
| @@ -7129,6 +7129,7 @@ struct lb_env { |
| int new_dst_cpu; |
| enum cpu_idle_type idle; |
| long imbalance; |
| + unsigned int src_grp_nr_running; |
| /* The set of CPUs under consideration for load-balancing */ |
| struct cpumask *cpus; |
| |
| @@ -8322,6 +8323,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd |
| if (env->sd->flags & SD_NUMA) |
| env->fbq_type = fbq_classify_group(&sds->busiest_stat); |
| |
| + env->src_grp_nr_running = sds->busiest_stat.sum_nr_running; |
| + |
| if (!env->sd->parent) { |
| struct root_domain *rd = env->dst_rq->rd; |
| |
| @@ -9016,7 +9019,8 @@ static int load_balance(int this_cpu, struct rq *this_rq, |
| * excessive cache_hot migrations and active balances. |
| */ |
| if (idle != CPU_NEWLY_IDLE) |
| - sd->nr_balance_failed++; |
| + if (env.src_grp_nr_running > 1) |
| + sd->nr_balance_failed++; |
| |
| if (need_active_balance(&env)) { |
| unsigned long flags; |