Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
process.c
Go to the documentation of this file.
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 #include <linux/delay.h>
18 #include <linux/workqueue.h>
19 #include <linux/kmod.h>
20 
21 /*
22  * Timeout for stopping processes
23  */
24 #define TIMEOUT (20 * HZ)
25 
26 static int try_to_freeze_tasks(bool user_only)
27 {
28  struct task_struct *g, *p;
29  unsigned long end_time;
30  unsigned int todo;
31  bool wq_busy = false;
32  struct timeval start, end;
33  u64 elapsed_csecs64;
34  unsigned int elapsed_csecs;
35  bool wakeup = false;
36 
37  do_gettimeofday(&start);
38 
39  end_time = jiffies + TIMEOUT;
40 
41  if (!user_only)
42  freeze_workqueues_begin();
43 
44  while (true) {
45  todo = 0;
47  do_each_thread(g, p) {
48  if (p == current || !freeze_task(p))
49  continue;
50 
51  /*
52  * Now that we've done set_freeze_flag, don't
53  * perturb a task in TASK_STOPPED or TASK_TRACED.
54  * It is "frozen enough". If the task does wake
55  * up, it will immediately call try_to_freeze.
56  *
57  * Because freeze_task() goes through p's scheduler lock, it's
58  * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING
59  * transition can't race with task state testing here.
60  */
61  if (!task_is_stopped_or_traced(p) &&
62  !freezer_should_skip(p))
63  todo++;
64  } while_each_thread(g, p);
66 
67  if (!user_only) {
68  wq_busy = freeze_workqueues_busy();
69  todo += wq_busy;
70  }
71 
72  if (!todo || time_after(jiffies, end_time))
73  break;
74 
75  if (pm_wakeup_pending()) {
76  wakeup = true;
77  break;
78  }
79 
80  /*
81  * We need to retry, but first give the freezing tasks some
82  * time to enter the refrigerator.
83  */
84  msleep(10);
85  }
86 
87  do_gettimeofday(&end);
88  elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
89  do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
90  elapsed_csecs = elapsed_csecs64;
91 
92  if (todo) {
93  printk("\n");
94  printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
95  "(%d tasks refusing to freeze, wq_busy=%d):\n",
96  wakeup ? "aborted" : "failed",
97  elapsed_csecs / 100, elapsed_csecs % 100,
98  todo - wq_busy, wq_busy);
99 
100  if (!wakeup) {
102  do_each_thread(g, p) {
103  if (p != current && !freezer_should_skip(p)
104  && freezing(p) && !frozen(p))
105  sched_show_task(p);
106  } while_each_thread(g, p);
108  }
109  } else {
110  printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
111  elapsed_csecs % 100);
112  }
113 
114  return todo ? -EBUSY : 0;
115 }
116 
123 {
124  int error;
125 
127  if (error)
128  return error;
129 
130  if (!pm_freezing)
132 
133  printk("Freezing user space processes ... ");
134  pm_freezing = true;
135  error = try_to_freeze_tasks(true);
136  if (!error) {
137  printk("done.");
139  oom_killer_disable();
140  }
141  printk("\n");
142  BUG_ON(in_atomic());
143 
144  if (error)
145  thaw_processes();
146  return error;
147 }
148 
158 {
159  int error;
160 
161  printk("Freezing remaining freezable tasks ... ");
162  pm_nosig_freezing = true;
163  error = try_to_freeze_tasks(false);
164  if (!error)
165  printk("done.");
166 
167  printk("\n");
168  BUG_ON(in_atomic());
169 
170  if (error)
172  return error;
173 }
174 
175 void thaw_processes(void)
176 {
177  struct task_struct *g, *p;
178 
179  if (pm_freezing)
181  pm_freezing = false;
182  pm_nosig_freezing = false;
183 
184  oom_killer_enable();
185 
186  printk("Restarting tasks ... ");
187 
188  thaw_workqueues();
189 
191  do_each_thread(g, p) {
192  __thaw_task(p);
193  } while_each_thread(g, p);
195 
196  usermodehelper_enable();
197 
198  schedule();
199  printk("done.\n");
200 }
201 
203 {
204  struct task_struct *g, *p;
205 
206  pm_nosig_freezing = false;
207  printk("Restarting kernel threads ... ");
208 
209  thaw_workqueues();
210 
212  do_each_thread(g, p) {
213  if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
214  __thaw_task(p);
215  } while_each_thread(g, p);
217 
218  schedule();
219  printk("done.\n");
220 }