stop_machine(): stop_machine_run() changed to use cpu mask
[safe/jmp/linux-2.6] / include / linux / stop_machine.h
1 #ifndef _LINUX_STOP_MACHINE
2 #define _LINUX_STOP_MACHINE
3 /* "Bogolock": stop the entire machine, disable interrupts.  This is a
4    very heavy lock, which is equivalent to grabbing every spinlock
5    (and more).  So the "read" side to such a lock is anything which
6    diables preeempt. */
7 #include <linux/cpu.h>
8 #include <linux/cpumask.h>
9 #include <asm/system.h>
10
11 #if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
12
13 /* Deprecated, but useful for transition. */
14 #define ALL_CPUS ~0U
15
16 /**
17  * stop_machine: freeze the machine on all CPUs and run this function
18  * @fn: the function to run
19  * @data: the data ptr for the @fn()
20  * @cpus: the cpus to run the @fn() on (NULL = any online cpu)
21  *
22  * Description: This causes a thread to be scheduled on every cpu,
23  * each of which disables interrupts.  The result is that noone is
24  * holding a spinlock or inside any other preempt-disabled region when
25  * @fn() runs.
26  *
27  * This can be thought of as a very heavy write lock, equivalent to
28  * grabbing every spinlock in the kernel. */
29 int stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus);
30
31 /**
32  * __stop_machine: freeze the machine on all CPUs and run this function
33  * @fn: the function to run
34  * @data: the data ptr for the @fn
35  * @cpus: the cpus to run the @fn() on (NULL = any online cpu)
36  *
37  * Description: This is a special version of the above, which assumes cpus
38  * won't come or go while it's being called.  Used by hotplug cpu.
39  */
40 int __stop_machine(int (*fn)(void *), void *data, const cpumask_t *cpus);
41 #else
42
43 static inline int stop_machine(int (*fn)(void *), void *data,
44                                const cpumask_t *cpus)
45 {
46         int ret;
47         local_irq_disable();
48         ret = fn(data);
49         local_irq_enable();
50         return ret;
51 }
52 #endif /* CONFIG_SMP */
53
54 static inline int __deprecated stop_machine_run(int (*fn)(void *), void *data,
55                                                 unsigned int cpu)
56 {
57         /* If they don't care which cpu fn runs on, just pick one. */
58         if (cpu == NR_CPUS)
59                 return stop_machine(fn, data, NULL);
60         else if (cpu == ~0U)
61                 return stop_machine(fn, data, &cpu_possible_map);
62         else {
63                 cpumask_t cpus = cpumask_of_cpu(cpu);
64                 return stop_machine(fn, data, &cpus);
65         }
66 }
67 #endif /* _LINUX_STOP_MACHINE */