Skip to content

Commit 55e068e

Browse files
committed
NVIDIA: VR: SAUCE: sched/fair: Reject misfit pulls onto busy SMT siblings on asym-capacity
BugLink: https://bugs.launchpad.net/bugs/2150671 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 42459d4 commit 55e068e

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
@@ -9390,6 +9390,7 @@ struct lb_env {
93909390

93919391
int dst_cpu;
93929392
struct rq *dst_rq;
9393+
bool dst_core_idle;
93939394

93949395
struct cpumask *dst_grpmask;
93959396
int new_dst_cpu;
@@ -10635,10 +10636,16 @@ static bool update_sd_pick_busiest(struct lb_env *env,
1063510636
* We can use max_capacity here as reduction in capacity on some
1063610637
* CPUs in the group should either be possible to resolve
1063710638
* internally or be covered by avg_load imbalance (eventually).
10639+
*
10640+
* When SMT is active, only pull a misfit to dst_cpu if it is on a
10641+
* fully idle core; otherwise the effective capacity of the core is
10642+
* reduced and we may not actually provide more capacity than the
10643+
* source.
1063810644
*/
1063910645
if ((env->sd->flags & SD_ASYM_CPUCAPACITY) &&
1064010646
(sgs->group_type == group_misfit_task) &&
10641-
(!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
10647+
(!env->dst_core_idle ||
10648+
!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
1064210649
sds->local_stat.group_type != group_has_spare))
1064310650
return false;
1064410651

@@ -11204,6 +11211,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
1120411211
unsigned long sum_util = 0;
1120511212
bool sg_overloaded = 0, sg_overutilized = 0;
1120611213

11214+
env->dst_core_idle = !sched_smt_active() || is_core_idle(env->dst_cpu);
11215+
1120711216
do {
1120811217
struct sg_lb_stats *sgs = &tmp_sgs;
1120911218
int local_group;

0 commit comments

Comments
 (0)