Skip to content

Commit 842b119

Browse files
committed
NVIDIA: SAUCE: sched/fair: Reject misfit pulls onto busy SMT siblings on asym-capacity
When SD_ASYM_CPUCAPACITY load balancing considers pulling a misfit task, capacity_of(dst_cpu) can overstate available compute if the SMT sibling is busy: the core does not deliver its full nominal capacity. If SMT is active and dst_cpu is not on a fully idle core, skip this destination so we do not migrate a misfit expecting a capacity upgrade we cannot actually provide. Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> Cc: Christian Loehle <christian.loehle@arm.com> Cc: Koba Ko <kobak@nvidia.com> Cc: K Prateek Nayak <kprateek.nayak@amd.com> Reported-by: Felix Abecassis <fabecassis@nvidia.com> Signed-off-by: Andrea Righi <arighi@nvidia.com> (cherry picked from https://lore.kernel.org/all/20260428051720.3180182-1-arighi@nvidia.com) Signed-off-by: Andrea Righi <arighi@nvidia.com>
1 parent 20f85dc commit 842b119

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

kernel/sched/fair.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9153,6 +9153,7 @@ struct lb_env {
91539153

91549154
int dst_cpu;
91559155
struct rq *dst_rq;
9156+
bool dst_core_idle;
91569157

91579158
struct cpumask *dst_grpmask;
91589159
int new_dst_cpu;
@@ -10394,10 +10395,16 @@ static bool update_sd_pick_busiest(struct lb_env *env,
1039410395
* We can use max_capacity here as reduction in capacity on some
1039510396
* CPUs in the group should either be possible to resolve
1039610397
* internally or be covered by avg_load imbalance (eventually).
10398+
*
10399+
* When SMT is active, only pull a misfit to dst_cpu if it is on a
10400+
* fully idle core; otherwise the effective capacity of the core is
10401+
* reduced and we may not actually provide more capacity than the
10402+
* source.
1039710403
*/
1039810404
if ((env->sd->flags & SD_ASYM_CPUCAPACITY) &&
1039910405
(sgs->group_type == group_misfit_task) &&
10400-
(!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
10406+
(!env->dst_core_idle ||
10407+
!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
1040110408
sds->local_stat.group_type != group_has_spare))
1040210409
return false;
1040310410

@@ -10964,6 +10971,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
1096410971
unsigned long sum_util = 0;
1096510972
bool sg_overloaded = 0, sg_overutilized = 0;
1096610973

10974+
env->dst_core_idle = !sched_smt_active() || is_core_idle(env->dst_cpu);
10975+
1096710976
do {
1096810977
struct sg_lb_stats *sgs = &tmp_sgs;
1096910978
int local_group;

0 commit comments

Comments
 (0)