diff options
-rw-r--r-- | include/linux/smp.h | 4 | ||||
-rw-r--r-- | kernel/smp.c | 23 |
2 files changed, 27 insertions, 0 deletions
diff --git a/include/linux/smp.h b/include/linux/smp.h index 24360de6c968..717fb746c9a8 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
@@ -81,6 +81,8 @@ void __smp_call_function_single(int cpuid, struct call_single_data *data, | |||
81 | int smp_call_function_any(const struct cpumask *mask, | 81 | int smp_call_function_any(const struct cpumask *mask, |
82 | smp_call_func_t func, void *info, int wait); | 82 | smp_call_func_t func, void *info, int wait); |
83 | 83 | ||
84 | void kick_all_cpus_sync(void); | ||
85 | |||
84 | /* | 86 | /* |
85 | * Generic and arch helpers | 87 | * Generic and arch helpers |
86 | */ | 88 | */ |
@@ -192,6 +194,8 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, | |||
192 | return smp_call_function_single(0, func, info, wait); | 194 | return smp_call_function_single(0, func, info, wait); |
193 | } | 195 | } |
194 | 196 | ||
197 | static inline void kick_all_cpus_sync(void) { } | ||
198 | |||
195 | #endif /* !SMP */ | 199 | #endif /* !SMP */ |
196 | 200 | ||
197 | /* | 201 | /* |
diff --git a/kernel/smp.c b/kernel/smp.c index a61294c07f3f..d0ae5b24875e 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -795,3 +795,26 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), | |||
795 | } | 795 | } |
796 | } | 796 | } |
797 | EXPORT_SYMBOL(on_each_cpu_cond); | 797 | EXPORT_SYMBOL(on_each_cpu_cond); |
798 | |||
799 | static void do_nothing(void *unused) | ||
800 | { | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * kick_all_cpus_sync - Force all cpus out of idle | ||
805 | * | ||
806 | * Used to synchronize the update of pm_idle function pointer. It's | ||
807 | * called after the pointer is updated and returns after the dummy | ||
808 | * callback function has been executed on all cpus. The execution of | ||
809 | * the function can only happen on the remote cpus after they have | ||
810 | * left the idle function which had been called via pm_idle function | ||
811 | * pointer. So it's guaranteed that nothing uses the previous pointer | ||
812 | * anymore. | ||
813 | */ | ||
814 | void kick_all_cpus_sync(void) | ||
815 | { | ||
816 | /* Make sure the change is visible before we kick the cpus */ | ||
817 | smp_mb(); | ||
818 | smp_call_function(do_nothing, NULL, 1); | ||
819 | } | ||
820 | EXPORT_SYMBOL_GPL(kick_all_cpus_sync); | ||