diff options
author | Colin Cross <ccross@android.com> | 2013-05-06 19:50:11 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-05-12 08:16:22 -0400 |
commit | 613f5d13b569859171f0896fbc73ee0bfa811fda (patch) | |
tree | 92f3f25db1fe1063624cc0ef69506d2f38a1988a /kernel/freezer.c | |
parent | 18ad0c6297df1d671ecea83b608cd9e432642a05 (diff) |
freezer: skip waking up tasks with PF_FREEZER_SKIP set
Android goes through suspend/resume very often (every few seconds when
on a busy wifi network with the screen off), and a significant portion
of the energy used to go in and out of suspend is spent in the
freezer. If a task has called freezer_do_not_count(), don't bother
waking it up. If it happens to wake up later it will call
freezer_count() and immediately enter the refrigerator.
Combined with patches to convert freezable helpers to use
freezer_do_not_count() and convert common sites where idle userspace
tasks are blocked to use the freezable helpers, this reduces the
time and energy required to suspend and resume.
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Colin Cross <ccross@android.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
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) | |||
110 | { | 110 | { |
111 | unsigned long flags; | 111 | unsigned long flags; |
112 | 112 | ||
113 | /* | ||
114 | * This check can race with freezer_do_not_count, but worst case that | ||
115 | * will result in an extra wakeup being sent to the task. It does not | ||
116 | * race with freezer_count(), the barriers in freezer_count() and | ||
117 | * freezer_should_skip() ensure that either freezer_count() sees | ||
118 | * freezing == true in try_to_freeze() and freezes, or | ||
119 | * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task | ||
120 | * normally. | ||
121 | */ | ||
122 | if (freezer_should_skip(p)) | ||
123 | return false; | ||
124 | |||
113 | spin_lock_irqsave(&freezer_lock, flags); | 125 | spin_lock_irqsave(&freezer_lock, flags); |
114 | if (!freezing(p) || frozen(p)) { | 126 | if (!freezing(p) || frozen(p)) { |
115 | spin_unlock_irqrestore(&freezer_lock, flags); | 127 | spin_unlock_irqrestore(&freezer_lock, flags); |