--- kernel/sched.c.bug176738 2006-06-08 15:43:09.000000000 +0200 +++ kernel/sched.c 2006-06-12 14:56:51.000000000 +0200 @@ -1020,6 +1020,28 @@ return idlest; } +static int +find_idlest_cpu_nodomain(struct task_struct *p, int this_cpu) +{ + cpumask_t tmp; + unsigned long load, min_load = ULONG_MAX; + int idlest = -1; + int i; + + /* Traverse only the allowed CPUs */ + cpus_and(tmp, cpu_online_map, p->cpus_allowed); + + for_each_cpu_mask(i, tmp) { + load = source_load(i, 0); + + if (load < min_load || (load == min_load && i == this_cpu)) { + min_load = load; + idlest = i; + } + } + return idlest; +} + /* * sched_balance_self: balance the current task (running on cpu) in domains * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and @@ -1036,6 +1058,9 @@ struct task_struct *t = current; struct sched_domain *tmp, *sd = NULL; + if (!cpus_full(t->cpus_allowed)) + return find_idlest_cpu_nodomain(t, cpu); + for_each_domain(cpu, tmp) if (tmp->flags & flag) sd = tmp;