diff options
Diffstat (limited to 'kernel/power/process.c')
-rw-r--r-- | kernel/power/process.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c index 7e426459e60a..19db29f67558 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/freezer.h> | 16 | #include <linux/freezer.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/workqueue.h> | 18 | #include <linux/workqueue.h> |
19 | #include <linux/kmod.h> | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | * Timeout for stopping processes | 22 | * Timeout for stopping processes |
@@ -53,11 +54,9 @@ static int try_to_freeze_tasks(bool user_only) | |||
53 | * It is "frozen enough". If the task does wake | 54 | * It is "frozen enough". If the task does wake |
54 | * up, it will immediately call try_to_freeze. | 55 | * up, it will immediately call try_to_freeze. |
55 | * | 56 | * |
56 | * Because freeze_task() goes through p's | 57 | * Because freeze_task() goes through p's scheduler lock, it's |
57 | * scheduler lock after setting TIF_FREEZE, it's | 58 | * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING |
58 | * guaranteed that either we see TASK_RUNNING or | 59 | * transition can't race with task state testing here. |
59 | * try_to_stop() after schedule() in ptrace/signal | ||
60 | * stop sees TIF_FREEZE. | ||
61 | */ | 60 | */ |
62 | if (!task_is_stopped_or_traced(p) && | 61 | if (!task_is_stopped_or_traced(p) && |
63 | !freezer_should_skip(p)) | 62 | !freezer_should_skip(p)) |
@@ -98,13 +97,15 @@ static int try_to_freeze_tasks(bool user_only) | |||
98 | elapsed_csecs / 100, elapsed_csecs % 100, | 97 | elapsed_csecs / 100, elapsed_csecs % 100, |
99 | todo - wq_busy, wq_busy); | 98 | todo - wq_busy, wq_busy); |
100 | 99 | ||
101 | read_lock(&tasklist_lock); | 100 | if (!wakeup) { |
102 | do_each_thread(g, p) { | 101 | read_lock(&tasklist_lock); |
103 | if (!wakeup && !freezer_should_skip(p) && | 102 | do_each_thread(g, p) { |
104 | p != current && freezing(p) && !frozen(p)) | 103 | if (p != current && !freezer_should_skip(p) |
105 | sched_show_task(p); | 104 | && freezing(p) && !frozen(p)) |
106 | } while_each_thread(g, p); | 105 | sched_show_task(p); |
107 | read_unlock(&tasklist_lock); | 106 | } while_each_thread(g, p); |
107 | read_unlock(&tasklist_lock); | ||
108 | } | ||
108 | } else { | 109 | } else { |
109 | printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100, | 110 | printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100, |
110 | elapsed_csecs % 100); | 111 | elapsed_csecs % 100); |
@@ -122,6 +123,10 @@ int freeze_processes(void) | |||
122 | { | 123 | { |
123 | int error; | 124 | int error; |
124 | 125 | ||
126 | error = __usermodehelper_disable(UMH_FREEZING); | ||
127 | if (error) | ||
128 | return error; | ||
129 | |||
125 | if (!pm_freezing) | 130 | if (!pm_freezing) |
126 | atomic_inc(&system_freezing_cnt); | 131 | atomic_inc(&system_freezing_cnt); |
127 | 132 | ||
@@ -130,6 +135,7 @@ int freeze_processes(void) | |||
130 | error = try_to_freeze_tasks(true); | 135 | error = try_to_freeze_tasks(true); |
131 | if (!error) { | 136 | if (!error) { |
132 | printk("done."); | 137 | printk("done."); |
138 | __usermodehelper_set_disable_depth(UMH_DISABLED); | ||
133 | oom_killer_disable(); | 139 | oom_killer_disable(); |
134 | } | 140 | } |
135 | printk("\n"); | 141 | printk("\n"); |
@@ -187,6 +193,8 @@ void thaw_processes(void) | |||
187 | } while_each_thread(g, p); | 193 | } while_each_thread(g, p); |
188 | read_unlock(&tasklist_lock); | 194 | read_unlock(&tasklist_lock); |
189 | 195 | ||
196 | usermodehelper_enable(); | ||
197 | |||
190 | schedule(); | 198 | schedule(); |
191 | printk("done.\n"); | 199 | printk("done.\n"); |
192 | } | 200 | } |