[PATCH 01/10] sched/fair: Do not set_rd_overloaded() if rd->online != env->cpus

From: Xin Zhao

Date: Sat Aug 15 2026 - 07:05:56 EST


In update_sg_lb_stats(), it only traverses sched_group that belongs to
env->cpus, but env->cpus may not necessarily equal rd->online. This can
lead to the incorrect clearing of the overloaded flag of rd. For example,
if cpuA belongs to the online CPU mask of the rd but does not belong to
env->cpus, and cpuA consistently maintains nr_running >= 2, while other
CPUs in rd->online keep rq->nr_running <= 1, the overloaded flag of rd
will not be set until next update of update_sd_lb_stats() for that rd.
During this period, sched_balance_newidle() will prematurely return due to
the incorrect assumption that the rd is in a non-overloaded state.

In update_sd_lb_stats(), add a check to verify whether rd->online is equal
to env->cpus before calling set_rd_overloaded() to avoid such incorrect
settings.

Signed-off-by: Xin Zhao <jackzxcui1989@xxxxxxx>
---
kernel/sched/fair.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index dcf860c59a14..13e873b1ef58 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -12679,8 +12679,12 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
env->fbq_type = fbq_classify_group(&sds->busiest_stat);

if (!env->sd->parent) {
- /* update overload indicator if we are at root domain */
- set_rd_overloaded(env->dst_rq->rd, sg_overloaded);
+ /*
+ * Update overload indicator if we are at root domain.
+ * Note that env->cpus may change during sched_balance_rq().
+ */
+ if (cpumask_equal(env->dst_rq->rd->online, env->cpus))
+ set_rd_overloaded(env->dst_rq->rd, sg_overloaded);

/* Update over-utilization (tipping point, U >= 0) indicator */
set_rd_overutilized(env->dst_rq->rd, sg_overutilized);
--
2.34.1