X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fstop_machine.c;h=319821ef78afc9e0a7488cbf9b2ea1c5853b65c1;hb=1202d6ff356cc66dc8d2b85546eb4f187f9e1f25;hp=84a9d18aa8da0ecb9309c6b58a2b8b694a1493e2;hpb=5696c1944a33b4434a9a1ebb6383b906afd43a10;p=linux-2.6-omap-h63xx.git diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 84a9d18aa8d..319821ef78a 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -1,9 +1,15 @@ -#include -#include -#include +/* Copyright 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation. + * GPL v2 and any later version. + */ #include #include +#include +#include +#include +#include #include +#include + #include #include #include @@ -41,6 +47,7 @@ static int stopmachine(void *cpu) if (stopmachine_state == STOPMACHINE_DISABLE_IRQ && !irqs_disabled) { local_irq_disable(); + hard_irq_disable(); irqs_disabled = 1; /* Ack: irqs disabled. */ smp_mb(); /* Must read state first. */ @@ -86,14 +93,6 @@ static void stopmachine_set_state(enum stopmachine_state state) static int stop_machine(void) { int i, ret = 0; - struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; - mm_segment_t old_fs = get_fs(); - - /* One high-prio thread per cpu. We'll do this one. */ - set_fs(KERNEL_DS); - sys_sched_setscheduler(current->pid, SCHED_FIFO, - (struct sched_param __user *)¶m); - set_fs(old_fs); atomic_set(&stopmachine_thread_ack, 0); stopmachine_num_threads = 0; @@ -115,17 +114,16 @@ static int stop_machine(void) /* If some failed, kill them all. */ if (ret < 0) { stopmachine_set_state(STOPMACHINE_EXIT); - up(&stopmachine_mutex); return ret; } - /* Don't schedule us away at this point, please. */ - local_irq_disable(); - /* Now they are all started, make them hold the CPUs, ready. */ + preempt_disable(); stopmachine_set_state(STOPMACHINE_PREPARE); /* Make them disable irqs. */ + local_irq_disable(); + hard_irq_disable(); stopmachine_set_state(STOPMACHINE_DISABLE_IRQ); return 0; @@ -135,6 +133,7 @@ static void restart_machine(void) { stopmachine_set_state(STOPMACHINE_EXIT); local_irq_enable(); + preempt_enable_no_resched(); } struct stop_machine_data @@ -186,6 +185,10 @@ struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, p = kthread_create(do_stop, &smdata, "kstopmachine"); if (!IS_ERR(p)) { + struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; + + /* One high-prio thread per cpu. We'll do this one. */ + sched_setscheduler(p, SCHED_FIFO, ¶m); kthread_bind(p, cpu); wake_up_process(p); wait_for_completion(&smdata.done); @@ -210,3 +213,4 @@ int stop_machine_run(int (*fn)(void *), void *data, unsigned int cpu) return ret; } +EXPORT_SYMBOL_GPL(stop_machine_run);