Will replace the misnomed cpu_idle_wait() function which is copied a gazillion times all over arch/*
Unified · Split
| @@ -81,6 +81,8 @@ void __smp_call_function_single(int cpuid, struct call_single_data *data, · 80 unmodified lines | ||
| 81 | 81 | int smp_call_function_any(const struct cpumask *mask, |
| 82 | 82 | smp_call_func_t func, void *info, int wait); |
| 83 | 83 | |
| 84 | +void kick_all_cpus_sync(void); | |
| 85 | + | |
| 84 | 86 | /* |
| 85 | 87 | * Generic and arch helpers |
| 86 | 88 | */ |
| @@ -192,6 +194,8 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, · 105 unmodified lines | ||
| 192 | 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 | 199 | #endif /* !SMP */ |
| 196 | 200 | |
| 197 | 201 | /* |
| @@ -795,3 +795,26 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info), · 794 unmodified lines | ||
| 795 | 795 | } |
| 796 | 796 | } |
| 797 | 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); | |