blob: 00259a85c854a14b8c52472b8b5bb0980d8b5594 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <linux/interrupt.h>
Alexey Dobriyan1a8670a2009-09-21 17:03:09 -070012#include <linux/oom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/suspend.h>
14#include <linux/module.h>
Rafael J. Wysocki02aaeb92006-03-23 03:00:04 -080015#include <linux/syscalls.h>
Nigel Cunningham7dfb7102006-12-06 20:34:23 -080016#include <linux/freezer.h>
Tejun Heobe404f02009-10-08 22:47:30 +020017#include <linux/delay.h>
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020018#include <linux/workqueue.h>
Rafael J. Wysocki1e732032012-03-28 23:30:21 +020019#include <linux/kmod.h>
Arve Hjønnevåg677f1042008-10-14 16:02:39 -070020#include <linux/wakelock.h>
Bryan Huntsmand074fa22011-11-16 13:52:50 -080021#include "power.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070022
23/*
24 * Timeout for stopping processes
25 */
Rafael J. Wysocki02aaeb92006-03-23 03:00:04 -080026#define TIMEOUT (20 * HZ)
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Tejun Heo839e3402011-11-21 12:32:26 -080028static int try_to_freeze_tasks(bool user_only)
Linus Torvalds1da177e2005-04-16 15:20:36 -070029{
Linus Torvalds1da177e2005-04-16 15:20:36 -070030 struct task_struct *g, *p;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080031 unsigned long end_time;
32 unsigned int todo;
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020033 bool wq_busy = false;
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070034 struct timeval start, end;
David Howellsf0af5662008-07-23 21:28:44 -070035 u64 elapsed_csecs64;
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070036 unsigned int elapsed_csecs;
Rafael J. Wysockidbeeec52010-10-04 22:07:32 +020037 bool wakeup = false;
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070038
39 do_gettimeofday(&start);
Christoph Lameter3e1d1d22005-06-24 23:13:50 -070040
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080041 end_time = jiffies + TIMEOUT;
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020042
Tejun Heo839e3402011-11-21 12:32:26 -080043 if (!user_only)
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020044 freeze_workqueues_begin();
45
Tejun Heobe404f02009-10-08 22:47:30 +020046 while (true) {
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080047 todo = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 read_lock(&tasklist_lock);
49 do_each_thread(g, p) {
Tejun Heo839e3402011-11-21 12:32:26 -080050 if (p == current || !freeze_task(p))
Rafael J. Wysockid5d8c592007-10-18 03:04:46 -070051 continue;
52
Roland McGrath13b1c3d2008-03-03 20:22:05 -080053 /*
54 * Now that we've done set_freeze_flag, don't
55 * perturb a task in TASK_STOPPED or TASK_TRACED.
56 * It is "frozen enough". If the task does wake
57 * up, it will immediately call try_to_freeze.
Tejun Heo8cfe4002010-11-26 23:07:27 +010058 *
Marcos Paulo de Souza37f08be2012-02-21 23:57:47 +010059 * Because freeze_task() goes through p's scheduler lock, it's
60 * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING
61 * transition can't race with task state testing here.
Roland McGrath13b1c3d2008-03-03 20:22:05 -080062 */
63 if (!task_is_stopped_or_traced(p) &&
64 !freezer_should_skip(p))
Rafael J. Wysockiba96a0c2007-05-23 13:57:25 -070065 todo++;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 } while_each_thread(g, p);
67 read_unlock(&tasklist_lock);
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020068
Tejun Heo839e3402011-11-21 12:32:26 -080069 if (!user_only) {
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020070 wq_busy = freeze_workqueues_busy();
71 todo += wq_busy;
72 }
73
Arve Hjønnevåg677f1042008-10-14 16:02:39 -070074 if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) {
75 wakeup = 1;
76 break;
77 }
Tejun Heobe404f02009-10-08 22:47:30 +020078 if (!todo || time_after(jiffies, end_time))
Rafael J. Wysocki02aaeb92006-03-23 03:00:04 -080079 break;
Tejun Heobe404f02009-10-08 22:47:30 +020080
Rafael J. Wysockia2867e02010-12-03 22:58:31 +010081 if (pm_wakeup_pending()) {
Rafael J. Wysockidbeeec52010-10-04 22:07:32 +020082 wakeup = true;
83 break;
84 }
85
Tejun Heobe404f02009-10-08 22:47:30 +020086 /*
87 * We need to retry, but first give the freezing tasks some
88 * time to enter the regrigerator.
89 */
90 msleep(10);
91 }
Christoph Lameter3e1d1d22005-06-24 23:13:50 -070092
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070093 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
Pavel Machek6161b2c2005-09-03 15:57:05 -070098 if (todo) {
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080099 /* 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 */
Arve Hjønnevåg677f1042008-10-14 16:02:39 -0700104 if(wakeup) {
105 printk("\n");
106 printk(KERN_ERR "Freezing of %s aborted\n",
Steve Mucklef132c6c2012-06-06 18:30:57 -0700107 user_only ? "user space " : "tasks ");
Arve Hjønnevåg677f1042008-10-14 16:02:39 -0700108 }
109 else {
110 printk("\n");
Steve Mucklef132c6c2012-06-06 18:30:57 -0700111 printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
Arve Hjønnevåg677f1042008-10-14 16:02:39 -0700112 "(%d tasks refusing to freeze, wq_busy=%d):\n",
Steve Mucklef132c6c2012-06-06 18:30:57 -0700113 wakeup ? "aborted" : "failed",
Arve Hjønnevåg677f1042008-10-14 16:02:39 -0700114 elapsed_csecs / 100, elapsed_csecs % 100,
115 todo - wq_busy, wq_busy);
116 }
Tejun Heoa0a1a5f2010-06-29 10:07:12 +0200117
Rafael J. Wysocki6c83b482012-02-11 00:00:34 +0100118 if (!wakeup) {
119 read_lock(&tasklist_lock);
120 do_each_thread(g, p) {
121 if (p != current && !freezer_should_skip(p)
Steve Mucklef132c6c2012-06-06 18:30:57 -0700122 && freezing(p) && !frozen(p) &&
123 elapsed_csecs > 100)
Rafael J. Wysocki6c83b482012-02-11 00:00:34 +0100124 sched_show_task(p);
125 } while_each_thread(g, p);
126 read_unlock(&tasklist_lock);
127 }
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -0700128 } else {
129 printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
130 elapsed_csecs % 100);
Pavel Machek6161b2c2005-09-03 15:57:05 -0700131 }
132
Rafael J. Wysockie7cd8a72007-07-19 01:47:34 -0700133 return todo ? -EBUSY : 0;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800134}
135
136/**
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200137 * freeze_processes - Signal user space processes to enter the refrigerator.
Tejun Heo03afed82011-11-21 12:32:24 -0800138 *
139 * On success, returns 0. On failure, -errno and system is fully thawed.
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800140 */
141int freeze_processes(void)
142{
Rafael J. Wysockie7cd8a72007-07-19 01:47:34 -0700143 int error;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800144
Rafael J. Wysocki247bc032012-03-28 23:30:28 +0200145 error = __usermodehelper_disable(UMH_FREEZING);
Rafael J. Wysocki1e732032012-03-28 23:30:21 +0200146 if (error)
147 return error;
148
Tejun Heoa3201222011-11-21 12:32:25 -0800149 if (!pm_freezing)
150 atomic_inc(&system_freezing_cnt);
151
Rafael J. Wysockib842ee52007-10-18 03:04:48 -0700152 printk("Freezing user space processes ... ");
Tejun Heoa3201222011-11-21 12:32:25 -0800153 pm_freezing = true;
Rafael J. Wysockiebb12db2008-06-11 22:04:29 +0200154 error = try_to_freeze_tasks(true);
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200155 if (!error) {
156 printk("done.");
Rafael J. Wysocki247bc032012-03-28 23:30:28 +0200157 __usermodehelper_set_disable_depth(UMH_DISABLED);
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200158 oom_killer_disable();
159 }
160 printk("\n");
161 BUG_ON(in_atomic());
162
Tejun Heo03afed82011-11-21 12:32:24 -0800163 if (error)
164 thaw_processes();
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200165 return error;
166}
167
168/**
169 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
Tejun Heo03afed82011-11-21 12:32:24 -0800170 *
Srivatsa S. Bhat379e0be2012-02-03 22:22:41 +0100171 * On success, returns 0. On failure, -errno and only the kernel threads are
172 * thawed, so as to give a chance to the caller to do additional cleanups
173 * (if any) before thawing the userspace tasks. So, it is the responsibility
174 * of the caller to thaw the userspace tasks, when the time is right.
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200175 */
176int freeze_kernel_threads(void)
177{
178 int error;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800179
Steve Mucklef132c6c2012-06-06 18:30:57 -0700180 error = suspend_sys_sync_wait();
181 if (error)
182 return error;
Nigel Cunninghamff395932006-12-06 20:34:28 -0800183
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800184 printk("Freezing remaining freezable tasks ... ");
Tejun Heoa3201222011-11-21 12:32:25 -0800185 pm_nosig_freezing = true;
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800186 error = try_to_freeze_tasks(false);
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200187 if (!error)
188 printk("done.");
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 printk("\n");
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200191 BUG_ON(in_atomic());
Nigel Cunninghamff395932006-12-06 20:34:28 -0800192
Tejun Heo03afed82011-11-21 12:32:24 -0800193 if (error)
Srivatsa S. Bhat379e0be2012-02-03 22:22:41 +0100194 thaw_kernel_threads();
Nigel Cunninghamff395932006-12-06 20:34:28 -0800195 return error;
196}
197
Tejun Heo6cd8ded2011-11-21 12:32:23 -0800198void thaw_processes(void)
Nigel Cunninghamff395932006-12-06 20:34:28 -0800199{
200 struct task_struct *g, *p;
201
Tejun Heoa3201222011-11-21 12:32:25 -0800202 if (pm_freezing)
203 atomic_dec(&system_freezing_cnt);
204 pm_freezing = false;
205 pm_nosig_freezing = false;
206
Tejun Heo6cd8ded2011-11-21 12:32:23 -0800207 oom_killer_enable();
208
209 printk("Restarting tasks ... ");
210
211 thaw_workqueues();
212
Nigel Cunninghamff395932006-12-06 20:34:28 -0800213 read_lock(&tasklist_lock);
214 do_each_thread(g, p) {
Tejun Heoa5be2d02011-11-21 12:32:23 -0800215 __thaw_task(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 } while_each_thread(g, p);
217 read_unlock(&tasklist_lock);
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800218
Rafael J. Wysocki1e732032012-03-28 23:30:21 +0200219 usermodehelper_enable();
220
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 schedule();
Nigel Cunningham14b5b7c2006-12-06 20:34:26 -0800222 printk("done.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223}
224
Rafael J. Wysocki181e9bd2012-01-29 20:35:52 +0100225void thaw_kernel_threads(void)
226{
227 struct task_struct *g, *p;
228
229 pm_nosig_freezing = false;
230 printk("Restarting kernel threads ... ");
231
232 thaw_workqueues();
233
234 read_lock(&tasklist_lock);
235 do_each_thread(g, p) {
236 if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
237 __thaw_task(p);
238 } while_each_thread(g, p);
239 read_unlock(&tasklist_lock);
240
241 schedule();
242 printk("done.\n");
243}