Skip to content

Commit a2af04d

Browse files
kudureranganathsforshee
authored andcommitted
sched/fair: Add SIS_UTIL support to select_idle_capacity()
BugLink: https://bugs.launchpad.net/bugs/2150671 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 (backported from commit 61ea17a linux-next) [ arighi: choose_idle_cpu() not available in v6.18 ] 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 09fceee commit a2af04d

1 file changed

Lines changed: 19 additions & 0 deletions

File tree

kernel/sched/fair.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7871,6 +7871,7 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
78717871
int fits, best_fits = ASYM_IDLE_THREAD_MISFIT;
78727872
int cpu, best_cpu = -1;
78737873
struct cpumask *cpus;
7874+
int nr = INT_MAX;
78747875

78757876
cpus = this_cpu_cpumask_var_ptr(select_rq_mask);
78767877
cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
@@ -7879,10 +7880,28 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
78797880
util_min = uclamp_eff_value(p, UCLAMP_MIN);
78807881
util_max = uclamp_eff_value(p, UCLAMP_MAX);
78817882

7883+
if (sched_feat(SIS_UTIL) && sd->shared) {
7884+
/*
7885+
* Same nr_idle_scan hint as select_idle_cpu(), nr only limits
7886+
* the scan when not preferring an idle core.
7887+
*/
7888+
nr = READ_ONCE(sd->shared->nr_idle_scan) + 1;
7889+
/* overloaded domain is unlikely to have idle cpu/core */
7890+
if (nr == 1)
7891+
return -1;
7892+
}
7893+
78827894
for_each_cpu_wrap(cpu, cpus, target) {
78837895
bool preferred_core = !has_idle_core || is_core_idle(cpu);
78847896
unsigned long cpu_cap = capacity_of(cpu);
78857897

7898+
/*
7899+
* Stop when the nr_idle_scan is exhausted (mirrors
7900+
* select_idle_cpu() logic).
7901+
*/
7902+
if (!has_idle_core && --nr <= 0)
7903+
return best_cpu;
7904+
78867905
if (!available_idle_cpu(cpu) && !sched_idle_cpu(cpu))
78877906
continue;
78887907

0 commit comments

Comments
 (0)