blob: 2d1e6241bc67f2b84ffe9c699df317bce3869217 [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;
Steve Kondik464aaea2014-01-18 03:12:00 -080031 struct task_struct *q = NULL;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080032 unsigned long end_time;
33 unsigned int todo;
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020034 bool wq_busy = false;
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070035 struct timeval start, end;
Colin Crossfd34c9b2013-05-06 23:50:10 +000036 u64 elapsed_msecs64;
37 unsigned int elapsed_msecs;
Rafael J. Wysockidbeeec52010-10-04 22:07:32 +020038 bool wakeup = false;
Colin Crossfd34c9b2013-05-06 23:50:10 +000039 int sleep_usecs = USEC_PER_MSEC;
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070040
41 do_gettimeofday(&start);
Christoph Lameter3e1d1d22005-06-24 23:13:50 -070042
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080043 end_time = jiffies + TIMEOUT;
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020044
Tejun Heo839e3402011-11-21 12:32:26 -080045 if (!user_only)
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020046 freeze_workqueues_begin();
47
Tejun Heobe404f02009-10-08 22:47:30 +020048 while (true) {
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -080049 todo = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 read_lock(&tasklist_lock);
51 do_each_thread(g, p) {
Tejun Heo839e3402011-11-21 12:32:26 -080052 if (p == current || !freeze_task(p))
Rafael J. Wysockid5d8c592007-10-18 03:04:46 -070053 continue;
54
Roland McGrath13b1c3d2008-03-03 20:22:05 -080055 /*
56 * Now that we've done set_freeze_flag, don't
57 * perturb a task in TASK_STOPPED or TASK_TRACED.
58 * It is "frozen enough". If the task does wake
59 * up, it will immediately call try_to_freeze.
Tejun Heo8cfe4002010-11-26 23:07:27 +010060 *
Marcos Paulo de Souza37f08be2012-02-21 23:57:47 +010061 * Because freeze_task() goes through p's scheduler lock, it's
62 * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING
63 * transition can't race with task state testing here.
Roland McGrath13b1c3d2008-03-03 20:22:05 -080064 */
65 if (!task_is_stopped_or_traced(p) &&
Steve Kondik464aaea2014-01-18 03:12:00 -080066 !freezer_should_skip(p)) {
Rafael J. Wysockiba96a0c2007-05-23 13:57:25 -070067 todo++;
Steve Kondik464aaea2014-01-18 03:12:00 -080068 q = p;
69 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 } while_each_thread(g, p);
71 read_unlock(&tasklist_lock);
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020072
Tejun Heo839e3402011-11-21 12:32:26 -080073 if (!user_only) {
Tejun Heoa0a1a5f2010-06-29 10:07:12 +020074 wq_busy = freeze_workqueues_busy();
75 todo += wq_busy;
76 }
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
Colin Crossfd34c9b2013-05-06 23:50:10 +000088 * time to enter the refrigerator. Start with an initial
89 * 1 ms sleep followed by exponential backoff until 8 ms.
Tejun Heobe404f02009-10-08 22:47:30 +020090 */
Colin Crossfd34c9b2013-05-06 23:50:10 +000091 usleep_range(sleep_usecs / 2, sleep_usecs);
92 if (sleep_usecs < 8 * USEC_PER_MSEC)
93 sleep_usecs *= 2;
Tejun Heobe404f02009-10-08 22:47:30 +020094 }
Christoph Lameter3e1d1d22005-06-24 23:13:50 -070095
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -070096 do_gettimeofday(&end);
Colin Crossfd34c9b2013-05-06 23:50:10 +000097 elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
98 do_div(elapsed_msecs64, NSEC_PER_MSEC);
99 elapsed_msecs = elapsed_msecs64;
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -0700100
Pavel Machek6161b2c2005-09-03 15:57:05 -0700101 if (todo) {
Iliyan Malchev51e8b072013-07-01 12:50:39 -0700102 printk("\n");
Colin Crossfd34c9b2013-05-06 23:50:10 +0000103 printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds "
Iliyan Malchev51e8b072013-07-01 12:50:39 -0700104 "(%d tasks refusing to freeze, wq_busy=%d):\n",
105 wakeup ? "aborted" : "failed",
Colin Crossfd34c9b2013-05-06 23:50:10 +0000106 elapsed_msecs / 1000, elapsed_msecs % 1000,
Iliyan Malchev51e8b072013-07-01 12:50:39 -0700107 todo - wq_busy, wq_busy);
Tejun Heoa0a1a5f2010-06-29 10:07:12 +0200108
Rafael J. Wysocki6c83b482012-02-11 00:00:34 +0100109 if (!wakeup) {
110 read_lock(&tasklist_lock);
111 do_each_thread(g, p) {
112 if (p != current && !freezer_should_skip(p)
Iliyan Malchev51e8b072013-07-01 12:50:39 -0700113 && freezing(p) && !frozen(p))
Rafael J. Wysocki6c83b482012-02-11 00:00:34 +0100114 sched_show_task(p);
115 } while_each_thread(g, p);
116 read_unlock(&tasklist_lock);
117 }
Rafael J. Wysocki438e2ce2007-10-18 03:04:49 -0700118 } else {
Colin Crossfd34c9b2013-05-06 23:50:10 +0000119 printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
120 elapsed_msecs % 1000);
Pavel Machek6161b2c2005-09-03 15:57:05 -0700121 }
122
Rafael J. Wysockie7cd8a72007-07-19 01:47:34 -0700123 return todo ? -EBUSY : 0;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800124}
125
126/**
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200127 * freeze_processes - Signal user space processes to enter the refrigerator.
Tejun Heo03afed82011-11-21 12:32:24 -0800128 *
129 * On success, returns 0. On failure, -errno and system is fully thawed.
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800130 */
131int freeze_processes(void)
132{
Rafael J. Wysockie7cd8a72007-07-19 01:47:34 -0700133 int error;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800134
Rafael J. Wysocki247bc032012-03-28 23:30:28 +0200135 error = __usermodehelper_disable(UMH_FREEZING);
Rafael J. Wysocki1e732032012-03-28 23:30:21 +0200136 if (error)
137 return error;
138
Tejun Heoa3201222011-11-21 12:32:25 -0800139 if (!pm_freezing)
140 atomic_inc(&system_freezing_cnt);
141
Rafael J. Wysockib842ee52007-10-18 03:04:48 -0700142 printk("Freezing user space processes ... ");
Tejun Heoa3201222011-11-21 12:32:25 -0800143 pm_freezing = true;
Rafael J. Wysockiebb12db2008-06-11 22:04:29 +0200144 error = try_to_freeze_tasks(true);
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200145 if (!error) {
146 printk("done.");
Rafael J. Wysocki247bc032012-03-28 23:30:28 +0200147 __usermodehelper_set_disable_depth(UMH_DISABLED);
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200148 oom_killer_disable();
149 }
150 printk("\n");
151 BUG_ON(in_atomic());
152
Tejun Heo03afed82011-11-21 12:32:24 -0800153 if (error)
154 thaw_processes();
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200155 return error;
156}
157
158/**
159 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
Tejun Heo03afed82011-11-21 12:32:24 -0800160 *
Srivatsa S. Bhat379e0be2012-02-03 22:22:41 +0100161 * On success, returns 0. On failure, -errno and only the kernel threads are
162 * thawed, so as to give a chance to the caller to do additional cleanups
163 * (if any) before thawing the userspace tasks. So, it is the responsibility
164 * of the caller to thaw the userspace tasks, when the time is right.
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200165 */
166int freeze_kernel_threads(void)
167{
168 int error;
Rafael J. Wysocki11b2ce22006-12-06 20:34:40 -0800169
Rafael J. Wysockib842ee52007-10-18 03:04:48 -0700170 printk("Freezing remaining freezable tasks ... ");
Tejun Heoa3201222011-11-21 12:32:25 -0800171 pm_nosig_freezing = true;
Rafael J. Wysockiebb12db2008-06-11 22:04:29 +0200172 error = try_to_freeze_tasks(false);
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200173 if (!error)
174 printk("done.");
Rafael J. Wysocki7f33d492009-06-16 15:32:41 -0700175
Rafael J. Wysockib842ee52007-10-18 03:04:48 -0700176 printk("\n");
Rafael J. Wysocki2aede852011-09-26 20:32:27 +0200177 BUG_ON(in_atomic());
Rafael J. Wysocki7f33d492009-06-16 15:32:41 -0700178
Tejun Heo03afed82011-11-21 12:32:24 -0800179 if (error)
Srivatsa S. Bhat379e0be2012-02-03 22:22:41 +0100180 thaw_kernel_threads();
Rafael J. Wysockib842ee52007-10-18 03:04:48 -0700181 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182}
183
Tejun Heo6cd8ded2011-11-21 12:32:23 -0800184void thaw_processes(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185{
186 struct task_struct *g, *p;
187
Tejun Heoa3201222011-11-21 12:32:25 -0800188 if (pm_freezing)
189 atomic_dec(&system_freezing_cnt);
190 pm_freezing = false;
191 pm_nosig_freezing = false;
192
Tejun Heo6cd8ded2011-11-21 12:32:23 -0800193 oom_killer_enable();
194
195 printk("Restarting tasks ... ");
196
197 thaw_workqueues();
198
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 read_lock(&tasklist_lock);
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800200 do_each_thread(g, p) {
Tejun Heoa5be2d02011-11-21 12:32:23 -0800201 __thaw_task(p);
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800202 } while_each_thread(g, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 read_unlock(&tasklist_lock);
Rafael J. Wysockia9b6f562006-12-06 20:34:37 -0800204
Rafael J. Wysocki1e732032012-03-28 23:30:21 +0200205 usermodehelper_enable();
206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 schedule();
Nigel Cunningham14b5b7c2006-12-06 20:34:26 -0800208 printk("done.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209}
210
Rafael J. Wysocki181e9bd2012-01-29 20:35:52 +0100211void thaw_kernel_threads(void)
212{
213 struct task_struct *g, *p;
214
215 pm_nosig_freezing = false;
216 printk("Restarting kernel threads ... ");
217
218 thaw_workqueues();
219
220 read_lock(&tasklist_lock);
221 do_each_thread(g, p) {
222 if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
223 __thaw_task(p);
224 } while_each_thread(g, p);
225 read_unlock(&tasklist_lock);
226
227 schedule();
228 printk("done.\n");
229}