1
2
3#ifndef FREEZER_H_INCLUDED
4#define FREEZER_H_INCLUDED
5
6#include <linux/debug_locks.h>
7#include <linux/sched.h>
8#include <linux/wait.h>
9#include <linux/atomic.h>
10
11#ifdef CONFIG_FREEZER
12extern atomic_t system_freezing_cnt;
13extern bool pm_freezing;
14extern bool pm_nosig_freezing;
15
16
17
18
19extern unsigned int freeze_timeout_msecs;
20
21
22
23
24static inline bool frozen(struct task_struct *p)
25{
26 return p->flags & PF_FROZEN;
27}
28
29extern bool freezing_slow_path(struct task_struct *p);
30
31
32
33
34static inline bool freezing(struct task_struct *p)
35{
36 if (likely(!atomic_read(&system_freezing_cnt)))
37 return false;
38 return freezing_slow_path(p);
39}
40
41
42extern void __thaw_task(struct task_struct *t);
43
44extern bool __refrigerator(bool check_kthr_stop);
45extern int freeze_processes(void);
46extern int freeze_kernel_threads(void);
47extern void thaw_processes(void);
48extern void thaw_kernel_threads(void);
49
50
51
52
53
54static inline bool try_to_freeze_unsafe(void)
55{
56 might_sleep();
57 if (likely(!freezing(current)))
58 return false;
59 return __refrigerator(false);
60}
61
62static inline bool try_to_freeze(void)
63{
64 if (!(current->flags & PF_NOFREEZE))
65 debug_check_no_locks_held();
66 return try_to_freeze_unsafe();
67}
68
69extern bool freeze_task(struct task_struct *p);
70extern bool set_freezable(void);
71
72#ifdef CONFIG_CGROUP_FREEZER
73extern bool cgroup_freezing(struct task_struct *task);
74#else
75static inline bool cgroup_freezing(struct task_struct *task)
76{
77 return false;
78}
79#endif
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106static inline void freezer_do_not_count(void)
107{
108 current->flags |= PF_FREEZER_SKIP;
109}
110
111
112
113
114
115
116
117
118static inline void freezer_count(void)
119{
120 current->flags &= ~PF_FREEZER_SKIP;
121
122
123
124
125
126 smp_mb();
127 try_to_freeze();
128}
129
130
131static inline void freezer_count_unsafe(void)
132{
133 current->flags &= ~PF_FREEZER_SKIP;
134 smp_mb();
135 try_to_freeze_unsafe();
136}
137
138
139
140
141
142
143
144
145
146
147
148static inline bool freezer_should_skip(struct task_struct *p)
149{
150
151
152
153
154
155
156
157 smp_mb();
158 return p->flags & PF_FREEZER_SKIP;
159}
160
161
162
163
164
165
166
167
168static inline void freezable_schedule(void)
169{
170 freezer_do_not_count();
171 schedule();
172 freezer_count();
173}
174
175
176static inline void freezable_schedule_unsafe(void)
177{
178 freezer_do_not_count();
179 schedule();
180 freezer_count_unsafe();
181}
182
183
184
185
186
187static inline long freezable_schedule_timeout(long timeout)
188{
189 long __retval;
190 freezer_do_not_count();
191 __retval = schedule_timeout(timeout);
192 freezer_count();
193 return __retval;
194}
195
196
197
198
199
200static inline long freezable_schedule_timeout_interruptible(long timeout)
201{
202 long __retval;
203 freezer_do_not_count();
204 __retval = schedule_timeout_interruptible(timeout);
205 freezer_count();
206 return __retval;
207}
208
209
210static inline long freezable_schedule_timeout_killable(long timeout)
211{
212 long __retval;
213 freezer_do_not_count();
214 __retval = schedule_timeout_killable(timeout);
215 freezer_count();
216 return __retval;
217}
218
219
220static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
221{
222 long __retval;
223 freezer_do_not_count();
224 __retval = schedule_timeout_killable(timeout);
225 freezer_count_unsafe();
226 return __retval;
227}
228
229
230
231
232
233static inline int freezable_schedule_hrtimeout_range(ktime_t *expires,
234 unsigned long delta, const enum hrtimer_mode mode)
235{
236 int __retval;
237 freezer_do_not_count();
238 __retval = schedule_hrtimeout_range(expires, delta, mode);
239 freezer_count();
240 return __retval;
241}
242
243
244
245
246
247
248
249#define wait_event_freezekillable(wq, condition) \
250({ \
251 int __retval; \
252 freezer_do_not_count(); \
253 __retval = wait_event_killable(wq, (condition)); \
254 freezer_count(); \
255 __retval; \
256})
257
258
259#define wait_event_freezekillable_unsafe(wq, condition) \
260({ \
261 int __retval; \
262 freezer_do_not_count(); \
263 __retval = wait_event_killable(wq, (condition)); \
264 freezer_count_unsafe(); \
265 __retval; \
266})
267
268#define wait_event_freezable(wq, condition) \
269({ \
270 int __retval; \
271 freezer_do_not_count(); \
272 __retval = wait_event_interruptible(wq, (condition)); \
273 freezer_count(); \
274 __retval; \
275})
276
277#define wait_event_freezable_timeout(wq, condition, timeout) \
278({ \
279 long __retval = timeout; \
280 freezer_do_not_count(); \
281 __retval = wait_event_interruptible_timeout(wq, (condition), \
282 __retval); \
283 freezer_count(); \
284 __retval; \
285})
286
287#define wait_event_freezable_exclusive(wq, condition) \
288({ \
289 int __retval; \
290 freezer_do_not_count(); \
291 __retval = wait_event_interruptible_exclusive(wq, condition); \
292 freezer_count(); \
293 __retval; \
294})
295
296
297#else
298static inline bool frozen(struct task_struct *p) { return false; }
299static inline bool freezing(struct task_struct *p) { return false; }
300static inline void __thaw_task(struct task_struct *t) {}
301
302static inline bool __refrigerator(bool check_kthr_stop) { return false; }
303static inline int freeze_processes(void) { return -ENOSYS; }
304static inline int freeze_kernel_threads(void) { return -ENOSYS; }
305static inline void thaw_processes(void) {}
306static inline void thaw_kernel_threads(void) {}
307
308static inline bool try_to_freeze_nowarn(void) { return false; }
309static inline bool try_to_freeze(void) { return false; }
310
311static inline void freezer_do_not_count(void) {}
312static inline void freezer_count(void) {}
313static inline int freezer_should_skip(struct task_struct *p) { return 0; }
314static inline void set_freezable(void) {}
315
316#define freezable_schedule() schedule()
317
318#define freezable_schedule_unsafe() schedule()
319
320#define freezable_schedule_timeout(timeout) schedule_timeout(timeout)
321
322#define freezable_schedule_timeout_interruptible(timeout) \
323 schedule_timeout_interruptible(timeout)
324
325#define freezable_schedule_timeout_killable(timeout) \
326 schedule_timeout_killable(timeout)
327
328#define freezable_schedule_timeout_killable_unsafe(timeout) \
329 schedule_timeout_killable(timeout)
330
331#define freezable_schedule_hrtimeout_range(expires, delta, mode) \
332 schedule_hrtimeout_range(expires, delta, mode)
333
334#define wait_event_freezable(wq, condition) \
335 wait_event_interruptible(wq, condition)
336
337#define wait_event_freezable_timeout(wq, condition, timeout) \
338 wait_event_interruptible_timeout(wq, condition, timeout)
339
340#define wait_event_freezable_exclusive(wq, condition) \
341 wait_event_interruptible_exclusive(wq, condition)
342
343#define wait_event_freezekillable(wq, condition) \
344 wait_event_killable(wq, condition)
345
346#define wait_event_freezekillable_unsafe(wq, condition) \
347 wait_event_killable(wq, condition)
348
349#endif
350
351#endif
352