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/sched/debug.h>
  16#include <linux/sched/task.h>
  17#include <linux/syscalls.h>
  18#include <linux/freezer.h>
  19#include <linux/delay.h>
  20#include <linux/workqueue.h>
  21#include <linux/kmod.h>
  22#include <trace/events/power.h>
  23
  24/* 
  25 * Timeout for stopping processes
  26 */
  27unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;
  28
  29static int try_to_freeze_tasks(bool user_only)
  30{
  31        struct task_struct *g, *p;
  32        unsigned long end_time;
  33        unsigned int todo;
  34        bool wq_busy = false;
  35        ktime_t start, end, elapsed;
  36        unsigned int elapsed_msecs;
  37        bool wakeup = false;
  38        int sleep_usecs = USEC_PER_MSEC;
  39
  40        start = ktime_get_boottime();
  41
  42        end_time = jiffies + msecs_to_jiffies(freeze_timeout_msecs);
  43
  44        if (!user_only)
  45                freeze_workqueues_begin();
  46
  47        while (true) {
  48                todo = 0;
  49                read_lock(&tasklist_lock);
  50                for_each_process_thread(g, p) {
  51                        if (p == current || !freeze_task(p))
  52                                continue;
  53
  54                        if (!freezer_should_skip(p))
  55                                todo++;
  56                }
  57                read_unlock(&tasklist_lock);
  58
  59                if (!user_only) {
  60                        wq_busy = freeze_workqueues_busy();
  61                        todo += wq_busy;
  62                }
  63
  64                if (!todo || time_after(jiffies, end_time))
  65                        break;
  66
  67                if (pm_wakeup_pending()) {
  68                        wakeup = true;
  69                        break;
  70                }
  71
  72                /*
  73                 * We need to retry, but first give the freezing tasks some
  74                 * time to enter the refrigerator.  Start with an initial
  75                 * 1 ms sleep followed by exponential backoff until 8 ms.
  76                 */
  77                usleep_range(sleep_usecs / 2, sleep_usecs);
  78                if (sleep_usecs < 8 * USEC_PER_MSEC)
  79                        sleep_usecs *= 2;
  80        }
  81
  82        end = ktime_get_boottime();
  83        elapsed = ktime_sub(end, start);
  84        elapsed_msecs = ktime_to_ms(elapsed);
  85
  86        if (todo) {
  87                pr_cont("\n");
  88                pr_err("Freezing of tasks %s after %d.%03d seconds "
  89                       "(%d tasks refusing to freeze, wq_busy=%d):\n",
  90                       wakeup ? "aborted" : "failed",
  91                       elapsed_msecs / 1000, elapsed_msecs % 1000,
  92                       todo - wq_busy, wq_busy);
  93
  94                if (wq_busy)
  95                        show_workqueue_state();
  96
  97                if (!wakeup) {
  98                        read_lock(&tasklist_lock);
  99                        for_each_process_thread(g, p) {
 100                                if (p != current && !freezer_should_skip(p)
 101                                    && freezing(p) && !frozen(p))
 102                                        sched_show_task(p);
 103                        }
 104                        read_unlock(&tasklist_lock);
 105                }
 106        } else {
 107                pr_cont("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
 108                        elapsed_msecs % 1000);
 109        }
 110
 111        return todo ? -EBUSY : 0;
 112}
 113
 114/**
 115 * freeze_processes - Signal user space processes to enter the refrigerator.
 116 * The current thread will not be frozen.  The same process that calls
 117 * freeze_processes must later call thaw_processes.
 118 *
 119 * On success, returns 0.  On failure, -errno and system is fully thawed.
 120 */
 121int freeze_processes(void)
 122{
 123        int error;
 124
 125        error = __usermodehelper_disable(UMH_FREEZING);
 126        if (error)
 127                return error;
 128
 129        /* Make sure this task doesn't get frozen */
 130        current->flags |= PF_SUSPEND_TASK;
 131
 132        if (!pm_freezing)
 133                atomic_inc(&system_freezing_cnt);
 134
 135        pm_wakeup_clear(true);
 136        pr_info("Freezing user space processes ... ");
 137        pm_freezing = true;
 138        error = try_to_freeze_tasks(true);
 139        if (!error) {
 140                __usermodehelper_set_disable_depth(UMH_DISABLED);
 141                pr_cont("done.");
 142        }
 143        pr_cont("\n");
 144        BUG_ON(in_atomic());
 145
 146        /*
 147         * Now that the whole userspace is frozen we need to disbale
 148         * the OOM killer to disallow any further interference with
 149         * killable tasks. There is no guarantee oom victims will
 150         * ever reach a point they go away we have to wait with a timeout.
 151         */
 152        if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
 153                error = -EBUSY;
 154
 155        if (error)
 156                thaw_processes();
 157        return error;
 158}
 159
 160/**
 161 * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator.
 162 *
 163 * On success, returns 0.  On failure, -errno and only the kernel threads are
 164 * thawed, so as to give a chance to the caller to do additional cleanups
 165 * (if any) before thawing the userspace tasks. So, it is the responsibility
 166 * of the caller to thaw the userspace tasks, when the time is right.
 167 */
 168int freeze_kernel_threads(void)
 169{
 170        int error;
 171
 172        pr_info("Freezing remaining freezable tasks ... ");
 173
 174        pm_nosig_freezing = true;
 175        error = try_to_freeze_tasks(false);
 176        if (!error)
 177                pr_cont("done.");
 178
 179        pr_cont("\n");
 180        BUG_ON(in_atomic());
 181
 182        if (error)
 183                thaw_kernel_threads();
 184        return error;
 185}
 186
 187void thaw_processes(void)
 188{
 189        struct task_struct *g, *p;
 190        struct task_struct *curr = current;
 191
 192        trace_suspend_resume(TPS("thaw_processes"), 0, true);
 193        if (pm_freezing)
 194                atomic_dec(&system_freezing_cnt);
 195        pm_freezing = false;
 196        pm_nosig_freezing = false;
 197
 198        oom_killer_enable();
 199
 200        pr_info("Restarting tasks ... ");
 201
 202        __usermodehelper_set_disable_depth(UMH_FREEZING);
 203        thaw_workqueues();
 204
 205        read_lock(&tasklist_lock);
 206        for_each_process_thread(g, p) {
 207                /* No other threads should have PF_SUSPEND_TASK set */
 208                WARN_ON((p != curr) && (p->flags & PF_SUSPEND_TASK));
 209                __thaw_task(p);
 210        }
 211        read_unlock(&tasklist_lock);
 212
 213        WARN_ON(!(curr->flags & PF_SUSPEND_TASK));
 214        curr->flags &= ~PF_SUSPEND_TASK;
 215
 216        usermodehelper_enable();
 217
 218        schedule();
 219        pr_cont("done.\n");
 220        trace_suspend_resume(TPS("thaw_processes"), 0, false);
 221}
 222
 223void thaw_kernel_threads(void)
 224{
 225        struct task_struct *g, *p;
 226
 227        pm_nosig_freezing = false;
 228        pr_info("Restarting kernel threads ... ");
 229
 230        thaw_workqueues();
 231
 232        read_lock(&tasklist_lock);
 233        for_each_process_thread(g, p) {
 234                if (p->flags & (PF_KTHREAD | PF_WQ_WORKER))
 235                        __thaw_task(p);
 236        }
 237        read_unlock(&tasklist_lock);
 238
 239        schedule();
 240        pr_cont("done.\n");
 241}
 242