Skip to content

Commit d8ff690

Browse files
Cheng JianSomasundaram Krishnasamy
authored andcommitted
sched/fair: Optimize select_idle_cpu
commit 60588bf upstream. select_idle_cpu() will scan the LLC domain for idle CPUs, it's always expensive. so the next commit : 1ad3aaf ("sched/core: Implement new approach to scale select_idle_cpu()") introduces a way to limit how many CPUs we scan. But it consume some CPUs out of 'nr' that are not allowed for the task and thus waste our attempts. The function always return nr_cpumask_bits, and we can't find a CPU which our task is allowed to run. Cpumask may be too big, similar to select_idle_core(), use per_cpu_ptr 'select_idle_mask' to prevent stack overflow. Fixes: 1ad3aaf ("sched/core: Implement new approach to scale select_idle_cpu()") Signed-off-by: Cheng Jian <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Srikar Dronamraju <[email protected]> Reviewed-by: Vincent Guittot <[email protected]> Reviewed-by: Valentin Schneider <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Yang Wei <[email protected]> Tested-by: Yang Wei <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit 7308b7bd678d408ee4c97ee78dd08d097ad45607) Conflicts: kernel/sched/fair.c Reviewed-by: Chris Hyser <[email protected]>
1 parent f36db73 commit d8ff690

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

kernel/sched/fair.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5821,6 +5821,7 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
58215821
*/
58225822
static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
58235823
{
5824+
struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
58245825
struct sched_domain *this_sd;
58255826
u64 avg_cost, avg_idle;
58265827
u64 time, cost;
@@ -5863,12 +5864,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
58635864

58645865
time = local_clock();
58655866

5866-
for_each_cpu_wrap(cpu, sched_domain_span(sd), target_tmp) {
5867-
per_cpu(next_cpu, target) = cpu;
5867+
cpumask_and(cpus, sched_domain_span(sd), &p->cpus_allowed);
5868+
5869+
for_each_cpu_wrap(cpu, cpus, target) {
58685870
if (!--nr)
58695871
return -1;
5870-
if (!cpumask_test_cpu(cpu, &p->cpus_allowed))
5871-
continue;
58725872
if (idle_cpu(cpu))
58735873
break;
58745874
}

0 commit comments

Comments
 (0)