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 disables 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/** 14 * stop_machine: freeze the machine on all CPUs and run this function 15 * @fn: the function to run 16 * @data: the data ptr for the @fn() 17 * @cpus: the cpus to run the @fn() on (NULL = any online cpu) 18 * 19 * Description: This causes a thread to be scheduled on every cpu, 20 * each of which disables interrupts. The result is that noone is 21 * holding a spinlock or inside any other preempt-disabled region when 22 * @fn() runs. 23 * 24 * This can be thought of as a very heavy write lock, equivalent to 25 * grabbing every spinlock in the kernel. */ 26int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); 27 28/** 29 * __stop_machine: freeze the machine on all CPUs and run this function 30 * @fn: the function to run 31 * @data: the data ptr for the @fn 32 * @cpus: the cpus to run the @fn() on (NULL = any online cpu) 33 * 34 * Description: This is a special version of the above, which assumes cpus 35 * won't come or go while it's being called. Used by hotplug cpu. 36 */ 37int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus); 38 39/** 40 * stop_machine_create: create all stop_machine threads 41 * 42 * Description: This causes all stop_machine threads to be created before 43 * stop_machine actually gets called. This can be used by subsystems that 44 * need a non failing stop_machine infrastructure. 45 */ 46int stop_machine_create(void); 47 48/** 49 * stop_machine_destroy: destroy all stop_machine threads 50 * 51 * Description: This causes all stop_machine threads which were created with 52 * stop_machine_create to be destroyed again. 53 */ 54void stop_machine_destroy(void); 55 56#else 57 58static inline int stop_machine(int (*fn)(void *), void *data, 59 const struct cpumask *cpus) 60{ 61 int ret; 62 local_irq_disable(); 63 ret = fn(data); 64 local_irq_enable(); 65 return ret; 66} 67 68static inline int stop_machine_create(void) { return 0; } 69static inline void stop_machine_destroy(void) { } 70 71#endif /* CONFIG_SMP */ 72#endif /* _LINUX_STOP_MACHINE */ 73