xref: /openbmc/linux/kernel/power/process.c (revision 39b6f3aa)
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 unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;
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 + msecs_to_jiffies(freeze_timeout_msecs);
40 
41 	if (!user_only)
42 		freeze_workqueues_begin();
43 
44 	while (true) {
45 		todo = 0;
46 		read_lock(&tasklist_lock);
47 		do_each_thread(g, p) {
48 			if (p == current || !freeze_task(p))
49 				continue;
50 
51 			if (!freezer_should_skip(p))
52 				todo++;
53 		} while_each_thread(g, p);
54 		read_unlock(&tasklist_lock);
55 
56 		if (!user_only) {
57 			wq_busy = freeze_workqueues_busy();
58 			todo += wq_busy;
59 		}
60 
61 		if (!todo || time_after(jiffies, end_time))
62 			break;
63 
64 		if (pm_wakeup_pending()) {
65 			wakeup = true;
66 			break;
67 		}
68 
69 		/*
70 		 * We need to retry, but first give the freezing tasks some
71 		 * time to enter the refrigerator.
72 		 */
73 		msleep(10);
74 	}
75 
76 	do_gettimeofday(&end);
77 	elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
78 	do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
79 	elapsed_csecs = elapsed_csecs64;
80 
81 	if (todo) {
82 		printk("\n");
83 		printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
84 		       "(%d tasks refusing to freeze, wq_busy=%d):\n",
85 		       wakeup ? "aborted" : "failed",
86 		       elapsed_csecs / 100, elapsed_csecs % 100,
87 		       todo - wq_busy, wq_busy);
88 
89 		if (!wakeup) {
90 			read_lock(&tasklist_lock);
91 			do_each_thread(g, p) {
92 				if (p != current && !freezer_should_skip(p)
93 				    && freezing(p) && !frozen(p))
94 					sched_show_task(p);
95 			} while_each_thread(g, p);
96 			read_unlock(&tasklist_lock);
97 		}
98 	} else {
99 		printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
100 			elapsed_csecs % 100);
101 	}
102 
103 	return todo ? -EBUSY : 0;
104 }
105 
106 /**
107  * freeze_processes - Signal user space processes to enter the refrigerator.
108  *
109  * On success, returns 0.  On failure, -errno and system is fully thawed.
110  */
111 int freeze_processes(void)
112 {
113 	int error;
114 
115 	error = __usermodehelper_disable(UMH_FREEZING);
116 	if (error)
117 		return error;
118 
119 	if (!pm_freezing)
120 		atomic_inc(&system_freezing_cnt);
121 
122 	printk("Freezing user space processes ... ");
123 	pm_freezing = true;
124 	error = try_to_freeze_tasks(true);
125 	if (!error) {
126 		printk("done.");
127 		__usermodehelper_set_disable_depth(UMH_DISABLED);
128 		oom_killer_disable();
129 	}
130 	printk("\n");
131 	BUG_ON(in_atomic());
132 
133 	if (error)
134 		thaw_processes();
135 	return error;
136 }
137 
138 /**
139  * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
140  *
141  * On success, returns 0.  On failure, -errno and only the kernel threads are
142  * thawed, so as to give a chance to the caller to do additional cleanups
143  * (if any) before thawing the userspace tasks. So, it is the responsibility
144  * of the caller to thaw the userspace tasks, when the time is right.
145  */
146 int freeze_kernel_threads(void)
147 {
148 	int error;
149 
150 	printk("Freezing remaining freezable tasks ... ");
151 	pm_nosig_freezing = true;
152 	error = try_to_freeze_tasks(false);
153 	if (!error)
154 		printk("done.");
155 
156 	printk("\n");
157 	BUG_ON(in_atomic());
158 
159 	if (error)
160 		thaw_kernel_threads();
161 	return error;
162 }
163 
164 void thaw_processes(void)
165 {
166 	struct task_struct *g, *p;
167 
168 	if (pm_freezing)
169 		atomic_dec(&system_freezing_cnt);
170 	pm_freezing = false;
171 	pm_nosig_freezing = false;
172 
173 	oom_killer_enable();
174 
175 	printk("Restarting tasks ... ");
176 
177 	thaw_workqueues();
178 
179 	read_lock(&tasklist_lock);
180 	do_each_thread(g, p) {
181 		__thaw_task(p);
182 	} while_each_thread(g, p);
183 	read_unlock(&tasklist_lock);
184 
185 	usermodehelper_enable();
186 
187 	schedule();
188 	printk("done.\n");
189 }
190 
191 void thaw_kernel_threads(void)
192 {
193 	struct task_struct *g, *p;
194 
195 	pm_nosig_freezing = false;
196 	printk("Restarting kernel threads ... ");
197 
198 	thaw_workqueues();
199 
200 	read_lock(&tasklist_lock);
201 	do_each_thread(g, p) {
202 		if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
203 			__thaw_task(p);
204 	} while_each_thread(g, p);
205 	read_unlock(&tasklist_lock);
206 
207 	schedule();
208 	printk("done.\n");
209 }
210