|
@@ -1265,29 +1265,59 @@ EXPORT_SYMBOL_GPL(kick_process);
|
|
|
*/
|
|
|
static int select_fallback_rq(int cpu, struct task_struct *p)
|
|
|
{
|
|
|
- int dest_cpu;
|
|
|
const struct cpumask *nodemask = cpumask_of_node(cpu_to_node(cpu));
|
|
|
+ enum { cpuset, possible, fail } state = cpuset;
|
|
|
+ int dest_cpu;
|
|
|
|
|
|
/* Look for allowed, online CPU in same node. */
|
|
|
- for_each_cpu_and(dest_cpu, nodemask, cpu_active_mask)
|
|
|
+ for_each_cpu_mask(dest_cpu, *nodemask) {
|
|
|
+ if (!cpu_online(dest_cpu))
|
|
|
+ continue;
|
|
|
+ if (!cpu_active(dest_cpu))
|
|
|
+ continue;
|
|
|
if (cpumask_test_cpu(dest_cpu, tsk_cpus_allowed(p)))
|
|
|
return dest_cpu;
|
|
|
+ }
|
|
|
|
|
|
- /* Any allowed, online CPU? */
|
|
|
- dest_cpu = cpumask_any_and(tsk_cpus_allowed(p), cpu_active_mask);
|
|
|
- if (dest_cpu < nr_cpu_ids)
|
|
|
- return dest_cpu;
|
|
|
+ for (;;) {
|
|
|
+ /* Any allowed, online CPU? */
|
|
|
+ for_each_cpu_mask(dest_cpu, *tsk_cpus_allowed(p)) {
|
|
|
+ if (!cpu_online(dest_cpu))
|
|
|
+ continue;
|
|
|
+ if (!cpu_active(dest_cpu))
|
|
|
+ continue;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
- /* No more Mr. Nice Guy. */
|
|
|
- dest_cpu = cpuset_cpus_allowed_fallback(p);
|
|
|
- /*
|
|
|
- * Don't tell them about moving exiting tasks or
|
|
|
- * kernel threads (both mm NULL), since they never
|
|
|
- * leave kernel.
|
|
|
- */
|
|
|
- if (p->mm && printk_ratelimit()) {
|
|
|
- printk_sched("process %d (%s) no longer affine to cpu%d\n",
|
|
|
- task_pid_nr(p), p->comm, cpu);
|
|
|
+ switch (state) {
|
|
|
+ case cpuset:
|
|
|
+ /* No more Mr. Nice Guy. */
|
|
|
+ cpuset_cpus_allowed_fallback(p);
|
|
|
+ state = possible;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case possible:
|
|
|
+ do_set_cpus_allowed(p, cpu_possible_mask);
|
|
|
+ state = fail;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case fail:
|
|
|
+ BUG();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+out:
|
|
|
+ if (state != cpuset) {
|
|
|
+ /*
|
|
|
+ * Don't tell them about moving exiting tasks or
|
|
|
+ * kernel threads (both mm NULL), since they never
|
|
|
+ * leave kernel.
|
|
|
+ */
|
|
|
+ if (p->mm && printk_ratelimit()) {
|
|
|
+ printk_sched("process %d (%s) no longer affine to cpu%d\n",
|
|
|
+ task_pid_nr(p), p->comm, cpu);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return dest_cpu;
|