diff options
Diffstat (limited to 'kernel/power/process.c')
| -rw-r--r-- | kernel/power/process.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c index fc0df8486449..06ec8869dbf1 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
| @@ -109,6 +109,8 @@ static int try_to_freeze_tasks(bool user_only) | |||
| 109 | 109 | ||
| 110 | /** | 110 | /** |
| 111 | * freeze_processes - Signal user space processes to enter the refrigerator. | 111 | * freeze_processes - Signal user space processes to enter the refrigerator. |
| 112 | * The current thread will not be frozen. The same process that calls | ||
| 113 | * freeze_processes must later call thaw_processes. | ||
| 112 | * | 114 | * |
| 113 | * On success, returns 0. On failure, -errno and system is fully thawed. | 115 | * On success, returns 0. On failure, -errno and system is fully thawed. |
| 114 | */ | 116 | */ |
| @@ -120,6 +122,9 @@ int freeze_processes(void) | |||
| 120 | if (error) | 122 | if (error) |
| 121 | return error; | 123 | return error; |
| 122 | 124 | ||
| 125 | /* Make sure this task doesn't get frozen */ | ||
| 126 | current->flags |= PF_SUSPEND_TASK; | ||
| 127 | |||
| 123 | if (!pm_freezing) | 128 | if (!pm_freezing) |
| 124 | atomic_inc(&system_freezing_cnt); | 129 | atomic_inc(&system_freezing_cnt); |
| 125 | 130 | ||
| @@ -168,6 +173,7 @@ int freeze_kernel_threads(void) | |||
| 168 | void thaw_processes(void) | 173 | void thaw_processes(void) |
| 169 | { | 174 | { |
| 170 | struct task_struct *g, *p; | 175 | struct task_struct *g, *p; |
| 176 | struct task_struct *curr = current; | ||
| 171 | 177 | ||
| 172 | if (pm_freezing) | 178 | if (pm_freezing) |
| 173 | atomic_dec(&system_freezing_cnt); | 179 | atomic_dec(&system_freezing_cnt); |
| @@ -182,10 +188,15 @@ void thaw_processes(void) | |||
| 182 | 188 | ||
| 183 | read_lock(&tasklist_lock); | 189 | read_lock(&tasklist_lock); |
| 184 | do_each_thread(g, p) { | 190 | do_each_thread(g, p) { |
| 191 | /* No other threads should have PF_SUSPEND_TASK set */ | ||
| 192 | WARN_ON((p != curr) && (p->flags & PF_SUSPEND_TASK)); | ||
| 185 | __thaw_task(p); | 193 | __thaw_task(p); |
| 186 | } while_each_thread(g, p); | 194 | } while_each_thread(g, p); |
| 187 | read_unlock(&tasklist_lock); | 195 | read_unlock(&tasklist_lock); |
| 188 | 196 | ||
| 197 | WARN_ON(!(curr->flags & PF_SUSPEND_TASK)); | ||
| 198 | curr->flags &= ~PF_SUSPEND_TASK; | ||
| 199 | |||
| 189 | usermodehelper_enable(); | 200 | usermodehelper_enable(); |
| 190 | 201 | ||
| 191 | schedule(); | 202 | schedule(); |
