]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - kernel/power/process.c
Merge branch 'master' into tk71
[mv-sheeva.git] / kernel / power / process.c
index 028a99598f4986b6dfcfaf946af51952f071c346..0cf3a27a6c9d53e32ca449ea6a350770f4caa039 100644 (file)
@@ -22,7 +22,7 @@
  */
 #define TIMEOUT        (20 * HZ)
 
-static inline int freezeable(struct task_struct * p)
+static inline int freezable(struct task_struct * p)
 {
        if ((p == current) ||
            (p->flags & PF_NOFREEZE) ||
@@ -40,6 +40,7 @@ static int try_to_freeze_tasks(bool sig_only)
        struct timeval start, end;
        u64 elapsed_csecs64;
        unsigned int elapsed_csecs;
+       bool wakeup = false;
 
        do_gettimeofday(&start);
 
@@ -52,7 +53,7 @@ static int try_to_freeze_tasks(bool sig_only)
                todo = 0;
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
-                       if (frozen(p) || !freezeable(p))
+                       if (frozen(p) || !freezable(p))
                                continue;
 
                        if (!freeze_task(p, sig_only))
@@ -63,6 +64,12 @@ static int try_to_freeze_tasks(bool sig_only)
                         * perturb a task in TASK_STOPPED or TASK_TRACED.
                         * It is "frozen enough".  If the task does wake
                         * up, it will immediately call try_to_freeze.
+                        *
+                        * Because freeze_task() goes through p's
+                        * scheduler lock after setting TIF_FREEZE, it's
+                        * guaranteed that either we see TASK_RUNNING or
+                        * try_to_stop() after schedule() in ptrace/signal
+                        * stop sees TIF_FREEZE.
                         */
                        if (!task_is_stopped_or_traced(p) &&
                            !freezer_should_skip(p))
@@ -78,6 +85,11 @@ static int try_to_freeze_tasks(bool sig_only)
                if (!todo || time_after(jiffies, end_time))
                        break;
 
+               if (pm_wakeup_pending()) {
+                       wakeup = true;
+                       break;
+               }
+
                /*
                 * We need to retry, but first give the freezing tasks some
                 * time to enter the regrigerator.
@@ -97,8 +109,9 @@ static int try_to_freeze_tasks(bool sig_only)
                 * but it cleans up leftover PF_FREEZE requests.
                 */
                printk("\n");
-               printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
+               printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
                       "(%d tasks refusing to freeze, wq_busy=%d):\n",
+                      wakeup ? "aborted" : "failed",
                       elapsed_csecs / 100, elapsed_csecs % 100,
                       todo - wq_busy, wq_busy);
 
@@ -107,7 +120,7 @@ static int try_to_freeze_tasks(bool sig_only)
                read_lock(&tasklist_lock);
                do_each_thread(g, p) {
                        task_lock(p);
-                       if (freezing(p) && !freezer_should_skip(p))
+                       if (!wakeup && freezing(p) && !freezer_should_skip(p))
                                sched_show_task(p);
                        cancel_freezing(p);
                        task_unlock(p);
@@ -154,7 +167,7 @@ static void thaw_tasks(bool nosig_only)
 
        read_lock(&tasklist_lock);
        do_each_thread(g, p) {
-               if (!freezeable(p))
+               if (!freezable(p))
                        continue;
 
                if (nosig_only && should_send_signal(p))