Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6] / kernel / power / process.c
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/smp_lock.h>
12 #include <linux/interrupt.h>
13 #include <linux/suspend.h>
14 #include <linux/module.h>
15 #include <linux/syscalls.h>
16 #include <linux/freezer.h>
17
18 /* 
19  * Timeout for stopping processes
20  */
21 #define TIMEOUT (20 * HZ)
22
23 #define FREEZER_KERNEL_THREADS 0
24 #define FREEZER_USER_SPACE 1
25
26 static inline int freezeable(struct task_struct * p)
27 {
28         if ((p == current) || 
29             (p->flags & PF_NOFREEZE) ||
30             (p->exit_state == EXIT_ZOMBIE) ||
31             (p->exit_state == EXIT_DEAD) ||
32             (p->state == TASK_STOPPED))
33                 return 0;
34         return 1;
35 }
36
37 /* Refrigerator is place where frozen processes are stored :-). */
38 void refrigerator(void)
39 {
40         /* Hmm, should we be allowed to suspend when there are realtime
41            processes around? */
42         long save;
43         save = current->state;
44         pr_debug("%s entered refrigerator\n", current->comm);
45
46         frozen_process(current);
47         spin_lock_irq(&current->sighand->siglock);
48         recalc_sigpending(); /* We sent fake signal, clean it up */
49         spin_unlock_irq(&current->sighand->siglock);
50
51         while (frozen(current)) {
52                 current->state = TASK_UNINTERRUPTIBLE;
53                 schedule();
54         }
55         pr_debug("%s left refrigerator\n", current->comm);
56         current->state = save;
57 }
58
59 static inline void freeze_process(struct task_struct *p)
60 {
61         unsigned long flags;
62
63         if (!freezing(p)) {
64                 freeze(p);
65                 spin_lock_irqsave(&p->sighand->siglock, flags);
66                 signal_wake_up(p, 0);
67                 spin_unlock_irqrestore(&p->sighand->siglock, flags);
68         }
69 }
70
71 static void cancel_freezing(struct task_struct *p)
72 {
73         unsigned long flags;
74
75         if (freezing(p)) {
76                 pr_debug("  clean up: %s\n", p->comm);
77                 do_not_freeze(p);
78                 spin_lock_irqsave(&p->sighand->siglock, flags);
79                 recalc_sigpending_tsk(p);
80                 spin_unlock_irqrestore(&p->sighand->siglock, flags);
81         }
82 }
83
84 static inline int is_user_space(struct task_struct *p)
85 {
86         return p->mm && !(p->flags & PF_BORROWED_MM);
87 }
88
89 static unsigned int try_to_freeze_tasks(int freeze_user_space)
90 {
91         struct task_struct *g, *p;
92         unsigned long end_time;
93         unsigned int todo;
94
95         end_time = jiffies + TIMEOUT;
96         do {
97                 todo = 0;
98                 read_lock(&tasklist_lock);
99                 do_each_thread(g, p) {
100                         if (!freezeable(p))
101                                 continue;
102
103                         if (frozen(p))
104                                 continue;
105
106                         if (p->state == TASK_TRACED &&
107                             (frozen(p->parent) ||
108                              p->parent->state == TASK_STOPPED)) {
109                                 cancel_freezing(p);
110                                 continue;
111                         }
112                         if (is_user_space(p)) {
113                                 if (!freeze_user_space)
114                                         continue;
115
116                                 /* Freeze the task unless there is a vfork
117                                  * completion pending
118                                  */
119                                 if (!p->vfork_done)
120                                         freeze_process(p);
121                         } else {
122                                 if (freeze_user_space)
123                                         continue;
124
125                                 freeze_process(p);
126                         }
127                         todo++;
128                 } while_each_thread(g, p);
129                 read_unlock(&tasklist_lock);
130                 yield();                        /* Yield is okay here */
131                 if (todo && time_after(jiffies, end_time))
132                         break;
133         } while (todo);
134
135         if (todo) {
136                 /* This does not unfreeze processes that are already frozen
137                  * (we have slightly ugly calling convention in that respect,
138                  * and caller must call thaw_processes() if something fails),
139                  * but it cleans up leftover PF_FREEZE requests.
140                  */
141                 printk("\n");
142                 printk(KERN_ERR "Stopping %s timed out after %d seconds "
143                                 "(%d tasks refusing to freeze):\n",
144                                 freeze_user_space ? "user space processes" :
145                                         "kernel threads",
146                                 TIMEOUT / HZ, todo);
147                 read_lock(&tasklist_lock);
148                 do_each_thread(g, p) {
149                         if (is_user_space(p) == !freeze_user_space)
150                                 continue;
151
152                         if (freezeable(p) && !frozen(p))
153                                 printk(KERN_ERR " %s\n", p->comm);
154
155                         cancel_freezing(p);
156                 } while_each_thread(g, p);
157                 read_unlock(&tasklist_lock);
158         }
159
160         return todo;
161 }
162
163 /**
164  *      freeze_processes - tell processes to enter the refrigerator
165  *
166  *      Returns 0 on success, or the number of processes that didn't freeze,
167  *      although they were told to.
168  */
169 int freeze_processes(void)
170 {
171         unsigned int nr_unfrozen;
172
173         printk("Stopping tasks ... ");
174         nr_unfrozen = try_to_freeze_tasks(FREEZER_USER_SPACE);
175         if (nr_unfrozen)
176                 return nr_unfrozen;
177
178         sys_sync();
179         nr_unfrozen = try_to_freeze_tasks(FREEZER_KERNEL_THREADS);
180         if (nr_unfrozen)
181                 return nr_unfrozen;
182
183         printk("done.\n");
184         BUG_ON(in_atomic());
185         return 0;
186 }
187
188 static void thaw_tasks(int thaw_user_space)
189 {
190         struct task_struct *g, *p;
191
192         read_lock(&tasklist_lock);
193         do_each_thread(g, p) {
194                 if (!freezeable(p))
195                         continue;
196
197                 if (is_user_space(p) == !thaw_user_space)
198                         continue;
199
200                 if (!thaw_process(p))
201                         printk(KERN_WARNING " Strange, %s not stopped\n",
202                                 p->comm );
203         } while_each_thread(g, p);
204         read_unlock(&tasklist_lock);
205 }
206
207 void thaw_processes(void)
208 {
209         printk("Restarting tasks ... ");
210         thaw_tasks(FREEZER_KERNEL_THREADS);
211         thaw_tasks(FREEZER_USER_SPACE);
212         schedule();
213         printk("done.\n");
214 }
215
216 EXPORT_SYMBOL(refrigerator);