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 25static 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 */ 37static inline void frozen_process(void) 38{ 39 if (!unlikely(current->flags & PF_NOFREEZE)) { 40 current->flags |= PF_FROZEN; 41 wmb(); 42 } 43 clear_tsk_thread_flag(current, TIF_FREEZE); 44} 45 46/* Refrigerator is place where frozen processes are stored :-). */ 47void 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 current->state = save; 76} 77 78static inline void freeze_process(struct task_struct *p) 79{ 80 unsigned long flags; 81 82 if (!freezing(p)) { 83 rmb(); 84 if (!frozen(p)) { 85 if (p->state == TASK_STOPPED) 86 force_sig_specific(SIGSTOP, p); 87 88 freeze(p); 89 spin_lock_irqsave(&p->sighand->siglock, flags); 90 signal_wake_up(p, p->state == TASK_STOPPED); 91 spin_unlock_irqrestore(&p->sighand->siglock, flags); 92 } 93 } 94} 95 96static void cancel_freezing(struct task_struct *p) 97{ 98 unsigned long flags; 99 100 if (freezing(p)) { 101 pr_debug(" clean up: %s\n", p->comm); 102 do_not_freeze(p); 103 spin_lock_irqsave(&p->sighand->siglock, flags); 104 recalc_sigpending_and_wake(p); 105 spin_unlock_irqrestore(&p->sighand->siglock, flags); 106 } 107} 108 109static inline int is_user_space(struct task_struct *p) 110{ 111 return p->mm && !(p->flags & PF_BORROWED_MM); 112} 113 114static unsigned int try_to_freeze_tasks(int freeze_user_space) 115{ 116 struct task_struct *g, *p; 117 unsigned long end_time; 118 unsigned int todo; 119 120 end_time = jiffies + TIMEOUT; 121 do { 122 todo = 0; 123 read_lock(&tasklist_lock); 124 do_each_thread(g, p) { 125 if (!freezeable(p)) 126 continue; 127 128 if (frozen(p)) 129 continue; 130 131 if (p->state == TASK_TRACED && frozen(p->parent)) { 132 cancel_freezing(p); 133 continue; 134 } 135 if (freeze_user_space && !is_user_space(p)) 136 continue; 137 138 freeze_process(p); 139 if (!freezer_should_skip(p)) 140 todo++; 141 } while_each_thread(g, p); 142 read_unlock(&tasklist_lock); 143 yield(); /* Yield is okay here */ 144 if (todo && time_after(jiffies, end_time)) 145 break; 146 } while (todo); 147 148 if (todo) { 149 /* This does not unfreeze processes that are already frozen 150 * (we have slightly ugly calling convention in that respect, 151 * and caller must call thaw_processes() if something fails), 152 * but it cleans up leftover PF_FREEZE requests. 153 */ 154 printk("\n"); 155 printk(KERN_ERR "Stopping %s timed out after %d seconds " 156 "(%d tasks refusing to freeze):\n", 157 freeze_user_space ? "user space processes" : 158 "kernel threads", 159 TIMEOUT / HZ, todo); 160 read_lock(&tasklist_lock); 161 do_each_thread(g, p) { 162 if (freeze_user_space && !is_user_space(p)) 163 continue; 164 165 task_lock(p); 166 if (freezeable(p) && !frozen(p) && 167 !freezer_should_skip(p)) 168 printk(KERN_ERR " %s\n", p->comm); 169 170 cancel_freezing(p); 171 task_unlock(p); 172 } while_each_thread(g, p); 173 read_unlock(&tasklist_lock); 174 } 175 176 return todo; 177} 178 179/** 180 * freeze_processes - tell processes to enter the refrigerator 181 * 182 * Returns 0 on success, or the number of processes that didn't freeze, 183 * although they were told to. 184 */ 185int freeze_processes(void) 186{ 187 unsigned int nr_unfrozen; 188 189 printk("Stopping tasks ... "); 190 nr_unfrozen = try_to_freeze_tasks(FREEZER_USER_SPACE); 191 if (nr_unfrozen) 192 return nr_unfrozen; 193 194 sys_sync(); 195 nr_unfrozen = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); 196 if (nr_unfrozen) 197 return nr_unfrozen; 198 199 printk("done.\n"); 200 BUG_ON(in_atomic()); 201 return 0; 202} 203 204static void thaw_tasks(int thaw_user_space) 205{ 206 struct task_struct *g, *p; 207 208 read_lock(&tasklist_lock); 209 do_each_thread(g, p) { 210 if (!freezeable(p)) 211 continue; 212 213 if (is_user_space(p) == !thaw_user_space) 214 continue; 215 216 thaw_process(p); 217 } while_each_thread(g, p); 218 read_unlock(&tasklist_lock); 219} 220 221void thaw_processes(void) 222{ 223 printk("Restarting tasks ... "); 224 thaw_tasks(FREEZER_KERNEL_THREADS); 225 thaw_tasks(FREEZER_USER_SPACE); 226 schedule(); 227 printk("done.\n"); 228} 229 230EXPORT_SYMBOL(refrigerator); 231