Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / kernel / power / process.c
index 71ae290..028a995 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/syscalls.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
+#include <linux/workqueue.h>
 
 /* 
  * Timeout for stopping processes
@@ -35,6 +36,7 @@ static int try_to_freeze_tasks(bool sig_only)
        struct task_struct *g, *p;
        unsigned long end_time;
        unsigned int todo;
+       bool wq_busy = false;
        struct timeval start, end;
        u64 elapsed_csecs64;
        unsigned int elapsed_csecs;
@@ -42,6 +44,10 @@ static int try_to_freeze_tasks(bool sig_only)
        do_gettimeofday(&start);
 
        end_time = jiffies + TIMEOUT;
+
+       if (!sig_only)
+               freeze_workqueues_begin();
+
        while (true) {
                todo = 0;
                read_lock(&tasklist_lock);
@@ -63,6 +69,12 @@ static int try_to_freeze_tasks(bool sig_only)
                                todo++;
                } while_each_thread(g, p);
                read_unlock(&tasklist_lock);
+
+               if (!sig_only) {
+                       wq_busy = freeze_workqueues_busy();
+                       todo += wq_busy;
+               }
+
                if (!todo || time_after(jiffies, end_time))
                        break;
 
@@ -86,8 +98,12 @@ static int try_to_freeze_tasks(bool sig_only)
                 */
                printk("\n");
                printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
-                               "(%d tasks refusing to freeze):\n",
-                               elapsed_csecs / 100, elapsed_csecs % 100, todo);
+                      "(%d tasks refusing to freeze, wq_busy=%d):\n",
+                      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);
@@ -157,6 +173,7 @@ void thaw_processes(void)
        oom_killer_enable();
 
        printk("Restarting tasks ... ");
+       thaw_workqueues();
        thaw_tasks(true);
        thaw_tasks(false);
        schedule();