sched/fair: Add SIS_UTIL support to select_idle_capacity()

Add to select_idle_capacity() the same SIS_UTIL-controlled idle-scan
mechanism, already used by select_idle_cpu(): when sched_feat(SIS_UTIL)
is enabled and the LLC domain has sched_domain_shared data, derive the
per-attempt scan limit from sd->shared->nr_idle_scan.

That bounds the walk on large LLCs: once nr_idle_scan is exhausted,
return the best CPU seen so far. The early exit is gated on
!has_idle_core so an active idle-core search (SMT with idle cores
reported by test_idle_cores()) isn't cut short before it gets a chance
to find one.

Co-developed-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.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-6-arighi@nvidia.com
This commit is contained in:
K Prateek Nayak 2026-05-09 20:07:29 +02:00 committed by Peter Zijlstra
parent bf6aa72219
commit 61ea17a637

View File

@ -8016,6 +8016,7 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
int fits, best_fits = ASYM_IDLE_THREAD_MISFIT;
int cpu, best_cpu = -1;
struct cpumask *cpus;
int nr = INT_MAX;
cpus = this_cpu_cpumask_var_ptr(select_rq_mask);
cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
@ -8024,10 +8025,28 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
util_min = uclamp_eff_value(p, UCLAMP_MIN);
util_max = uclamp_eff_value(p, UCLAMP_MAX);
if (sched_feat(SIS_UTIL) && sd->shared) {
/*
* Same nr_idle_scan hint as select_idle_cpu(), nr only limits
* the scan when not preferring an idle core.
*/
nr = READ_ONCE(sd->shared->nr_idle_scan) + 1;
/* overloaded domain is unlikely to have idle cpu/core */
if (nr == 1)
return -1;
}
for_each_cpu_wrap(cpu, cpus, target) {
bool preferred_core = !has_idle_core || is_core_idle(cpu);
unsigned long cpu_cap = capacity_of(cpu);
/*
* Stop when the nr_idle_scan is exhausted (mirrors
* select_idle_cpu() logic).
*/
if (!has_idle_core && --nr <= 0)
return best_cpu;
if (!choose_idle_cpu(cpu, p))
continue;