diff --git a/kernel/sched/walt/walt_cfs.c b/kernel/sched/walt/walt_cfs.c index c077627ad963..9da4028c52af 100644 --- a/kernel/sched/walt/walt_cfs.c +++ b/kernel/sched/walt/walt_cfs.c @@ -213,6 +213,17 @@ enum fastpaths { PREV_CPU_FASTPATH, }; +static inline bool is_complex_sibling_idle(int cpu) +{ + if (is_min_capacity_cpu(cpu)) { + if (cpu % 2) + return available_idle_cpu(cpu - 1); + return available_idle_cpu(cpu + 1); + } + + return false; +} + static void walt_find_best_target(struct sched_domain *sd, cpumask_t *candidates, struct task_struct *p, @@ -266,6 +277,8 @@ static void walt_find_best_target(struct sched_domain *sd, for (cluster = 0; cluster < num_sched_clusters; cluster++) { int best_idle_cpu_cluster = -1; int target_cpu_cluster = -1; + int this_complex_idle = 0; + int best_complex_idle = 0; target_max_spare_cap = 0; min_exit_latency = INT_MAX; @@ -349,6 +362,10 @@ static void walt_find_best_target(struct sched_domain *sd, if (available_idle_cpu(i)) { idle_exit_latency = walt_get_idle_exit_latency(cpu_rq(i)); + this_complex_idle = is_complex_sibling_idle(i) ? 1 : 0; + + if (this_complex_idle < best_complex_idle) + continue; /* * Prefer shallowest over deeper idle state cpu, * of same capacity cpus. @@ -366,6 +383,7 @@ static void walt_find_best_target(struct sched_domain *sd, min_exit_latency = idle_exit_latency; best_idle_cuml_util = new_util_cuml; best_idle_cpu_cluster = i; + best_complex_idle = this_complex_idle; continue; }