Skip to content

Commit 8a640eb

Browse files
arighigithub-actions[bot]
authored andcommitted
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. Reported-by: Felix Abecassis <fabecassis@nvidia.com> Signed-off-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org> Link: https://patch.msgid.link/20260509180955.1840064-5-arighi@nvidia.com (cherry picked from commit bf6aa72 linux-next) Signed-off-by: Andrea Righi <arighi@nvidia.com> Acked-by: Seth Forshee <sforshee@nvidia.com> Acked-by: Nirmoy Das <nirmoyd@nvidia.com> Acked-by: Matthew R. Ochs <mochs@nvidia.com> Signed-off-by: Seth Forshee <sforshee@nvidia.com>
1 parent 59e3317 commit 8a640eb

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
@@ -9496,6 +9496,7 @@ struct lb_env {
94969496

94979497
int dst_cpu;
94989498
struct rq *dst_rq;
9499+
bool dst_core_idle;
94999500

95009501
struct cpumask *dst_grpmask;
95019502
int new_dst_cpu;
@@ -10737,10 +10738,16 @@ static bool update_sd_pick_busiest(struct lb_env *env,
1073710738
* We can use max_capacity here as reduction in capacity on some
1073810739
* CPUs in the group should either be possible to resolve
1073910740
* internally or be covered by avg_load imbalance (eventually).
10741+
*
10742+
* When SMT is active, only pull a misfit to dst_cpu if it is on a
10743+
* fully idle core; otherwise the effective capacity of the core is
10744+
* reduced and we may not actually provide more capacity than the
10745+
* source.
1074010746
*/
1074110747
if ((env->sd->flags & SD_ASYM_CPUCAPACITY) &&
1074210748
(sgs->group_type == group_misfit_task) &&
10743-
(!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
10749+
(!env->dst_core_idle ||
10750+
!capacity_greater(capacity_of(env->dst_cpu), sg->sgc->max_capacity) ||
1074410751
sds->local_stat.group_type != group_has_spare))
1074510752
return false;
1074610753

@@ -11307,6 +11314,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd
1130711314
unsigned long sum_util = 0;
1130811315
bool sg_overloaded = 0, sg_overutilized = 0;
1130911316

11317+
env->dst_core_idle = !sched_smt_active() || is_core_idle(env->dst_cpu);
11318+
1131011319
do {
1131111320
struct sg_lb_stats *sgs = &tmp_sgs;
1131211321
int local_group;

0 commit comments

Comments
 (0)