diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-05-09 23:30:01 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-05-09 23:30:01 -0700 |
| commit | ddea677b6730f9f72d94f87885e38cff6d329fab (patch) | |
| tree | ea430cec4e0c852524a9584fe41e5517ade05b3e /kernel/fork.c | |
| parent | 4197ad870f2d0618da7ca2bea46ec632128c0920 (diff) | |
[PATCH] Move migrate_all_tasks to CPU_DEAD handling
From: Srivatsa Vaddagiri <vatsa@in.ibm.com>
migrate_all_tasks is currently run with rest of the machine stopped.
It iterates thr' the complete task table, turning off cpu affinity of any task
that it finds affine to the dying cpu. Depending on the task table
size this can take considerable time. All this time machine is stopped, doing
nothing.
Stopping the machine for such extended periods can be avoided if we do
task migration in CPU_DEAD notification and that's precisely what this patch
does.
The patch puts idle task to the _front_ of the dying CPU's runqueue at the
highest priority possible. This cause idle thread to run _immediately_ after
kstopmachine thread yields. Idle thread notices that its cpu is offline and
dies quickly. Task migration can then be done at leisure in CPU_DEAD
notification, when rest of the CPUs are running.
Some advantages with this approach are:
- More scalable. Predicatable amout of time that machine is stopped.
- No changes to hot path/core code. We are just exploiting scheduler
rules which runs the next high-priority task on the runqueue. Also
since I put idle task to the _front_ of the runqueue, there
are no races when a equally high priority task is woken up
and added to the runqueue. It gets in at the back of the runqueue,
_after_ idle task!
- cpu_is_offline check that is presenty required in try_to_wake_up,
idle_balance and rebalance_tick can be removed, thus speeding them
up a bit
From: Srivatsa Vaddagiri <vatsa@in.ibm.com>
Rusty mentioned that the unlikely hints against cpu_is_offline is
redundant since the macro already has that hint. Patch below removes those
redundant hints I added.
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index c3af0b74708a..24c7e85b9a33 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -26,6 +26,7 @@ #include <linux/binfmts.h> #include <linux/mman.h> #include <linux/fs.h> +#include <linux/cpu.h> #include <linux/security.h> #include <linux/syscalls.h> #include <linux/jiffies.h> @@ -1196,8 +1197,15 @@ long do_fork(unsigned long clone_flags, wake_up_forked_thread(p); else wake_up_forked_process(p); - } else + } else { + int cpu = get_cpu(); + p->state = TASK_STOPPED; + if (cpu_is_offline(task_cpu(p))) + set_task_cpu(p, cpu); + + put_cpu(); + } ++total_forks; if (unlikely (trace)) { |
