From 7fd540b1bcaf59289e6e921463037d4eadc1d75b Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Mon, 20 Jul 2026 19:43:21 -0700 Subject: [PATCH] sched/fair: Allow load balancing between CPUs of identical capacity sched_balance_find_src_rq() avoids selecting a runqueue with a single running task as busiest if doing so results in migrating the task to a CPU with less than ~5% of extra capacity. It also unintentionally prevents migrations between CPUs of identical capacity. When CONFIG_SCHED_CLUSTER is enabled, load should be balanced across clusters of CPUs with the same capacity. Allowing migration between CPUs of identical capacity is necessary to meet this goal. Use get_actual_cpu_capacity() to reflect architectural capacity as well as diminished capacity due to hardware or cpufreq pressure. Guard this check with the sched_cluster_active static key so that systems without cluster topology are unaffected. Signed-off-by: Ricardo Neri Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Christian Loehle Reviewed-by: Vincent Guittot Tested-by: Christian Loehle Tested-by: Andrea Righi Link: https://patch.msgid.link/20260720-rneri-fix-cas-clusters-v6-5-bb500bf4afd4@linux.intel.com --- kernel/sched/fair.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index f1b4db36c23b..dcf860c59a14 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -13102,13 +13102,20 @@ static struct rq *sched_balance_find_src_rq(struct lb_env *env, */ if (env->sd->flags & SD_ASYM_CPUCAPACITY && nr_running == 1) { + bool cluster_equal_cap = static_branch_unlikely(&sched_cluster_active) && + (get_actual_cpu_capacity(env->dst_cpu) == + get_actual_cpu_capacity(i)); bool smt_degraded_cap = sched_smt_active() && !is_core_idle(i); /* * Busy SMT siblings reduce the capacity of CPU @i. Do * not skip it in this case. + * + * CONFIG_SCHED_CLUSTER requires balancing load across + * clusters of identical capacity, accounting for + * hardware and cpufreq pressure. */ - if (!smt_degraded_cap && + if (!smt_degraded_cap && !cluster_equal_cap && !capacity_greater(capacity_of(env->dst_cpu), capacity)) continue; }