1 /* 2 * Uniprocessor-only support functions. The counterpart to kernel/smp.c 3 */ 4 5 #include <linux/interrupt.h> 6 #include <linux/kernel.h> 7 #include <linux/export.h> 8 #include <linux/smp.h> 9 10 int smp_call_function_single(int cpu, void (*func) (void *info), void *info, 11 int wait) 12 { 13 unsigned long flags; 14 15 WARN_ON(cpu != 0); 16 17 local_irq_save(flags); 18 func(info); 19 local_irq_restore(flags); 20 21 return 0; 22 } 23 EXPORT_SYMBOL(smp_call_function_single); 24 25 int smp_call_function_single_async(int cpu, struct call_single_data *csd) 26 { 27 unsigned long flags; 28 29 local_irq_save(flags); 30 csd->func(csd->info); 31 local_irq_restore(flags); 32 return 0; 33 } 34 EXPORT_SYMBOL(smp_call_function_single_async); 35 36 int on_each_cpu(smp_call_func_t func, void *info, int wait) 37 { 38 unsigned long flags; 39 40 local_irq_save(flags); 41 func(info); 42 local_irq_restore(flags); 43 return 0; 44 } 45 EXPORT_SYMBOL(on_each_cpu); 46 47 /* 48 * Note we still need to test the mask even for UP 49 * because we actually can get an empty mask from 50 * code that on SMP might call us without the local 51 * CPU in the mask. 52 */ 53 void on_each_cpu_mask(const struct cpumask *mask, 54 smp_call_func_t func, void *info, bool wait) 55 { 56 unsigned long flags; 57 58 if (cpumask_test_cpu(0, mask)) { 59 local_irq_save(flags); 60 func(info); 61 local_irq_restore(flags); 62 } 63 } 64 EXPORT_SYMBOL(on_each_cpu_mask); 65 66 /* 67 * Preemption is disabled here to make sure the cond_func is called under the 68 * same condtions in UP and SMP. 69 */ 70 void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), 71 smp_call_func_t func, void *info, bool wait, 72 gfp_t gfp_flags) 73 { 74 unsigned long flags; 75 76 preempt_disable(); 77 if (cond_func(0, info)) { 78 local_irq_save(flags); 79 func(info); 80 local_irq_restore(flags); 81 } 82 preempt_enable(); 83 } 84 EXPORT_SYMBOL(on_each_cpu_cond); 85