diff options
-rw-r--r-- | include/linux/freezer.h | 9 | ||||
-rw-r--r-- | kernel/power/process.c | 25 |
2 files changed, 26 insertions, 8 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 266373f74445..294ebea859c9 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
@@ -1,5 +1,8 @@ | |||
1 | /* Freezer declarations */ | 1 | /* Freezer declarations */ |
2 | 2 | ||
3 | #define FREEZER_KERNEL_THREADS 0 | ||
4 | #define FREEZER_ALL_THREADS 1 | ||
5 | |||
3 | #ifdef CONFIG_PM | 6 | #ifdef CONFIG_PM |
4 | /* | 7 | /* |
5 | * Check if a process has been frozen | 8 | * Check if a process has been frozen |
@@ -57,7 +60,8 @@ static inline void frozen_process(struct task_struct *p) | |||
57 | 60 | ||
58 | extern void refrigerator(void); | 61 | extern void refrigerator(void); |
59 | extern int freeze_processes(void); | 62 | extern int freeze_processes(void); |
60 | extern void thaw_processes(void); | 63 | #define thaw_processes() do { thaw_some_processes(FREEZER_ALL_THREADS); } while(0) |
64 | #define thaw_kernel_threads() do { thaw_some_processes(FREEZER_KERNEL_THREADS); } while(0) | ||
61 | 65 | ||
62 | static inline int try_to_freeze(void) | 66 | static inline int try_to_freeze(void) |
63 | { | 67 | { |
@@ -67,6 +71,9 @@ static inline int try_to_freeze(void) | |||
67 | } else | 71 | } else |
68 | return 0; | 72 | return 0; |
69 | } | 73 | } |
74 | |||
75 | extern void thaw_some_processes(int all); | ||
76 | |||
70 | #else | 77 | #else |
71 | static inline int frozen(struct task_struct *p) { return 0; } | 78 | static inline int frozen(struct task_struct *p) { return 0; } |
72 | static inline int freezing(struct task_struct *p) { return 0; } | 79 | static inline int freezing(struct task_struct *p) { return 0; } |
diff --git a/kernel/power/process.c b/kernel/power/process.c index fedabad5a180..cba8a5890eda 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -153,18 +153,29 @@ int freeze_processes(void) | |||
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
155 | 155 | ||
156 | void thaw_processes(void) | 156 | void thaw_some_processes(int all) |
157 | { | 157 | { |
158 | struct task_struct *g, *p; | 158 | struct task_struct *g, *p; |
159 | int pass = 0; /* Pass 0 = Kernel space, 1 = Userspace */ | ||
159 | 160 | ||
160 | printk("Restarting tasks... "); | 161 | printk("Restarting tasks... "); |
161 | read_lock(&tasklist_lock); | 162 | read_lock(&tasklist_lock); |
162 | do_each_thread(g, p) { | 163 | do { |
163 | if (!freezeable(p)) | 164 | do_each_thread(g, p) { |
164 | continue; | 165 | /* |
165 | if (!thaw_process(p)) | 166 | * is_user = 0 if kernel thread or borrowed mm, |
166 | printk(KERN_INFO "Strange, %s not stopped\n", p->comm); | 167 | * 1 otherwise. |
167 | } while_each_thread(g, p); | 168 | */ |
169 | int is_user = !!(p->mm && !(p->flags & PF_BORROWED_MM)); | ||
170 | if (!freezeable(p) || (is_user != pass)) | ||
171 | continue; | ||
172 | if (!thaw_process(p)) | ||
173 | printk(KERN_INFO | ||
174 | "Strange, %s not stopped\n", p->comm); | ||
175 | } while_each_thread(g, p); | ||
176 | |||
177 | pass++; | ||
178 | } while (pass < 2 && all); | ||
168 | 179 | ||
169 | read_unlock(&tasklist_lock); | 180 | read_unlock(&tasklist_lock); |
170 | schedule(); | 181 | schedule(); |