diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/power/power.h | 24 | ||||
| -rw-r--r-- | kernel/power/process.c | 7 | ||||
| -rw-r--r-- | kernel/power/user.c | 6 |
3 files changed, 31 insertions, 6 deletions
diff --git a/kernel/power/power.h b/kernel/power/power.h index 0c4defe6d3b8..21724eee5206 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
| @@ -231,8 +231,28 @@ extern int pm_test_level; | |||
| 231 | #ifdef CONFIG_SUSPEND_FREEZER | 231 | #ifdef CONFIG_SUSPEND_FREEZER |
| 232 | static inline int suspend_freeze_processes(void) | 232 | static inline int suspend_freeze_processes(void) |
| 233 | { | 233 | { |
| 234 | int error = freeze_processes(); | 234 | int error; |
| 235 | return error ? : freeze_kernel_threads(); | 235 | |
| 236 | error = freeze_processes(); | ||
| 237 | |||
| 238 | /* | ||
| 239 | * freeze_processes() automatically thaws every task if freezing | ||
| 240 | * fails. So we need not do anything extra upon error. | ||
| 241 | */ | ||
| 242 | if (error) | ||
| 243 | goto Finish; | ||
| 244 | |||
| 245 | error = freeze_kernel_threads(); | ||
| 246 | |||
| 247 | /* | ||
| 248 | * freeze_kernel_threads() thaws only kernel threads upon freezing | ||
| 249 | * failure. So we have to thaw the userspace tasks ourselves. | ||
| 250 | */ | ||
| 251 | if (error) | ||
| 252 | thaw_processes(); | ||
| 253 | |||
| 254 | Finish: | ||
| 255 | return error; | ||
| 236 | } | 256 | } |
| 237 | 257 | ||
| 238 | static inline void suspend_thaw_processes(void) | 258 | static inline void suspend_thaw_processes(void) |
diff --git a/kernel/power/process.c b/kernel/power/process.c index eeca00311f39..7e426459e60a 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
| @@ -143,7 +143,10 @@ int freeze_processes(void) | |||
| 143 | /** | 143 | /** |
| 144 | * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator. | 144 | * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator. |
| 145 | * | 145 | * |
| 146 | * On success, returns 0. On failure, -errno and system is fully thawed. | 146 | * On success, returns 0. On failure, -errno and only the kernel threads are |
| 147 | * thawed, so as to give a chance to the caller to do additional cleanups | ||
| 148 | * (if any) before thawing the userspace tasks. So, it is the responsibility | ||
| 149 | * of the caller to thaw the userspace tasks, when the time is right. | ||
| 147 | */ | 150 | */ |
| 148 | int freeze_kernel_threads(void) | 151 | int freeze_kernel_threads(void) |
| 149 | { | 152 | { |
| @@ -159,7 +162,7 @@ int freeze_kernel_threads(void) | |||
| 159 | BUG_ON(in_atomic()); | 162 | BUG_ON(in_atomic()); |
| 160 | 163 | ||
| 161 | if (error) | 164 | if (error) |
| 162 | thaw_processes(); | 165 | thaw_kernel_threads(); |
| 163 | return error; | 166 | return error; |
| 164 | } | 167 | } |
| 165 | 168 | ||
diff --git a/kernel/power/user.c b/kernel/power/user.c index e5a21a857302..3e100075b13c 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
| @@ -249,13 +249,15 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
| 249 | } | 249 | } |
| 250 | pm_restore_gfp_mask(); | 250 | pm_restore_gfp_mask(); |
| 251 | error = hibernation_snapshot(data->platform_support); | 251 | error = hibernation_snapshot(data->platform_support); |
| 252 | if (!error) { | 252 | if (error) { |
| 253 | thaw_kernel_threads(); | ||
| 254 | } else { | ||
| 253 | error = put_user(in_suspend, (int __user *)arg); | 255 | error = put_user(in_suspend, (int __user *)arg); |
| 254 | if (!error && !freezer_test_done) | 256 | if (!error && !freezer_test_done) |
| 255 | data->ready = 1; | 257 | data->ready = 1; |
| 256 | if (freezer_test_done) { | 258 | if (freezer_test_done) { |
| 257 | freezer_test_done = false; | 259 | freezer_test_done = false; |
| 258 | thaw_processes(); | 260 | thaw_kernel_threads(); |
| 259 | } | 261 | } |
| 260 | } | 262 | } |
| 261 | break; | 263 | break; |
