upload tizen1.0 source
[kernel/linux-2.6.36.git] / 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/interrupt.h>
12 #include <linux/oom.h>
13 #include <linux/suspend.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/syscalls.h>
17 #include <linux/freezer.h>
18 #include <linux/delay.h>
19 #include <linux/workqueue.h>
20
21 /* 
22  * Timeout for stopping processes
23  */
24 int freeze_task_timeout = 20;
25 EXPORT_SYMBOL(freeze_task_timeout);
26 module_param(freeze_task_timeout, int, S_IRUGO | S_IWUSR);
27
28 #define TIMEOUT (freeze_task_timeout * HZ)
29
30 static inline int freezeable(struct task_struct * p)
31 {
32         if ((p == current) ||
33             (p->flags & PF_NOFREEZE) ||
34             (p->exit_state != 0))
35                 return 0;
36         return 1;
37 }
38
39 static int try_to_freeze_tasks(bool sig_only)
40 {
41         struct task_struct *g, *p;
42         unsigned long end_time;
43         unsigned int todo;
44         bool wq_busy = false;
45         struct timeval start, end;
46         u64 elapsed_csecs64;
47         unsigned int elapsed_csecs;
48
49         do_gettimeofday(&start);
50
51         end_time = jiffies + TIMEOUT;
52
53         if (!sig_only)
54                 freeze_workqueues_begin();
55
56         while (true) {
57                 todo = 0;
58                 read_lock(&tasklist_lock);
59                 do_each_thread(g, p) {
60                         if (frozen(p) || !freezeable(p))
61                                 continue;
62
63                         if (!freeze_task(p, sig_only))
64                                 continue;
65
66                         /*
67                          * Now that we've done set_freeze_flag, don't
68                          * perturb a task in TASK_STOPPED or TASK_TRACED.
69                          * It is "frozen enough".  If the task does wake
70                          * up, it will immediately call try_to_freeze.
71                          */
72                         if (!task_is_stopped_or_traced(p) &&
73                             !freezer_should_skip(p))
74                                 todo++;
75                 } while_each_thread(g, p);
76                 read_unlock(&tasklist_lock);
77
78                 if (!sig_only) {
79                         wq_busy = freeze_workqueues_busy();
80                         todo += wq_busy;
81                 }
82
83                 if (!todo || time_after(jiffies, end_time))
84                         break;
85
86                 /*
87                  * We need to retry, but first give the freezing tasks some
88                  * time to enter the regrigerator.
89                  */
90                 msleep(10);
91         }
92
93         do_gettimeofday(&end);
94         elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
95         do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
96         elapsed_csecs = elapsed_csecs64;
97
98         if (todo) {
99                 /* This does not unfreeze processes that are already frozen
100                  * (we have slightly ugly calling convention in that respect,
101                  * and caller must call thaw_processes() if something fails),
102                  * but it cleans up leftover PF_FREEZE requests.
103                  */
104                 printk("\n");
105                 printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
106                        "(%d tasks refusing to freeze, wq_busy=%d):\n",
107                        elapsed_csecs / 100, elapsed_csecs % 100,
108                        todo - wq_busy, wq_busy);
109
110                 thaw_workqueues();
111
112                 read_lock(&tasklist_lock);
113                 do_each_thread(g, p) {
114                         task_lock(p);
115                         if (freezing(p) && !freezer_should_skip(p))
116                                 sched_show_task(p);
117                         cancel_freezing(p);
118                         task_unlock(p);
119                 } while_each_thread(g, p);
120                 read_unlock(&tasklist_lock);
121         } else {
122                 printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
123                         elapsed_csecs % 100);
124         }
125
126         return todo ? -EBUSY : 0;
127 }
128
129 /**
130  *      freeze_processes - tell processes to enter the refrigerator
131  */
132 int freeze_processes(void)
133 {
134         int error;
135
136         printk("Freezing user space processes ... ");
137         error = try_to_freeze_tasks(true);
138         if (error)
139                 goto Exit;
140         printk("done.\n");
141
142         printk("Freezing remaining freezable tasks ... ");
143         error = try_to_freeze_tasks(false);
144         if (error)
145                 goto Exit;
146         printk("done.");
147
148         oom_killer_disable();
149  Exit:
150         BUG_ON(in_atomic());
151         printk("\n");
152
153         return error;
154 }
155
156 static void thaw_tasks(bool nosig_only)
157 {
158         struct task_struct *g, *p;
159
160         read_lock(&tasklist_lock);
161         do_each_thread(g, p) {
162                 if (!freezeable(p))
163                         continue;
164
165                 if (nosig_only && should_send_signal(p))
166                         continue;
167
168                 if (cgroup_freezing_or_frozen(p))
169                         continue;
170
171                 thaw_process(p);
172         } while_each_thread(g, p);
173         read_unlock(&tasklist_lock);
174 }
175
176 void thaw_processes(void)
177 {
178         oom_killer_enable();
179
180         printk("Restarting tasks ... ");
181         thaw_workqueues();
182         thaw_tasks(true);
183         thaw_tasks(false);
184         schedule();
185         printk("done.\n");
186 }
187