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 u64 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
250#define wait_event_freezekillable_unsafe(wq, condition) \
251({ \
252 int __retval; \
253 freezer_do_not_count(); \
254 __retval = wait_event_killable(wq, (condition)); \
255 freezer_count_unsafe(); \
256 __retval; \
257})
258
259#else
260static inline bool frozen(struct task_struct *p) { return false; }
261static inline bool freezing(struct task_struct *p) { return false; }
262static inline void __thaw_task(struct task_struct *t) {}
263
264static inline bool __refrigerator(bool check_kthr_stop) { return false; }
265static inline int freeze_processes(void) { return -ENOSYS; }
266static inline int freeze_kernel_threads(void) { return -ENOSYS; }
267static inline void thaw_processes(void) {}
268static inline void thaw_kernel_threads(void) {}
269
270static inline bool try_to_freeze_nowarn(void) { return false; }
271static inline bool try_to_freeze(void) { return false; }
272
273static inline void freezer_do_not_count(void) {}
274static inline void freezer_count(void) {}
275static inline int freezer_should_skip(struct task_struct *p) { return 0; }
276static inline void set_freezable(void) {}
277
278#define freezable_schedule() schedule()
279
280#define freezable_schedule_unsafe() schedule()
281
282#define freezable_schedule_timeout(timeout) schedule_timeout(timeout)
283
284#define freezable_schedule_timeout_interruptible(timeout) \
285 schedule_timeout_interruptible(timeout)
286
287#define freezable_schedule_timeout_killable(timeout) \
288 schedule_timeout_killable(timeout)
289
290#define freezable_schedule_timeout_killable_unsafe(timeout) \
291 schedule_timeout_killable(timeout)
292
293#define freezable_schedule_hrtimeout_range(expires, delta, mode) \
294 schedule_hrtimeout_range(expires, delta, mode)
295
296#define wait_event_freezekillable_unsafe(wq, condition) \
297 wait_event_killable(wq, condition)
298
299#endif
300
301#endif
302