[PATCH 01/10] sched/fair: Do not set_rd_overloaded() if rd->online != env->cpus
Xin Zhao <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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