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