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