linux/kernel/power/process.c
<<
>>
Prefs
   1/*
   2 * drivers/power/process.c - Functions for starting/stopping processes on 
   3 *                           suspend transitions.
   4 *
   5 * Originally from swsusp.
   6 */
   7
   8
   9#undef DEBUG
  10
  11#include <linux/interrupt.h>
  12#include <linux/oom.h>
  13#include <linux/suspend.h>
  14#include <linux/module.h>
  15#include <linux/syscalls.h>
  16#include <linux/freezer.h>
  17#include <linux/delay.h>
  18#include <linux/workqueue.h>
  19
  20/* 
  21 * Timeout for stopping processes
  22 */
  23#define TIMEOUT (20 * HZ)
  24
  25static inline int freezable(struct task_struct * p)
  26{
  27        if ((p == current) ||
  28            (p->flags & PF_NOFREEZE) ||
  29            (p->exit_state != 0))
  30                return 0;
  31        return 1;
  32}
  33
  34static int try_to_freeze_tasks(bool sig_only)
  35{
  36        struct task_struct *g, *p;
  37        unsigned long end_time;
  38        unsigned int todo;
  39        bool wq_busy = false;
  40        struct timeval start, end;
  41        u64 elapsed_csecs64;
  42        unsigned int elapsed_csecs;
  43        bool wakeup = false;
  44
  45        do_gettimeofday(&start);
  46
  47        end_time = jiffies + TIMEOUT;
  48
  49        if (!sig_only)
  50                freeze_workqueues_begin();
  51
  52        while (true) {
  53                todo = 0;
  54                read_lock(&tasklist_lock);
  55                do_each_thread(g, p) {
  56                        if (frozen(p) || !freezable(p))
  57                                continue;
  58
  59                        if (!freeze_task(p, sig_only))
  60                                continue;
  61
  62                        /*
  63                         * Now that we've done set_freeze_flag, don't
  64                         * perturb a task in TASK_STOPPED or TASK_TRACED.
  65                         * It is "frozen enough".  If the task does wake
  66                         * up, it will immediately call try_to_freeze.
  67                         *
  68                         * Because freeze_task() goes through p's
  69                         * scheduler lock after setting TIF_FREEZE, it's
  70                         * guaranteed that either we see TASK_RUNNING or
  71                         * try_to_stop() after schedule() in ptrace/signal
  72                         * stop sees TIF_FREEZE.
  73                         */
  74                        if (!task_is_stopped_or_traced(p) &&
  75                            !freezer_should_skip(p))
  76                                todo++;
  77                } while_each_thread(g, p);
  78                read_unlock(&tasklist_lock);
  79
  80                if (!sig_only) {
  81                        wq_busy = freeze_workqueues_busy();
  82                        todo += wq_busy;
  83                }
  84
  85                if (!todo || time_after(jiffies, end_time))
  86                        break;
  87
  88                if (pm_wakeup_pending()) {
  89                        wakeup = true;
  90                        break;
  91                }
  92
  93                /*
  94                 * We need to retry, but first give the freezing tasks some
  95                 * time to enter the regrigerator.
  96                 */
  97                msleep(10);
  98        }
  99
 100        do_gettimeofday(&end);
 101        elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
 102        do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
 103        elapsed_csecs = elapsed_csecs64;
 104
 105        if (todo) {
 106                /* This does not unfreeze processes that are already frozen
 107                 * (we have slightly ugly calling convention in that respect,
 108                 * and caller must call thaw_processes() if something fails),
 109                 * but it cleans up leftover PF_FREEZE requests.
 110                 */
 111                printk("\n");
 112                printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
 113                       "(%d tasks refusing to freeze, wq_busy=%d):\n",
 114                       wakeup ? "aborted" : "failed",
 115                       elapsed_csecs / 100, elapsed_csecs % 100,
 116                       todo - wq_busy, wq_busy);
 117
 118                thaw_workqueues();
 119
 120                read_lock(&tasklist_lock);
 121                do_each_thread(g, p) {
 122                        task_lock(p);
 123                        if (!wakeup && freezing(p) && !freezer_should_skip(p))
 124                                sched_show_task(p);
 125                        cancel_freezing(p);
 126                        task_unlock(p);
 127                } while_each_thread(g, p);
 128                read_unlock(&tasklist_lock);
 129        } else {
 130                printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
 131                        elapsed_csecs % 100);
 132        }
 133
 134        return todo ? -EBUSY : 0;
 135}
 136
 137/**
 138 *      freeze_processes - tell processes to enter the refrigerator
 139 */
 140int freeze_processes(void)
 141{
 142        int error;
 143
 144        printk("Freezing user space processes ... ");
 145        error = try_to_freeze_tasks(true);
 146        if (error)
 147                goto Exit;
 148        printk("done.\n");
 149
 150        printk("Freezing remaining freezable tasks ... ");
 151        error = try_to_freeze_tasks(false);
 152        if (error)
 153                goto Exit;
 154        printk("done.");
 155
 156        oom_killer_disable();
 157 Exit:
 158        BUG_ON(in_atomic());
 159        printk("\n");
 160
 161        return error;
 162}
 163
 164static void thaw_tasks(bool nosig_only)
 165{
 166        struct task_struct *g, *p;
 167
 168        read_lock(&tasklist_lock);
 169        do_each_thread(g, p) {
 170                if (!freezable(p))
 171                        continue;
 172
 173                if (nosig_only && should_send_signal(p))
 174                        continue;
 175
 176                if (cgroup_freezing_or_frozen(p))
 177                        continue;
 178
 179                thaw_process(p);
 180        } while_each_thread(g, p);
 181        read_unlock(&tasklist_lock);
 182}
 183
 184void thaw_processes(void)
 185{
 186        oom_killer_enable();
 187
 188        printk("Restarting tasks ... ");
 189        thaw_workqueues();
 190        thaw_tasks(true);
 191        thaw_tasks(false);
 192        schedule();
 193        printk("done.\n");
 194}
 195
 196