powerpc: Minor cleanup to lib/Kconfig.debug
[safe/jmp/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/interrupt.h>
12 #include <linux/oom.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 static inline int freezeable(struct task_struct * p)
24 {
25         if ((p == current) ||
26             (p->flags & PF_NOFREEZE) ||
27             (p->exit_state != 0))
28                 return 0;
29         return 1;
30 }
31
32 static int try_to_freeze_tasks(bool sig_only)
33 {
34         struct task_struct *g, *p;
35         unsigned long end_time;
36         unsigned int todo;
37         struct timeval start, end;
38         u64 elapsed_csecs64;
39         unsigned int elapsed_csecs;
40
41         do_gettimeofday(&start);
42
43         end_time = jiffies + TIMEOUT;
44         do {
45                 todo = 0;
46                 read_lock(&tasklist_lock);
47                 do_each_thread(g, p) {
48                         if (frozen(p) || !freezeable(p))
49                                 continue;
50
51                         if (!freeze_task(p, sig_only))
52                                 continue;
53
54                         /*
55                          * Now that we've done set_freeze_flag, don't
56                          * perturb a task in TASK_STOPPED or TASK_TRACED.
57                          * It is "frozen enough".  If the task does wake
58                          * up, it will immediately call try_to_freeze.
59                          */
60                         if (!task_is_stopped_or_traced(p) &&
61                             !freezer_should_skip(p))
62                                 todo++;
63                 } while_each_thread(g, p);
64                 read_unlock(&tasklist_lock);
65                 yield();                        /* Yield is okay here */
66                 if (time_after(jiffies, end_time))
67                         break;
68         } while (todo);
69
70         do_gettimeofday(&end);
71         elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
72         do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
73         elapsed_csecs = elapsed_csecs64;
74
75         if (todo) {
76                 /* This does not unfreeze processes that are already frozen
77                  * (we have slightly ugly calling convention in that respect,
78                  * and caller must call thaw_processes() if something fails),
79                  * but it cleans up leftover PF_FREEZE requests.
80                  */
81                 printk("\n");
82                 printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
83                                 "(%d tasks refusing to freeze):\n",
84                                 elapsed_csecs / 100, elapsed_csecs % 100, todo);
85                 show_state();
86                 read_lock(&tasklist_lock);
87                 do_each_thread(g, p) {
88                         task_lock(p);
89                         if (freezing(p) && !freezer_should_skip(p))
90                                 printk(KERN_ERR " %s\n", p->comm);
91                         cancel_freezing(p);
92                         task_unlock(p);
93                 } while_each_thread(g, p);
94                 read_unlock(&tasklist_lock);
95         } else {
96                 printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
97                         elapsed_csecs % 100);
98         }
99
100         return todo ? -EBUSY : 0;
101 }
102
103 /**
104  *      freeze_processes - tell processes to enter the refrigerator
105  */
106 int freeze_processes(void)
107 {
108         int error;
109
110         printk("Freezing user space processes ... ");
111         error = try_to_freeze_tasks(true);
112         if (error)
113                 goto Exit;
114         printk("done.\n");
115
116         printk("Freezing remaining freezable tasks ... ");
117         error = try_to_freeze_tasks(false);
118         if (error)
119                 goto Exit;
120         printk("done.");
121
122         oom_killer_disable();
123  Exit:
124         BUG_ON(in_atomic());
125         printk("\n");
126
127         return error;
128 }
129
130 static void thaw_tasks(bool nosig_only)
131 {
132         struct task_struct *g, *p;
133
134         read_lock(&tasklist_lock);
135         do_each_thread(g, p) {
136                 if (!freezeable(p))
137                         continue;
138
139                 if (nosig_only && should_send_signal(p))
140                         continue;
141
142                 if (cgroup_frozen(p))
143                         continue;
144
145                 thaw_process(p);
146         } while_each_thread(g, p);
147         read_unlock(&tasklist_lock);
148 }
149
150 void thaw_processes(void)
151 {
152         oom_killer_enable();
153
154         printk("Restarting tasks ... ");
155         thaw_tasks(true);
156         thaw_tasks(false);
157         schedule();
158         printk("done.\n");
159 }
160