diff options
-rw-r--r-- | include/linux/freezer.h | 6 | ||||
-rw-r--r-- | kernel/power/process.c | 49 |
2 files changed, 28 insertions, 27 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 294ebea859c9..6e05e3e7ce39 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
@@ -1,8 +1,5 @@ | |||
1 | /* Freezer declarations */ | 1 | /* Freezer declarations */ |
2 | 2 | ||
3 | #define FREEZER_KERNEL_THREADS 0 | ||
4 | #define FREEZER_ALL_THREADS 1 | ||
5 | |||
6 | #ifdef CONFIG_PM | 3 | #ifdef CONFIG_PM |
7 | /* | 4 | /* |
8 | * Check if a process has been frozen | 5 | * Check if a process has been frozen |
@@ -60,8 +57,7 @@ static inline void frozen_process(struct task_struct *p) | |||
60 | 57 | ||
61 | extern void refrigerator(void); | 58 | extern void refrigerator(void); |
62 | extern int freeze_processes(void); | 59 | extern int freeze_processes(void); |
63 | #define thaw_processes() do { thaw_some_processes(FREEZER_ALL_THREADS); } while(0) | 60 | extern void thaw_processes(void); |
64 | #define thaw_kernel_threads() do { thaw_some_processes(FREEZER_KERNEL_THREADS); } while(0) | ||
65 | 61 | ||
66 | static inline int try_to_freeze(void) | 62 | static inline int try_to_freeze(void) |
67 | { | 63 | { |
diff --git a/kernel/power/process.c b/kernel/power/process.c index 1badb9a89ade..fd0ebb942f50 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -20,6 +20,8 @@ | |||
20 | */ | 20 | */ |
21 | #define TIMEOUT (20 * HZ) | 21 | #define TIMEOUT (20 * HZ) |
22 | 22 | ||
23 | #define FREEZER_KERNEL_THREADS 0 | ||
24 | #define FREEZER_USER_SPACE 1 | ||
23 | 25 | ||
24 | static inline int freezeable(struct task_struct * p) | 26 | static inline int freezeable(struct task_struct * p) |
25 | { | 27 | { |
@@ -79,6 +81,11 @@ static void cancel_freezing(struct task_struct *p) | |||
79 | } | 81 | } |
80 | } | 82 | } |
81 | 83 | ||
84 | static inline int is_user_space(struct task_struct *p) | ||
85 | { | ||
86 | return p->mm && !(p->flags & PF_BORROWED_MM); | ||
87 | } | ||
88 | |||
82 | /* 0 = success, else # of processes that we failed to stop */ | 89 | /* 0 = success, else # of processes that we failed to stop */ |
83 | int freeze_processes(void) | 90 | int freeze_processes(void) |
84 | { | 91 | { |
@@ -103,10 +110,9 @@ int freeze_processes(void) | |||
103 | cancel_freezing(p); | 110 | cancel_freezing(p); |
104 | continue; | 111 | continue; |
105 | } | 112 | } |
106 | if (p->mm && !(p->flags & PF_BORROWED_MM)) { | 113 | if (is_user_space(p)) { |
107 | /* The task is a user-space one. | 114 | /* Freeze the task unless there is a vfork |
108 | * Freeze it unless there's a vfork completion | 115 | * completion pending |
109 | * pending | ||
110 | */ | 116 | */ |
111 | if (!p->vfork_done) | 117 | if (!p->vfork_done) |
112 | freeze_process(p); | 118 | freeze_process(p); |
@@ -155,31 +161,30 @@ int freeze_processes(void) | |||
155 | return 0; | 161 | return 0; |
156 | } | 162 | } |
157 | 163 | ||
158 | void thaw_some_processes(int all) | 164 | static void thaw_tasks(int thaw_user_space) |
159 | { | 165 | { |
160 | struct task_struct *g, *p; | 166 | struct task_struct *g, *p; |
161 | int pass = 0; /* Pass 0 = Kernel space, 1 = Userspace */ | ||
162 | 167 | ||
163 | printk("Restarting tasks... "); | ||
164 | read_lock(&tasklist_lock); | 168 | read_lock(&tasklist_lock); |
165 | do { | 169 | do_each_thread(g, p) { |
166 | do_each_thread(g, p) { | 170 | if (!freezeable(p)) |
167 | /* | 171 | continue; |
168 | * is_user = 0 if kernel thread or borrowed mm, | ||
169 | * 1 otherwise. | ||
170 | */ | ||
171 | int is_user = !!(p->mm && !(p->flags & PF_BORROWED_MM)); | ||
172 | if (!freezeable(p) || (is_user != pass)) | ||
173 | continue; | ||
174 | if (!thaw_process(p)) | ||
175 | printk(KERN_INFO | ||
176 | "Strange, %s not stopped\n", p->comm); | ||
177 | } while_each_thread(g, p); | ||
178 | 172 | ||
179 | pass++; | 173 | if (is_user_space(p) == !thaw_user_space) |
180 | } while (pass < 2 && all); | 174 | continue; |
181 | 175 | ||
176 | if (!thaw_process(p)) | ||
177 | printk(KERN_WARNING " Strange, %s not stopped\n", | ||
178 | p->comm ); | ||
179 | } while_each_thread(g, p); | ||
182 | read_unlock(&tasklist_lock); | 180 | read_unlock(&tasklist_lock); |
181 | } | ||
182 | |||
183 | void thaw_processes(void) | ||
184 | { | ||
185 | printk("Restarting tasks ... "); | ||
186 | thaw_tasks(FREEZER_KERNEL_THREADS); | ||
187 | thaw_tasks(FREEZER_USER_SPACE); | ||
183 | schedule(); | 188 | schedule(); |
184 | printk("done.\n"); | 189 | printk("done.\n"); |
185 | } | 190 | } |