diff options
Diffstat (limited to 'kernel/sched_fair.c')
| -rw-r--r-- | kernel/sched_fair.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 7e51b5bb27c..ba0e1f49a22 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
| @@ -2326,7 +2326,8 @@ static int select_idle_sibling(struct task_struct *p, int target) | |||
| 2326 | int cpu = smp_processor_id(); | 2326 | int cpu = smp_processor_id(); |
| 2327 | int prev_cpu = task_cpu(p); | 2327 | int prev_cpu = task_cpu(p); |
| 2328 | struct sched_domain *sd; | 2328 | struct sched_domain *sd; |
| 2329 | int i; | 2329 | struct sched_group *sg; |
| 2330 | int i, smt = 0; | ||
| 2330 | 2331 | ||
| 2331 | /* | 2332 | /* |
| 2332 | * If the task is going to be woken-up on this cpu and if it is | 2333 | * If the task is going to be woken-up on this cpu and if it is |
| @@ -2346,25 +2347,38 @@ static int select_idle_sibling(struct task_struct *p, int target) | |||
| 2346 | * Otherwise, iterate the domains and find an elegible idle cpu. | 2347 | * Otherwise, iterate the domains and find an elegible idle cpu. |
| 2347 | */ | 2348 | */ |
| 2348 | rcu_read_lock(); | 2349 | rcu_read_lock(); |
| 2350 | again: | ||
| 2349 | for_each_domain(target, sd) { | 2351 | for_each_domain(target, sd) { |
| 2350 | if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) | 2352 | if (!smt && (sd->flags & SD_SHARE_CPUPOWER)) |
| 2351 | break; | 2353 | continue; |
| 2352 | 2354 | ||
| 2353 | for_each_cpu_and(i, sched_domain_span(sd), tsk_cpus_allowed(p)) { | 2355 | if (!(sd->flags & SD_SHARE_PKG_RESOURCES)) { |
| 2354 | if (idle_cpu(i)) { | 2356 | if (!smt) { |
| 2355 | target = i; | 2357 | smt = 1; |
| 2356 | break; | 2358 | goto again; |
| 2357 | } | 2359 | } |
| 2360 | break; | ||
| 2358 | } | 2361 | } |
| 2359 | 2362 | ||
| 2360 | /* | 2363 | sg = sd->groups; |
| 2361 | * Lets stop looking for an idle sibling when we reached | 2364 | do { |
| 2362 | * the domain that spans the current cpu and prev_cpu. | 2365 | if (!cpumask_intersects(sched_group_cpus(sg), |
| 2363 | */ | 2366 | tsk_cpus_allowed(p))) |
| 2364 | if (cpumask_test_cpu(cpu, sched_domain_span(sd)) && | 2367 | goto next; |
| 2365 | cpumask_test_cpu(prev_cpu, sched_domain_span(sd))) | 2368 | |
| 2366 | break; | 2369 | for_each_cpu(i, sched_group_cpus(sg)) { |
| 2370 | if (!idle_cpu(i)) | ||
| 2371 | goto next; | ||
| 2372 | } | ||
| 2373 | |||
| 2374 | target = cpumask_first_and(sched_group_cpus(sg), | ||
| 2375 | tsk_cpus_allowed(p)); | ||
| 2376 | goto done; | ||
| 2377 | next: | ||
| 2378 | sg = sg->next; | ||
| 2379 | } while (sg != sd->groups); | ||
| 2367 | } | 2380 | } |
| 2381 | done: | ||
| 2368 | rcu_read_unlock(); | 2382 | rcu_read_unlock(); |
| 2369 | 2383 | ||
| 2370 | return target; | 2384 | return target; |
