A recent change to freeze_secondary_cpus() which added an early abort if a wakeup is pending missed the fact that the function is also invoked for shutdown, reboot and kexec via disable_nonboot_cpus(). In case of disable_nonboot_cpus() the wakeup event needs to be ignored as the purpose is to terminate the currently running kernel. Add a 'suspend' argument which is only set when the freeze is in context of a suspend operation. If not set then an eventually pending wakeup event is ignored.
Unified · Split
| @@ -144,12 +144,18 @@ static inline void get_online_cpus(void) { cpus_read_lock(); } · 143 unmodified lines | ||
| 144 | 144 | static inline void put_online_cpus(void) { cpus_read_unlock(); } |
| 145 | 145 | |
| 146 | 146 | #ifdef CONFIG_PM_SLEEP_SMP |
| 147 | −extern int freeze_secondary_cpus(int primary); | |
| 147 | +int __freeze_secondary_cpus(int primary, bool suspend); | |
| 148 | +static inline int freeze_secondary_cpus(int primary) | |
| 149 | +{ | |
| 150 | + return __freeze_secondary_cpus(primary, true); | |
| 151 | +} | |
| 152 | + | |
| 148 | 153 | static inline int disable_nonboot_cpus(void) |
| 149 | 154 | { |
| 150 | − return freeze_secondary_cpus(0); | |
| 155 | + return __freeze_secondary_cpus(0, false); | |
| 151 | 156 | } |
| 152 | −extern void enable_nonboot_cpus(void); | |
| 157 | + | |
| 158 | +void enable_nonboot_cpus(void); | |
| 153 | 159 | |
| 154 | 160 | static inline int suspend_disable_secondary_cpus(void) |
| 155 | 161 | { |
| @@ -1327,7 +1327,7 @@ void bringup_nonboot_cpus(unsigned int setup_max_cpus) · 1326 unmodified lines | ||
| 1327 | 1327 | #ifdef CONFIG_PM_SLEEP_SMP |
| 1328 | 1328 | static cpumask_var_t frozen_cpus; |
| 1329 | 1329 | |
| 1330 | −int freeze_secondary_cpus(int primary) | |
| 1330 | +int __freeze_secondary_cpus(int primary, bool suspend) | |
| 1331 | 1331 | { |
| 1332 | 1332 | int cpu, error = 0; |
| 1333 | 1333 | |
| @@ -1352,7 +1352,7 @@ int freeze_secondary_cpus(int primary) · 18 unmodified lines | ||
| 1352 | 1352 | if (cpu == primary) |
| 1353 | 1353 | continue; |
| 1354 | 1354 | |
| 1355 | − if (pm_wakeup_pending()) { | |
| 1355 | + if (suspend && pm_wakeup_pending()) { | |
| 1356 | 1356 | pr_info("Wakeup pending. Abort CPU freeze\n"); |
| 1357 | 1357 | error = -EBUSY; |
| 1358 | 1358 | break; |