On Mon, 2012-09-24 at 09:33 -0700, Linus Torvalds wrote: > Sure, the "scan bits" bitops will return ">= nr_cpu_ids" for the "I > couldn't find a bit" thing, but that doesn't mean that everything else > should.
Fair enough.. --- kernel/sched/fair.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6b800a1..329f78d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2634,25 +2634,12 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) */ static int select_idle_sibling(struct task_struct *p, int target) { - int cpu = smp_processor_id(); - int prev_cpu = task_cpu(p); struct sched_domain *sd; struct sched_group *sg; int i; - /* - * If the task is going to be woken-up on this cpu and if it is - * already idle, then it is the right target. - */ - if (target == cpu && idle_cpu(cpu)) - return cpu; - - /* - * If the task is going to be woken-up on the cpu where it previously - * ran and if it is currently idle, then it the right target. - */ - if (target == prev_cpu && idle_cpu(prev_cpu)) - return prev_cpu; + if (idle_cpu(target)) + return target; /* * Otherwise, iterate the domains and find an elegible idle cpu. @@ -2661,18 +2648,31 @@ static int select_idle_sibling(struct task_struct *p, int target) for_each_lower_domain(sd) { sg = sd->groups; do { - if (!cpumask_intersects(sched_group_cpus(sg), - tsk_cpus_allowed(p))) - goto next; + int candidate = -1; + /* + * In the SMT case the groups are the SMT-siblings, + * otherwise they're singleton groups. + */ for_each_cpu(i, sched_group_cpus(sg)) { + if (!cpumask_test_cpu(i, tsk_cpus_allowed(p))) + continue; + + /* + * If any of the SMT-siblings are !idle, the + * core isn't idle. + */ if (!idle_cpu(i)) goto next; + + if (candidate < 0) + candidate = i; } - target = cpumask_first_and(sched_group_cpus(sg), - tsk_cpus_allowed(p)); - goto done; + if (candidate >= 0) { + target = candidate; + goto done; + } next: sg = sg->next; } while (sg != sd->groups); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/