aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/process.c49
1 files changed, 27 insertions, 22 deletions
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
24static inline int freezeable(struct task_struct * p) 26static 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
84static 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 */
83int freeze_processes(void) 90int 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
158void thaw_some_processes(int all) 164static 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
183void 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}