diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 2fe25a61ba76..dc342f8094c2 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -8061,6 +8061,19 @@ group_smaller_max_cpu_capacity(struct sched_group *sg, struct sched_group *ref) return fits_capacity(sg->sgc->max_capacity, ref->sgc->max_capacity); } +/* + * group_similar_cpu_capacity: Returns true if the minimum capacity of the + * compared groups differ by less than 12.5%. + */ +static inline bool +group_similar_cpu_capacity(struct sched_group *sg, struct sched_group *ref) +{ + long diff = sg->sgc->min_capacity - ref->sgc->min_capacity; + long max = max(sg->sgc->min_capacity, ref->sgc->min_capacity); + + return abs(diff) < max >> 3; +} + static inline enum group_type group_classify(struct sched_group *group, struct sg_lb_stats *sgs) @@ -8215,6 +8228,15 @@ static bool update_sd_pick_busiest(struct lb_env *env, group_smaller_min_cpu_capacity(sds->local, sg)) return false; + /* + * Candidate sg doesn't face any severe imbalance issues so + * don't disturb unless the groups are of similar capacity + * where balancing is more harmless. + */ + if (sgs->group_type == group_other && + !group_similar_cpu_capacity(sds->local, sg)) + return false; + /* * If we have more than one misfit sg go with the biggest misfit. */