cregit-Linux how code gets into the kernel

Release 4.10 kernel/power/process.c

Directory: kernel/power
/*
 * drivers/power/process.c - Functions for starting/stopping processes on 
 *                           suspend transitions.
 *
 * Originally from swsusp.
 */



#undef DEBUG

#include <linux/interrupt.h>
#include <linux/oom.h>
#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/freezer.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/kmod.h>
#include <trace/events/power.h>

/* 
 * Timeout for stopping processes
 */

unsigned int __read_mostly freeze_timeout_msecs = 20 * MSEC_PER_SEC;


static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; ktime_t start, end, elapsed; unsigned int elapsed_msecs; bool wakeup = false; int sleep_usecs = USEC_PER_MSEC; start = ktime_get_boottime(); end_time = jiffies + msecs_to_jiffies(freeze_timeout_msecs); if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); for_each_process_thread(g, p) { if (p == current || !freeze_task(p)) continue; if (!freezer_should_skip(p)) todo++; } read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } 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 refrigerator. Start with an initial * 1 ms sleep followed by exponential backoff until 8 ms. */ usleep_range(sleep_usecs / 2, sleep_usecs); if (sleep_usecs < 8 * USEC_PER_MSEC) sleep_usecs *= 2; } end = ktime_get_boottime(); elapsed = ktime_sub(end, start); elapsed_msecs = ktime_to_ms(elapsed); if (todo) { pr_cont("\n"); pr_err("Freezing of tasks %s after %d.%03d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_msecs / 1000, elapsed_msecs % 1000, todo - wq_busy, wq_busy); if (wq_busy) show_workqueue_state(); if (!wakeup) { read_lock(&tasklist_lock); for_each_process_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p)) sched_show_task(p); } read_unlock(&tasklist_lock); } } else { pr_cont("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000, elapsed_msecs % 1000); } return todo ? -EBUSY : 0; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki12838.32%1142.31%
patrick mochelpatrick mochel5616.77%27.69%
tejun heotejun heo5416.17%519.23%
colin crosscolin cross3610.78%13.85%
pavel machekpavel machek278.08%13.85%
abhilash jindalabhilash jindal164.79%13.85%
roger luroger lu72.10%13.85%
michal hockomichal hocko51.50%27.69%
li feili fei41.20%13.85%
xiaotian fengxiaotian feng10.30%13.85%
Total334100.00%26100.00%

/** * freeze_processes - Signal user space processes to enter the refrigerator. * The current thread will not be frozen. The same process that calls * freeze_processes must later call thaw_processes. * * On success, returns 0. On failure, -errno and system is fully thawed. */
int freeze_processes(void) { int error; error = __usermodehelper_disable(UMH_FREEZING); if (error) return error; /* Make sure this task doesn't get frozen */ current->flags |= PF_SUSPEND_TASK; if (!pm_freezing) atomic_inc(&system_freezing_cnt); pm_wakeup_clear(); pr_info("Freezing user space processes ... "); pm_freezing = true; error = try_to_freeze_tasks(true); if (!error) { __usermodehelper_set_disable_depth(UMH_DISABLED); pr_cont("done."); } pr_cont("\n"); BUG_ON(in_atomic()); /* * Now that the whole userspace is frozen we need to disbale * the OOM killer to disallow any further interference with * killable tasks. There is no guarantee oom victims will * ever reach a point they go away we have to wait with a timeout. */ if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs))) error = -EBUSY; if (error) thaw_processes(); return error; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki6352.94%853.33%
michal hockomichal hocko2722.69%426.67%
tejun heotejun heo2218.49%213.33%
colin crosscolin cross75.88%16.67%
Total119100.00%15100.00%

/** * freeze_kernel_threads - Make freezable kernel threads go to the refrigerator. * * On success, returns 0. On failure, -errno and only the kernel threads are * thawed, so as to give a chance to the caller to do additional cleanups * (if any) before thawing the userspace tasks. So, it is the responsibility * of the caller to thaw the userspace tasks, when the time is right. */
int freeze_kernel_threads(void) { int error; pr_info("Freezing remaining freezable tasks ... "); pm_nosig_freezing = true; error = try_to_freeze_tasks(false); if (!error) pr_cont("done."); pr_cont("\n"); BUG_ON(in_atomic()); if (error) thaw_kernel_threads(); return error; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki3154.39%654.55%
patrick mochelpatrick mochel1221.05%19.09%
tejun heotejun heo1017.54%218.18%
michal hockomichal hocko35.26%19.09%
srivatsa s. bhatsrivatsa s. bhat11.75%19.09%
Total57100.00%11100.00%


void thaw_processes(void) { struct task_struct *g, *p; struct task_struct *curr = current; trace_suspend_resume(TPS("thaw_processes"), 0, true); if (pm_freezing) atomic_dec(&system_freezing_cnt); pm_freezing = false; pm_nosig_freezing = false; oom_killer_enable(); pr_info("Restarting tasks ... "); __usermodehelper_set_disable_depth(UMH_FREEZING); thaw_workqueues(); read_lock(&tasklist_lock); for_each_process_thread(g, p) { /* No other threads should have PF_SUSPEND_TASK set */ WARN_ON((p != curr) && (p->flags & PF_SUSPEND_TASK)); __thaw_task(p); } read_unlock(&tasklist_lock); WARN_ON(!(curr->flags & PF_SUSPEND_TASK)); curr->flags &= ~PF_SUSPEND_TASK; usermodehelper_enable(); schedule(); pr_cont("done.\n"); trace_suspend_resume(TPS("thaw_processes"), 0, false); }

Contributors

PersonTokensPropCommitsCommitProp
colin crosscolin cross4428.76%18.33%
patrick mochelpatrick mochel4227.45%216.67%
tejun heotejun heo3120.26%325.00%
todd e brandttodd e brandt2415.69%18.33%
takashi iwaitakashi iwai53.27%18.33%
michal hockomichal hocko31.96%216.67%
rafael j. wysockirafael j. wysocki31.96%18.33%
nigel cunninghamnigel cunningham10.65%18.33%
Total153100.00%12100.00%


void thaw_kernel_threads(void) { struct task_struct *g, *p; pm_nosig_freezing = false; pr_info("Restarting kernel threads ... "); thaw_workqueues(); read_lock(&tasklist_lock); for_each_process_thread(g, p) { if (p->flags & (PF_KTHREAD | PF_WQ_WORKER)) __thaw_task(p); } read_unlock(&tasklist_lock); schedule(); pr_cont("done.\n"); }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki6995.83%133.33%
michal hockomichal hocko34.17%266.67%
Total72100.00%3100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki30038.41%1838.30%
patrick mochelpatrick mochel12415.88%24.26%
tejun heotejun heo12315.75%919.15%
colin crosscolin cross8811.27%24.26%
michal hockomichal hocko415.25%510.64%
pavel machekpavel machek273.46%12.13%
todd e brandttodd e brandt273.46%12.13%
abhilash jindalabhilash jindal162.05%12.13%
li feili fei131.66%12.13%
roger luroger lu70.90%12.13%
takashi iwaitakashi iwai50.64%12.13%
nigel cunninghamnigel cunningham40.51%24.26%
alexey dobriyanalexey dobriyan30.38%12.13%
srivatsa s. bhatsrivatsa s. bhat20.26%12.13%
xiaotian fengxiaotian feng10.13%12.13%
Total781100.00%47100.00%
Directory: kernel/power
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.