at v2.6.16 1.8 kB view raw
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/config.h> 8#include <linux/cpu.h> 9#include <asm/system.h> 10 11#if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP) 12/** 13 * stop_machine_run: freeze the machine on all CPUs and run this function 14 * @fn: the function to run 15 * @data: the data ptr for the @fn() 16 * @cpu: the cpu to run @fn() on (or any, if @cpu == NR_CPUS. 17 * 18 * Description: This causes a thread to be scheduled on every other cpu, 19 * each of which disables interrupts, and finally interrupts are disabled 20 * on the current CPU. The result is that noone is holding a spinlock 21 * or inside any other preempt-disabled region when @fn() runs. 22 * 23 * This can be thought of as a very heavy write lock, equivalent to 24 * grabbing every spinlock in the kernel. */ 25int stop_machine_run(int (*fn)(void *), void *data, unsigned int cpu); 26 27/** 28 * __stop_machine_run: freeze the machine on all CPUs and run this function 29 * @fn: the function to run 30 * @data: the data ptr for the @fn 31 * @cpu: the cpu to run @fn on (or any, if @cpu == NR_CPUS. 32 * 33 * Description: This is a special version of the above, which returns the 34 * thread which has run @fn(): kthread_stop will return the return value 35 * of @fn(). Used by hotplug cpu. 36 */ 37struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, 38 unsigned int cpu); 39 40#else 41 42static inline int stop_machine_run(int (*fn)(void *), void *data, 43 unsigned int cpu) 44{ 45 int ret; 46 local_irq_disable(); 47 ret = fn(data); 48 local_irq_enable(); 49 return ret; 50} 51#endif /* CONFIG_SMP */ 52#endif /* _LINUX_STOP_MACHINE */