This patch introduces a new proc file `/proc/[pid]/freeze_priority` that allows reading and writing the freeze priority of a task. This is useful for process freezing mechanisms that wish to prioritize which tasks to freeze first during suspend or hibernation. To avoid misuse and for system integrity, userspace is not permitted to assign the `FREEZE_PRIORITY_NEVER` level to any task. Signed-off-by: Zihuan Zhang --- Documentation/filesystems/proc.rst | 14 ++++++- fs/proc/base.c | 64 ++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 2971551b7235..4b7bc695b249 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -48,7 +48,8 @@ fixes/update part 1.1 Stefani Seibold June 9 2009 3.11 /proc//patch_state - Livepatch patch operation state 3.12 /proc//arch_status - Task architecture specific information 3.13 /proc//fd - List of symlinks to open files - 3.14 /proc//ksm_stat - Information about the process's ksm status + 3.15 /proc//freeze_priority - Information about freeze_priority. 4 Configuring procfs 4.1 Mount options @@ -2349,6 +2350,17 @@ applicable to KSM. More information about KSM can be found in Documentation/admin-guide/mm/ksm.rst. +3.15 /proc//freeze_priority - Information about freeze_priority +----------------------------------------------------------------------- +This file exposes the `freeze_priority` value of a given task. + +The freezer subsystem uses `freeze_priority` to determine the order +in which tasks are frozen during suspend/hibernate. Tasks with +lower values are frozen earlier. Higher values defer the task to +later freeze rounds. + +Writing a value to this file allows user space to adjust the +priority of the task in the freezer traversal. Chapter 4: Configuring procfs ============================= diff --git a/fs/proc/base.c b/fs/proc/base.c index 62d35631ba8c..724145356128 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -3290,6 +3291,66 @@ static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns, } #endif /* CONFIG_KSM */ +#ifdef CONFIG_FREEZER +static int freeze_priority_show(struct seq_file *m, void *v) +{ + struct inode *inode = m->private; + struct task_struct *p; + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + task_lock(p); + seq_printf(m, "%u\n", p->freeze_priority); + task_unlock(p); + + put_task_struct(p); + + return 0; +} + +static ssize_t freeze_priority_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct inode *inode = file_inode(file); + struct task_struct *p; + u64 freeze_priority; + int err; + + err = kstrtoull_from_user(buf, count, 10, &freeze_priority); + if (err < 0) + return err; + + if (freeze_priority >= FREEZE_PRIORITY_NEVER) + return -EINVAL; + + p = get_proc_task(inode); + if (!p) + return -ESRCH; + + task_lock(p); + p->freeze_priority = freeze_priority; + task_unlock(p); + + put_task_struct(p); + return count; +} + +static int freeze_priority_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, freeze_priority_show, inode); +} + +static const struct file_operations proc_pid_freeze_priority = { + .open = freeze_priority_open, + .read = seq_read, + .write = freeze_priority_write, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* CONFIG_FREEZER */ + #ifdef CONFIG_KSTACK_ERASE_METRICS static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) @@ -3407,6 +3468,9 @@ static const struct pid_entry tgid_base_stuff[] = { REG("timers", S_IRUGO, proc_timers_operations), #endif REG("timerslack_ns", S_IRUGO|S_IWUGO, proc_pid_set_timerslack_ns_operations), +#ifdef CONFIG_FREEZER + REG("freeze_priority", S_IRUGO|S_IWUSR, proc_pid_freeze_priority), +#endif #ifdef CONFIG_LIVEPATCH ONE("patch_state", S_IRUSR, proc_pid_patch_state), #endif -- 2.25.1