]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Implement migrate_all_tasks
authorRusty Russell <rusty@rustcorp.com.au>
Thu, 18 Mar 2004 05:30:28 +0000 (21:30 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 18 Mar 2004 05:30:28 +0000 (21:30 -0800)
Implement migrate_all_tasks() which moves tasks off cpu while machine
is stopped.

include/linux/sched.h
kernel/sched.c

index d15706883bb66d1a5c738266a6eb0a9bfefdb4dd..eb5bc2f127885c4b4d8e9077a7ccd468bacc8683 100644 (file)
@@ -547,6 +547,8 @@ extern void node_nr_running_init(void);
 #define node_nr_running_init() {}
 #endif
 
+/* Move tasks off this (offline) CPU onto another. */
+extern void migrate_all_tasks(void);
 extern void set_user_nice(task_t *p, long nice);
 extern int task_prio(task_t *p);
 extern int task_nice(task_t *p);
index 007548c4a883b8b319bbee42196b2fbfaf8a277d..ce9c63eba5154bf0ef797d9bc04effa617eb0bb7 100644 (file)
@@ -2793,6 +2793,63 @@ static int migration_thread(void * data)
        return 0;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+/* migrate_all_tasks - function to migrate all the tasks from the
+ * current cpu caller must have already scheduled this to the target
+ * cpu via set_cpus_allowed.  Machine is stopped.  */
+void migrate_all_tasks(void)
+{
+       struct task_struct *tsk, *t;
+       int dest_cpu, src_cpu;
+       unsigned int node;
+
+       /* We're nailed to this CPU. */
+       src_cpu = smp_processor_id();
+
+       /* Not required, but here for neatness. */
+       write_lock(&tasklist_lock);
+
+       /* watch out for per node tasks, let's stay on this node */
+       node = cpu_to_node(src_cpu);
+
+       do_each_thread(t, tsk) {
+               cpumask_t mask;
+               if (tsk == current)
+                       continue;
+
+               if (task_cpu(tsk) != src_cpu)
+                       continue;
+
+               /* Figure out where this task should go (attempting to
+                * keep it on-node), and check if it can be migrated
+                * as-is.  NOTE that kernel threads bound to more than
+                * one online cpu will be migrated. */
+               mask = node_to_cpumask(node);
+               cpus_and(mask, mask, tsk->cpus_allowed);
+               dest_cpu = any_online_cpu(mask);
+               if (dest_cpu == NR_CPUS)
+                       dest_cpu = any_online_cpu(tsk->cpus_allowed);
+               if (dest_cpu == NR_CPUS) {
+                       cpus_clear(tsk->cpus_allowed);
+                       cpus_complement(tsk->cpus_allowed);
+                       dest_cpu = any_online_cpu(tsk->cpus_allowed);
+
+                       /* Don't tell them about moving exiting tasks
+                          or kernel threads (both mm NULL), since
+                          they never leave kernel. */
+                       if (tsk->mm && printk_ratelimit())
+                               printk(KERN_INFO "process %d (%s) no "
+                                      "longer affine to cpu%d\n",
+                                      tsk->pid, tsk->comm, src_cpu);
+               }
+
+               move_task_away(tsk, dest_cpu);
+       } while_each_thread(t, tsk);
+
+       write_unlock(&tasklist_lock);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
 /*
  * migration_call - callback that gets triggered when a CPU is added.
  * Here we can start up the necessary migration thread for the new CPU.