freezer: test freezable conditions while holding freezer_lock
authorTejun Heo <tj@kernel.org>
Mon, 21 Nov 2011 20:32:24 +0000 (12:32 -0800)
committerTejun Heo <tj@kernel.org>
Mon, 21 Nov 2011 20:32:24 +0000 (12:32 -0800)
try_to_freeze_tasks() and thaw_processes() use freezable() and
frozen() as preliminary tests before initiating operations on a task.
These are done without any synchronization and hinder with
synchronization cleanup without any real performance benefits.

In try_to_freeze_tasks(), open code self test and move PF_NOFREEZE and
frozen() tests inside freezer_lock in freeze_task().

thaw_processes() can simply drop freezable() test as frozen() test in
__thaw_task() is enough.

Note: This used to be a part of larger patch to fix set_freezable()
      race.  Separated out to satisfy ordering among dependent fixes.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
kernel/freezer.c
kernel/power/process.c

index a8822be..a257ecd 100644 (file)
@@ -109,7 +109,8 @@ bool freeze_task(struct task_struct *p, bool sig_only)
 
        spin_lock_irqsave(&freezer_lock, flags);
 
-       if (sig_only && !should_send_signal(p))
+       if ((p->flags & PF_NOFREEZE) ||
+           (sig_only && !should_send_signal(p)))
                goto out_unlock;
 
        if (frozen(p))
index e6e2739..e59676f 100644 (file)
  */
 #define TIMEOUT        (20 * HZ)
 
-static inline int freezable(struct task_struct * p)
-{
-       if ((p == current) ||
-           (p->flags & PF_NOFREEZE))
-               return 0;
-       return 1;
-}
-
 static int try_to_freeze_tasks(bool sig_only)
 {
        struct task_struct *g, *p;
@@ -52,10 +44,7 @@ static int try_to_freeze_tasks(bool sig_only)
                todo = 0;
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       if (frozen(p) || !freezable(p))
-                               continue;
-
-                       if (!freeze_task(p, sig_only))
+                       if (p == current || !freeze_task(p, sig_only))
                                continue;
 
                        /*
@@ -181,9 +170,6 @@ void thaw_processes(void)
 
        read_lock(&tasklist_lock);
        do_each_thread(g, p) {
-               if (!freezable(p))
-                       continue;
-
                if (cgroup_freezing_or_frozen(p))
                        continue;