aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/freezer.h
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2013-05-06 19:50:14 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-05-12 08:16:22 -0400
commitdd5ec0f4e72bed3d0e589e21fdf46eedafc106b7 (patch)
tree5c6d29cb3b1b6db27fab0470e3892e12fd2a9f78 /include/linux/freezer.h
parent8ee492d6595573a0d4be168ebda1c7ceb4ec509d (diff)
freezer: add new freezable helpers using freezer_do_not_count()
Freezing tasks will wake up almost every userspace task from where it is blocking and force it to run until it hits a call to try_to_sleep(), generally on the exit path from the syscall it is blocking in. On resume each task will run again, usually restarting the syscall and running until it hits the same blocking call as it was originally blocked in. To allow tasks to avoid running on every suspend/resume cycle, this patch adds additional freezable wrappers around blocking calls that call freezer_do_not_count(). Combined with the previous patch, these tasks will not run during suspend or resume unless they wake up for another reason, in which case they will run until they hit the try_to_freeze() in freezer_count(), and then continue processing the wakeup after tasks are thawed. Additional patches will convert the most common locations that userspace blocks in to use freezable helpers. Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'include/linux/freezer.h')
-rw-r--r--include/linux/freezer.h61
1 files changed, 61 insertions, 0 deletions
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 8430d4c51ece..7fd81b8c4897 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -180,6 +180,32 @@ static inline void freezable_schedule_unsafe(void)
180 freezer_count_unsafe(); 180 freezer_count_unsafe();
181} 181}
182 182
183/*
184 * Like freezable_schedule_timeout(), but should not block the freezer. Do not
185 * call this with locks held.
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 * Like schedule_timeout_interruptible(), but should not block the freezer. Do not
198 * call this with locks held.
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
183/* Like schedule_timeout_killable(), but should not block the freezer. */ 209/* Like schedule_timeout_killable(), but should not block the freezer. */
184static inline long freezable_schedule_timeout_killable(long timeout) 210static inline long freezable_schedule_timeout_killable(long timeout)
185{ 211{
@@ -201,6 +227,20 @@ static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
201} 227}
202 228
203/* 229/*
230 * Like schedule_hrtimeout_range(), but should not block the freezer. Do not
231 * call this with locks held.
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/*
204 * Freezer-friendly wrappers around wait_event_interruptible(), 244 * Freezer-friendly wrappers around wait_event_interruptible(),
205 * wait_event_killable() and wait_event_interruptible_timeout(), originally 245 * wait_event_killable() and wait_event_interruptible_timeout(), originally
206 * defined in <linux/wait.h> 246 * defined in <linux/wait.h>
@@ -244,6 +284,16 @@ static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
244 __retval; \ 284 __retval; \
245}) 285})
246 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
247#else /* !CONFIG_FREEZER */ 297#else /* !CONFIG_FREEZER */
248static inline bool frozen(struct task_struct *p) { return false; } 298static inline bool frozen(struct task_struct *p) { return false; }
249static inline bool freezing(struct task_struct *p) { return false; } 299static inline bool freezing(struct task_struct *p) { return false; }
@@ -267,18 +317,29 @@ static inline void set_freezable(void) {}
267 317
268#define freezable_schedule_unsafe() schedule() 318#define freezable_schedule_unsafe() schedule()
269 319
320#define freezable_schedule_timeout(timeout) schedule_timeout(timeout)
321
322#define freezable_schedule_timeout_interruptible(timeout) \
323 schedule_timeout_interruptible(timeout)
324
270#define freezable_schedule_timeout_killable(timeout) \ 325#define freezable_schedule_timeout_killable(timeout) \
271 schedule_timeout_killable(timeout) 326 schedule_timeout_killable(timeout)
272 327
273#define freezable_schedule_timeout_killable_unsafe(timeout) \ 328#define freezable_schedule_timeout_killable_unsafe(timeout) \
274 schedule_timeout_killable(timeout) 329 schedule_timeout_killable(timeout)
275 330
331#define freezable_schedule_hrtimeout_range(expires, delta, mode) \
332 schedule_hrtimeout_range(expires, delta, mode)
333
276#define wait_event_freezable(wq, condition) \ 334#define wait_event_freezable(wq, condition) \
277 wait_event_interruptible(wq, condition) 335 wait_event_interruptible(wq, condition)
278 336
279#define wait_event_freezable_timeout(wq, condition, timeout) \ 337#define wait_event_freezable_timeout(wq, condition, timeout) \
280 wait_event_interruptible_timeout(wq, condition, timeout) 338 wait_event_interruptible_timeout(wq, condition, timeout)
281 339
340#define wait_event_freezable_exclusive(wq, condition) \
341 wait_event_interruptible_exclusive(wq, condition)
342
282#define wait_event_freezekillable(wq, condition) \ 343#define wait_event_freezekillable(wq, condition) \
283 wait_event_killable(wq, condition) 344 wait_event_killable(wq, condition)
284 345