1 /* 2 * drivers/power/process.c - Functions for starting/stopping processes on 3 * suspend transitions. 4 * 5 * Originally from swsusp. 6 */ 7 8 9 #undef DEBUG 10 11 #include <linux/interrupt.h> 12 #include <linux/suspend.h> 13 #include <linux/module.h> 14 #include <linux/syscalls.h> 15 #include <linux/freezer.h> 16 17 /* 18 * Timeout for stopping processes 19 */ 20 #define TIMEOUT (20 * HZ) 21 22 #define FREEZER_KERNEL_THREADS 0 23 #define FREEZER_USER_SPACE 1 24 25 static inline int freezeable(struct task_struct * p) 26 { 27 if ((p == current) || 28 (p->flags & PF_NOFREEZE) || 29 (p->exit_state != 0)) 30 return 0; 31 return 1; 32 } 33 34 /* 35 * freezing is complete, mark current process as frozen 36 */ 37 static inline void frozen_process(void) 38 { 39 if (!unlikely(current->flags & PF_NOFREEZE)) { 40 current->flags |= PF_FROZEN; 41 wmb(); 42 } 43 clear_freeze_flag(current); 44 } 45 46 /* Refrigerator is place where frozen processes are stored :-). */ 47 void refrigerator(void) 48 { 49 /* Hmm, should we be allowed to suspend when there are realtime 50 processes around? */ 51 long save; 52 53 task_lock(current); 54 if (freezing(current)) { 55 frozen_process(); 56 task_unlock(current); 57 } else { 58 task_unlock(current); 59 return; 60 } 61 save = current->state; 62 pr_debug("%s entered refrigerator\n", current->comm); 63 64 spin_lock_irq(¤t->sighand->siglock); 65 recalc_sigpending(); /* We sent fake signal, clean it up */ 66 spin_unlock_irq(¤t->sighand->siglock); 67 68 for (;;) { 69 set_current_state(TASK_UNINTERRUPTIBLE); 70 if (!frozen(current)) 71 break; 72 schedule(); 73 } 74 pr_debug("%s left refrigerator\n", current->comm); 75 __set_current_state(save); 76 } 77 78 static void fake_signal_wake_up(struct task_struct *p, int resume) 79 { 80 unsigned long flags; 81 82 spin_lock_irqsave(&p->sighand->siglock, flags); 83 signal_wake_up(p, resume); 84 spin_unlock_irqrestore(&p->sighand->siglock, flags); 85 } 86 87 static void send_fake_signal(struct task_struct *p) 88 { 89 if (task_is_stopped(p)) 90 force_sig_specific(SIGSTOP, p); 91 fake_signal_wake_up(p, task_is_stopped(p)); 92 } 93 94 static int has_mm(struct task_struct *p) 95 { 96 return (p->mm && !(p->flags & PF_BORROWED_MM)); 97 } 98 99 /** 100 * freeze_task - send a freeze request to given task 101 * @p: task to send the request to 102 * @with_mm_only: if set, the request will only be sent if the task has its 103 * own mm 104 * Return value: 0, if @with_mm_only is set and the task has no mm of its 105 * own or the task is frozen, 1, otherwise 106 * 107 * The freeze request is sent by seting the tasks's TIF_FREEZE flag and 108 * either sending a fake signal to it or waking it up, depending on whether 109 * or not it has its own mm (ie. it is a user land task). If @with_mm_only 110 * is set and the task has no mm of its own (ie. it is a kernel thread), 111 * its TIF_FREEZE flag should not be set. 112 * 113 * The task_lock() is necessary to prevent races with exit_mm() or 114 * use_mm()/unuse_mm() from occuring. 115 */ 116 static int freeze_task(struct task_struct *p, int with_mm_only) 117 { 118 int ret = 1; 119 120 task_lock(p); 121 if (freezing(p)) { 122 if (has_mm(p)) { 123 if (!signal_pending(p)) 124 fake_signal_wake_up(p, 0); 125 } else { 126 if (with_mm_only) 127 ret = 0; 128 else 129 wake_up_state(p, TASK_INTERRUPTIBLE); 130 } 131 } else { 132 rmb(); 133 if (frozen(p)) { 134 ret = 0; 135 } else { 136 if (has_mm(p)) { 137 set_freeze_flag(p); 138 send_fake_signal(p); 139 } else { 140 if (with_mm_only) { 141 ret = 0; 142 } else { 143 set_freeze_flag(p); 144 wake_up_state(p, TASK_INTERRUPTIBLE); 145 } 146 } 147 } 148 } 149 task_unlock(p); 150 return ret; 151 } 152 153 static void cancel_freezing(struct task_struct *p) 154 { 155 unsigned long flags; 156 157 if (freezing(p)) { 158 pr_debug(" clean up: %s\n", p->comm); 159 clear_freeze_flag(p); 160 spin_lock_irqsave(&p->sighand->siglock, flags); 161 recalc_sigpending_and_wake(p); 162 spin_unlock_irqrestore(&p->sighand->siglock, flags); 163 } 164 } 165 166 static int try_to_freeze_tasks(int freeze_user_space) 167 { 168 struct task_struct *g, *p; 169 unsigned long end_time; 170 unsigned int todo; 171 struct timeval start, end; 172 s64 elapsed_csecs64; 173 unsigned int elapsed_csecs; 174 175 do_gettimeofday(&start); 176 177 end_time = jiffies + TIMEOUT; 178 do { 179 todo = 0; 180 read_lock(&tasklist_lock); 181 do_each_thread(g, p) { 182 if (frozen(p) || !freezeable(p)) 183 continue; 184 185 if (task_is_traced(p) && frozen(p->parent)) { 186 cancel_freezing(p); 187 continue; 188 } 189 190 if (!freeze_task(p, freeze_user_space)) 191 continue; 192 193 if (!freezer_should_skip(p)) 194 todo++; 195 } while_each_thread(g, p); 196 read_unlock(&tasklist_lock); 197 yield(); /* Yield is okay here */ 198 if (time_after(jiffies, end_time)) 199 break; 200 } while (todo); 201 202 do_gettimeofday(&end); 203 elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); 204 do_div(elapsed_csecs64, NSEC_PER_SEC / 100); 205 elapsed_csecs = elapsed_csecs64; 206 207 if (todo) { 208 /* This does not unfreeze processes that are already frozen 209 * (we have slightly ugly calling convention in that respect, 210 * and caller must call thaw_processes() if something fails), 211 * but it cleans up leftover PF_FREEZE requests. 212 */ 213 printk("\n"); 214 printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " 215 "(%d tasks refusing to freeze):\n", 216 elapsed_csecs / 100, elapsed_csecs % 100, todo); 217 show_state(); 218 read_lock(&tasklist_lock); 219 do_each_thread(g, p) { 220 task_lock(p); 221 if (freezing(p) && !freezer_should_skip(p)) 222 printk(KERN_ERR " %s\n", p->comm); 223 cancel_freezing(p); 224 task_unlock(p); 225 } while_each_thread(g, p); 226 read_unlock(&tasklist_lock); 227 } else { 228 printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100, 229 elapsed_csecs % 100); 230 } 231 232 return todo ? -EBUSY : 0; 233 } 234 235 /** 236 * freeze_processes - tell processes to enter the refrigerator 237 */ 238 int freeze_processes(void) 239 { 240 int error; 241 242 printk("Freezing user space processes ... "); 243 error = try_to_freeze_tasks(FREEZER_USER_SPACE); 244 if (error) 245 goto Exit; 246 printk("done.\n"); 247 248 printk("Freezing remaining freezable tasks ... "); 249 error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); 250 if (error) 251 goto Exit; 252 printk("done."); 253 Exit: 254 BUG_ON(in_atomic()); 255 printk("\n"); 256 return error; 257 } 258 259 static void thaw_tasks(int thaw_user_space) 260 { 261 struct task_struct *g, *p; 262 263 read_lock(&tasklist_lock); 264 do_each_thread(g, p) { 265 if (!freezeable(p)) 266 continue; 267 268 if (!p->mm == thaw_user_space) 269 continue; 270 271 thaw_process(p); 272 } while_each_thread(g, p); 273 read_unlock(&tasklist_lock); 274 } 275 276 void thaw_processes(void) 277 { 278 printk("Restarting tasks ... "); 279 thaw_tasks(FREEZER_KERNEL_THREADS); 280 thaw_tasks(FREEZER_USER_SPACE); 281 schedule(); 282 printk("done.\n"); 283 } 284 285 EXPORT_SYMBOL(refrigerator); 286