diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-28 13:00:53 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-28 13:00:53 +0200 |
commit | 207bc1181b1c03ab6ecb55bca5b307606dd1d6bc (patch) | |
tree | 018365e826918d709beae86717db5ee9e4215bc6 /kernel/freezer.c | |
parent | e8b6cb3947430d62538d88f615c007a51aeb23fe (diff) | |
parent | 2b15af6f953012aac49984ead3f8ec744d941540 (diff) | |
download | linux-207bc1181b1c03ab6ecb55bca5b307606dd1d6bc.tar.bz2 |
Merge branch 'freezer'
* freezer:
af_unix: use freezable blocking calls in read
sigtimedwait: use freezable blocking call
nanosleep: use freezable blocking call
futex: use freezable blocking call
select: use freezable blocking call
epoll: use freezable blocking call
binder: use freezable blocking calls
freezer: add new freezable helpers using freezer_do_not_count()
freezer: convert freezable helpers to static inline where possible
freezer: convert freezable helpers to freezer_do_not_count()
freezer: skip waking up tasks with PF_FREEZER_SKIP set
freezer: shorten freezer sleep time using exponential backoff
lockdep: check that no locks held at freeze time
lockdep: remove task argument from debug_check_no_locks_held
freezer: add unsafe versions of freezable helpers for CIFS
freezer: add unsafe versions of freezable helpers for NFS
Diffstat (limited to 'kernel/freezer.c')
-rw-r--r-- | kernel/freezer.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/kernel/freezer.c b/kernel/freezer.c index c38893b0efba..8b2afc1c9df0 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -110,6 +110,18 @@ bool freeze_task(struct task_struct *p) { unsigned long flags; + /* + * This check can race with freezer_do_not_count, but worst case that + * will result in an extra wakeup being sent to the task. It does not + * race with freezer_count(), the barriers in freezer_count() and + * freezer_should_skip() ensure that either freezer_count() sees + * freezing == true in try_to_freeze() and freezes, or + * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task + * normally. + */ + if (freezer_should_skip(p)) + return false; + spin_lock_irqsave(&freezer_lock, flags); if (!freezing(p) || frozen(p)) { spin_unlock_irqrestore(&freezer_lock, flags); |