freezer: skip waking up tasks with PF_FREEZER_SKIP set
authorColin Cross <ccross@android.com>
Mon, 6 May 2013 23:50:11 +0000 (23:50 +0000)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sun, 12 May 2013 12:16:22 +0000 (14:16 +0200)
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>
kernel/freezer.c

index c38893b0efbaa39d770b11546dba9e97ec53ff51..8b2afc1c9df0c698eccd86664d25c33ed647fea7 100644 (file)
@@ -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);