cgroup_freezer: prepare for removal of TIF_FREEZE
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / kernel / power / process.c
index addbbe5531bc42634c78844f5d93796526cb13ec..9f6f5c755cfa5831cef6d4e123b2dcdb4129807a 100644 (file)
  */
 #define TIMEOUT        (20 * HZ)
 
-static inline int freezable(struct task_struct * p)
-{
-       if ((p == current) ||
-           (p->flags & PF_NOFREEZE) ||
-           (p->exit_state != 0))
-               return 0;
-       return 1;
-}
-
 static int try_to_freeze_tasks(bool sig_only)
 {
        struct task_struct *g, *p;
@@ -53,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;
 
                        /*
@@ -103,11 +91,6 @@ static int try_to_freeze_tasks(bool sig_only)
        elapsed_csecs = elapsed_csecs64;
 
        if (todo) {
-               /* This does not unfreeze processes that are already frozen
-                * (we have slightly ugly calling convention in that respect,
-                * and caller must call thaw_processes() if something fails),
-                * but it cleans up leftover PF_FREEZE requests.
-                */
                printk("\n");
                printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
                       "(%d tasks refusing to freeze, wq_busy=%d):\n",
@@ -115,15 +98,11 @@ static int try_to_freeze_tasks(bool sig_only)
                       elapsed_csecs / 100, elapsed_csecs % 100,
                       todo - wq_busy, wq_busy);
 
-               thaw_workqueues();
-
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       task_lock(p);
-                       if (!wakeup && freezing(p) && !freezer_should_skip(p))
+                       if (!wakeup && !freezer_should_skip(p) &&
+                           freezing(p) && !frozen(p))
                                sched_show_task(p);
-                       cancel_freezing(p);
-                       task_unlock(p);
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
        } else {
@@ -136,6 +115,8 @@ static int try_to_freeze_tasks(bool sig_only)
 
 /**
  * freeze_processes - Signal user space processes to enter the refrigerator.
+ *
+ * On success, returns 0.  On failure, -errno and system is fully thawed.
  */
 int freeze_processes(void)
 {
@@ -150,11 +131,15 @@ int freeze_processes(void)
        printk("\n");
        BUG_ON(in_atomic());
 
+       if (error)
+               thaw_processes();
        return error;
 }
 
 /**
  * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
+ *
+ * On success, returns 0.  On failure, -errno and system is fully thawed.
  */
 int freeze_kernel_threads(void)
 {
@@ -168,37 +153,30 @@ int freeze_kernel_threads(void)
        printk("\n");
        BUG_ON(in_atomic());
 
+       if (error)
+               thaw_processes();
        return error;
 }
 
-static void thaw_tasks(bool nosig_only)
+void thaw_processes(void)
 {
        struct task_struct *g, *p;
 
-       read_lock(&tasklist_lock);
-       do_each_thread(g, p) {
-               if (!freezable(p))
-                       continue;
+       oom_killer_enable();
 
-               if (nosig_only && should_send_signal(p))
-                       continue;
+       printk("Restarting tasks ... ");
+
+       thaw_workqueues();
 
-               if (cgroup_freezing_or_frozen(p))
+       read_lock(&tasklist_lock);
+       do_each_thread(g, p) {
+               if (cgroup_freezing(p))
                        continue;
 
-               thaw_process(p);
+               __thaw_task(p);
        } while_each_thread(g, p);
        read_unlock(&tasklist_lock);
-}
 
-void thaw_processes(void)
-{
-       oom_killer_enable();
-
-       printk("Restarting tasks ... ");
-       thaw_workqueues();
-       thaw_tasks(true);
-       thaw_tasks(false);
        schedule();
        printk("done.\n");
 }