If big CPU has been already busy (halfutilized for <= 2 tasks, or overutilized for > 2 tasks), then it's pointless to migrate a big task from little CPU to big CPU. Otherwise it will introduce big CPU over-utilized and finally want to spread out tasks cross two clusters.
So this patch is avoid single big task migration for busy big CPU.
Signed-off-by: Leo Yan leo.yan@linaro.org --- kernel/sched/fair.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9ac593b..d403816 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5339,6 +5339,34 @@ static bool need_spread_task(int cpu) return spread; }
+static bool need_want_affine(struct task_struct *p, int cpu) +{ + int capacity = capacity_orig_of(cpu); + int max_capacity = cpu_rq(cpu)->rd->max_cpu_capacity.val; + unsigned long margin = schedtune_task_margin(p); + struct sched_domain *sd; + int affine = 0, i; + + if (margin) + return 1; + + if (capacity != max_capacity) + return 1; + + sd = rcu_dereference_check_sched_domain(cpu_rq(cpu)->sd); + if (!sd) + return 1; + + for_each_cpu(i, sched_domain_span(sd)) { + if (idle_cpu(i)) { + affine = 1; + break; + } + } + + return affine; +} + static bool need_filter_task(struct task_struct *p) { int cpu = task_cpu(p); @@ -5972,7 +6000,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f if (sd_flag & SD_BALANCE_WAKE) want_affine = (!wake_wide(p) && task_fits_max(p, cpu) && cpumask_test_cpu(cpu, tsk_cpus_allowed(p))) || - energy_aware(); + (energy_aware() && need_want_affine(p, cpu));
rcu_read_lock(); for_each_domain(cpu, tmp) { @@ -8143,9 +8171,14 @@ static int need_active_balance(struct lb_env *env)
if ((capacity_orig_of(env->src_cpu) < capacity_orig_of(env->dst_cpu)) && env->src_rq->cfs.h_nr_running == 1 && - cpu_overutilized(env->src_cpu) && - !cpu_overutilized(env->dst_cpu)) - return 1; + cpu_overutilized(env->src_cpu)) { + + if (idle_cpu(env->dst_cpu)) + return 1; + + if (!idle_cpu(env->dst_cpu) && !cpu_overutilized(env->dst_cpu)) + return 1; + }
return unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2); } -- 1.9.1