^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/proc/array.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1992 by Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * based on ideas by Darren Senn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Fixes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Michael. K. Johnson: stat,statm extensions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * <johnsonm@stolaf.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Pauline Middelink : Made cmdline,envline only break at '\0's, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * make sure SET_PROCTITLE works. Also removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * bad '!' which forced address recalculation for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * EVERY character on the current page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * <middelin@polyware.iaf.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Danny ter Haar : added cpuinfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * <dth@cistron.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Alessandro Rubini : profile extension.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * <rubini@ipvvis.unipv.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Jeff Tranter : added BogoMips field to cpuinfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * <Jeff_Tranter@Mitel.COM>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Bruno Haible : remove 4K limit for the maps file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * <haible@ma2s2.mathematik.uni-karlsruhe.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Yves Arrouye : remove removal of trailing spaces in get_array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * <Yves.Arrouye@marin.fdn.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Jerome Forissier : added per-CPU time information to /proc/stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * and /proc/<pid>/cpu extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * <forissier@isia.cma.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * - Incorporation and non-SMP safe operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * of forissier patch in 2.1.78 by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Hans Marcus <crowbar@concepts.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * aeb@cwi.nl : /proc/partitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Alan Cox : security fixes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * <alan@lxorguk.ukuu.org.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Al Viro : safe handling of mm_struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Gerhard Wichert : added BIGMEM support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Siemens AG <Gerhard.Wichert@pdb.siemens.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Al Viro & Jeff Garzik : moved most of the thing into base.c and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * : proc_misc.c. The rest may eventually go into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * : base.c too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/kernel_stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <linux/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/sched/numa_balancing.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <linux/sched/task.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <linux/sched/cputime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <linux/hugetlb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include <linux/fdtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #include <linux/times.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <linux/cpuset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #include <linux/delayacct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #include <linux/pid_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #include <linux/prctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #include <linux/string_helpers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #include <linux/fs_struct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) char tcomm[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (p->flags & PF_WQ_WORKER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) wq_worker_comm(tcomm, sizeof(tcomm), p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) __get_task_comm(tcomm, sizeof(tcomm), p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) size = seq_get_buf(m, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (escape) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret = string_escape_str(tcomm, buf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ret >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = strscpy(buf, tcomm, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) seq_commit(m, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * The task state array is a strange "bitmap" of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * reasons to sleep. Thus "running" is zero, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * you can test for combinations of others with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * simple bit tests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static const char * const task_state_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* states in TASK_REPORT: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "R (running)", /* 0x00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "S (sleeping)", /* 0x01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "D (disk sleep)", /* 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "T (stopped)", /* 0x04 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) "t (tracing stop)", /* 0x08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "X (dead)", /* 0x10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "Z (zombie)", /* 0x20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) "P (parked)", /* 0x40 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* states beyond TASK_REPORT: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) "I (idle)", /* 0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline const char *get_task_state(struct task_struct *tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return task_state_array[task_state_index(tsk)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct pid *pid, struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct user_namespace *user_ns = seq_user_ns(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct group_info *group_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int g, umask = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct task_struct *tracer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) const struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) pid_t ppid, tpid = 0, tgid, ngid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int max_fds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ppid = pid_alive(p) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) tracer = ptrace_parent(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (tracer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) tpid = task_pid_nr_ns(tracer, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) tgid = task_tgid_nr_ns(p, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ngid = task_numa_group_id(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) cred = get_task_cred(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) task_lock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (p->fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) umask = p->fs->umask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (p->files)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) max_fds = files_fdtable(p->files)->max_fds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) task_unlock(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (umask >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) seq_printf(m, "Umask:\t%#04o\n", umask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) seq_puts(m, "State:\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) seq_puts(m, get_task_state(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) seq_put_decimal_ull(m, "\nTgid:\t", tgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) seq_put_decimal_ull(m, "\nNgid:\t", ngid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) seq_put_decimal_ull(m, "\nPid:\t", pid_nr_ns(pid, ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) seq_put_decimal_ull(m, "\nPPid:\t", ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) seq_put_decimal_ull(m, "\nTracerPid:\t", tpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) seq_put_decimal_ull(m, "\nUid:\t", from_kuid_munged(user_ns, cred->uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->euid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->suid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->fsuid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) seq_put_decimal_ull(m, "\nGid:\t", from_kgid_munged(user_ns, cred->gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->egid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->sgid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->fsgid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) seq_put_decimal_ull(m, "\nFDSize:\t", max_fds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) seq_puts(m, "\nGroups:\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) group_info = cred->group_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (g = 0; g < group_info->ngroups; g++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) seq_put_decimal_ull(m, g ? " " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) from_kgid_munged(user_ns, group_info->gid[g]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) put_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* Trailing space shouldn't have been added in the first place. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) seq_putc(m, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #ifdef CONFIG_PID_NS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) seq_puts(m, "\nNStgid:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) for (g = ns->level; g <= pid->level; g++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) seq_put_decimal_ull(m, "\t", task_tgid_nr_ns(p, pid->numbers[g].ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) seq_puts(m, "\nNSpid:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) for (g = ns->level; g <= pid->level; g++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) seq_put_decimal_ull(m, "\t", task_pid_nr_ns(p, pid->numbers[g].ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) seq_puts(m, "\nNSpgid:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) for (g = ns->level; g <= pid->level; g++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) seq_put_decimal_ull(m, "\t", task_pgrp_nr_ns(p, pid->numbers[g].ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) seq_puts(m, "\nNSsid:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) for (g = ns->level; g <= pid->level; g++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void render_sigset_t(struct seq_file *m, const char *header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) sigset_t *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) seq_puts(m, header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) i = _NSIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) i -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (sigismember(set, i+1)) x |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (sigismember(set, i+2)) x |= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (sigismember(set, i+3)) x |= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (sigismember(set, i+4)) x |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) seq_putc(m, hex_asc[x]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } while (i >= 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *sigign,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sigset_t *sigcatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct k_sigaction *k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) k = p->sighand->action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (i = 1; i <= _NSIG; ++i, ++k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (k->sa.sa_handler == SIG_IGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) sigaddset(sigign, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) else if (k->sa.sa_handler != SIG_DFL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) sigaddset(sigcatch, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static inline void task_sig(struct seq_file *m, struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) sigset_t pending, shpending, blocked, ignored, caught;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int num_threads = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned int qsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) unsigned long qlim = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) sigemptyset(&pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) sigemptyset(&shpending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) sigemptyset(&blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sigemptyset(&ignored);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) sigemptyset(&caught);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (lock_task_sighand(p, &flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) pending = p->pending.signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) shpending = p->signal->shared_pending.signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) blocked = p->blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) collect_sigign_sigcatch(p, &ignored, &caught);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) num_threads = get_nr_threads(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) rcu_read_lock(); /* FIXME: is this correct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) qsize = atomic_read(&__task_cred(p)->user->sigpending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) qlim = task_rlimit(p, RLIMIT_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) unlock_task_sighand(p, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) seq_put_decimal_ull(m, "Threads:\t", num_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) seq_put_decimal_ull(m, "\nSigQ:\t", qsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) seq_put_decimal_ull(m, "/", qlim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* render them all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) render_sigset_t(m, "\nSigPnd:\t", &pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) render_sigset_t(m, "ShdPnd:\t", &shpending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) render_sigset_t(m, "SigBlk:\t", &blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) render_sigset_t(m, "SigIgn:\t", &ignored);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) render_sigset_t(m, "SigCgt:\t", &caught);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static void render_cap_t(struct seq_file *m, const char *header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) kernel_cap_t *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned __capi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) seq_puts(m, header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) CAP_FOR_EACH_U32(__capi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) seq_put_hex_ll(m, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) a->cap[CAP_LAST_U32 - __capi], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static inline void task_cap(struct seq_file *m, struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) const struct cred *cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) kernel_cap_t cap_inheritable, cap_permitted, cap_effective,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cap_bset, cap_ambient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cred = __task_cred(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cap_inheritable = cred->cap_inheritable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cap_permitted = cred->cap_permitted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) cap_effective = cred->cap_effective;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) cap_bset = cred->cap_bset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cap_ambient = cred->cap_ambient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) render_cap_t(m, "CapInh:\t", &cap_inheritable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) render_cap_t(m, "CapPrm:\t", &cap_permitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) render_cap_t(m, "CapEff:\t", &cap_effective);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) render_cap_t(m, "CapBnd:\t", &cap_bset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) render_cap_t(m, "CapAmb:\t", &cap_ambient);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) seq_put_decimal_ull(m, "NoNewPrivs:\t", task_no_new_privs(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #ifdef CONFIG_SECCOMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #ifdef CONFIG_SECCOMP_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) seq_put_decimal_ull(m, "\nSeccomp_filters:\t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) atomic_read(&p->seccomp.filter_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) seq_puts(m, "\nSpeculation_Store_Bypass:\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case -EINVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) seq_puts(m, "unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case PR_SPEC_NOT_AFFECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) seq_puts(m, "not vulnerable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) seq_puts(m, "thread force mitigated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) seq_puts(m, "thread mitigated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) seq_puts(m, "thread vulnerable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case PR_SPEC_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) seq_puts(m, "globally mitigated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) seq_puts(m, "vulnerable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static inline void task_context_switch_counts(struct seq_file *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) seq_put_decimal_ull(m, "\nnonvoluntary_ctxt_switches:\t", p->nivcsw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) seq_printf(m, "Cpus_allowed:\t%*pb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) cpumask_pr_args(task->cpus_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) seq_printf(m, "Cpus_allowed_list:\t%*pbl\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) cpumask_pr_args(task->cpus_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) seq_put_decimal_ull(m, "CoreDumping:\t", !!mm->core_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static inline void task_thp_status(struct seq_file *m, struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) bool thp_enabled = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (thp_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) thp_enabled = !test_bit(MMF_DISABLE_THP, &mm->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) seq_printf(m, "THP_enabled:\t%d\n", thp_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct mm_struct *mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) seq_puts(m, "Name:\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) proc_task_name(m, task, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) task_state(m, ns, pid, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) task_mem(m, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) task_core_dumping(m, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) task_thp_status(m, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) task_sig(m, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) task_cap(m, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) task_seccomp(m, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) task_cpus_allowed(m, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) cpuset_task_status_allowed(m, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) task_context_switch_counts(m, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct pid *pid, struct task_struct *task, int whole)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) unsigned long vsize, eip, esp, wchan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int priority, nice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int tty_pgrp = -1, tty_nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) sigset_t sigign, sigcatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) char state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) pid_t ppid = 0, pgid = -1, sid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int num_threads = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int permitted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct mm_struct *mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) unsigned long long start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) unsigned long cmin_flt = 0, cmaj_flt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned long min_flt = 0, maj_flt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) u64 cutime, cstime, utime, stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u64 cgtime, gtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) unsigned long rsslim = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) state = *get_task_state(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) vsize = eip = esp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) vsize = task_vsize(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * esp and eip are intentionally zeroed out. There is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * non-racy way to read them without freezing the task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Programs that need reliable values can use ptrace(2).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * The only exception is if the task is core dumping because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * a program is not able to use ptrace(2) in that case. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * safe because the task has stopped executing permanently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (try_get_task_stack(task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) eip = KSTK_EIP(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) esp = KSTK_ESP(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) put_task_stack(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sigemptyset(&sigign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) sigemptyset(&sigcatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) cutime = cstime = utime = stime = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) cgtime = gtime = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (lock_task_sighand(task, &flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct signal_struct *sig = task->signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (sig->tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct pid *pgrp = tty_get_pgrp(sig->tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) tty_pgrp = pid_nr_ns(pgrp, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) put_pid(pgrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) tty_nr = new_encode_dev(tty_devnum(sig->tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) num_threads = get_nr_threads(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) collect_sigign_sigcatch(task, &sigign, &sigcatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) cmin_flt = sig->cmin_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) cmaj_flt = sig->cmaj_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) cutime = sig->cutime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) cstime = sig->cstime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) cgtime = sig->cgtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* add up live thread stats at the group level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (whole) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct task_struct *t = task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) min_flt += t->min_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) maj_flt += t->maj_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) gtime += task_gtime(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) } while_each_thread(task, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) min_flt += sig->min_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) maj_flt += sig->maj_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) thread_group_cputime_adjusted(task, &utime, &stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) gtime += sig->gtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) sid = task_session_nr_ns(task, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ppid = task_tgid_nr_ns(task->real_parent, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) pgid = task_pgrp_nr_ns(task, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unlock_task_sighand(task, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (permitted && (!whole || num_threads < 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) wchan = get_wchan(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (!whole) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) min_flt = task->min_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) maj_flt = task->maj_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) task_cputime_adjusted(task, &utime, &stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) gtime = task_gtime(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* scale priority and nice values from timeslices to -20..20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* to make it look like a "normal" Unix priority/nice value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) priority = task_prio(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) nice = task_nice(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* convert nsec -> ticks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) start_time = nsec_to_clock_t(task->start_boottime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) seq_put_decimal_ull(m, "", pid_nr_ns(pid, ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) seq_puts(m, " (");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) proc_task_name(m, task, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) seq_puts(m, ") ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) seq_putc(m, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) seq_put_decimal_ll(m, " ", ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) seq_put_decimal_ll(m, " ", pgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) seq_put_decimal_ll(m, " ", sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) seq_put_decimal_ll(m, " ", tty_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) seq_put_decimal_ll(m, " ", tty_pgrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) seq_put_decimal_ull(m, " ", task->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) seq_put_decimal_ull(m, " ", min_flt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) seq_put_decimal_ull(m, " ", cmin_flt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) seq_put_decimal_ull(m, " ", maj_flt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) seq_put_decimal_ull(m, " ", cmaj_flt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) seq_put_decimal_ull(m, " ", nsec_to_clock_t(utime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) seq_put_decimal_ull(m, " ", nsec_to_clock_t(stime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) seq_put_decimal_ll(m, " ", nsec_to_clock_t(cutime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) seq_put_decimal_ll(m, " ", nsec_to_clock_t(cstime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) seq_put_decimal_ll(m, " ", priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) seq_put_decimal_ll(m, " ", nice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) seq_put_decimal_ll(m, " ", num_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) seq_put_decimal_ull(m, " ", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) seq_put_decimal_ull(m, " ", start_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) seq_put_decimal_ull(m, " ", vsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) seq_put_decimal_ull(m, " ", mm ? get_mm_rss(mm) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) seq_put_decimal_ull(m, " ", rsslim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->start_code : 1) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->end_code : 1) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) seq_put_decimal_ull(m, " ", (permitted && mm) ? mm->start_stack : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) seq_put_decimal_ull(m, " ", esp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) seq_put_decimal_ull(m, " ", eip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* The signal information here is obsolete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * It must be decimal for Linux 2.0 compatibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * Use /proc/#/status for real-time signals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) seq_put_decimal_ull(m, " ", task->pending.signal.sig[0] & 0x7fffffffUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) seq_put_decimal_ull(m, " ", task->blocked.sig[0] & 0x7fffffffUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) seq_put_decimal_ull(m, " ", sigign.sig[0] & 0x7fffffffUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) seq_put_decimal_ull(m, " ", sigcatch.sig[0] & 0x7fffffffUL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * We used to output the absolute kernel address, but that's an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * information leak - so instead we show a 0/1 flag here, to signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * to user-space whether there's a wchan field in /proc/PID/wchan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * This works with older implementations of procps as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (wchan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) seq_puts(m, " 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) seq_puts(m, " 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) seq_put_decimal_ull(m, " ", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) seq_put_decimal_ull(m, " ", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) seq_put_decimal_ll(m, " ", task->exit_signal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) seq_put_decimal_ll(m, " ", task_cpu(task));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) seq_put_decimal_ull(m, " ", task->rt_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) seq_put_decimal_ull(m, " ", task->policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) seq_put_decimal_ull(m, " ", delayacct_blkio_ticks(task));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) seq_put_decimal_ull(m, " ", nsec_to_clock_t(gtime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) seq_put_decimal_ll(m, " ", nsec_to_clock_t(cgtime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (mm && permitted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) seq_put_decimal_ull(m, " ", mm->start_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) seq_put_decimal_ull(m, " ", mm->end_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) seq_put_decimal_ull(m, " ", mm->start_brk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) seq_put_decimal_ull(m, " ", mm->arg_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) seq_put_decimal_ull(m, " ", mm->arg_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) seq_put_decimal_ull(m, " ", mm->env_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) seq_put_decimal_ull(m, " ", mm->env_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) seq_puts(m, " 0 0 0 0 0 0 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (permitted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) seq_put_decimal_ll(m, " ", task->exit_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) seq_puts(m, " 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return do_task_stat(m, ns, pid, task, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return do_task_stat(m, ns, pid, task, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct pid *pid, struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct mm_struct *mm = get_task_mm(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned long resident = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) unsigned long shared = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) unsigned long text = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) unsigned long data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) size = task_statm(mm, &shared, &text, &data, &resident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) mmput(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * For quick read, open code by putting numbers directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * expected format is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * size, resident, shared, text, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) seq_put_decimal_ull(m, "", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) seq_put_decimal_ull(m, " ", resident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) seq_put_decimal_ull(m, " ", shared);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) seq_put_decimal_ull(m, " ", text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) seq_put_decimal_ull(m, " ", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) seq_put_decimal_ull(m, " ", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) seq_put_decimal_ull(m, " ", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) seq_write(m, "0 0 0 0 0 0 0\n", 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) #ifdef CONFIG_PROC_CHILDREN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct pid *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct task_struct *start, *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct pid *pid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) read_lock(&tasklist_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) start = pid_task(proc_pid(inode), PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * Lets try to continue searching first, this gives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * us significant speedup on children-rich processes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (pid_prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) task = pid_task(pid_prev, PIDTYPE_PID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (task && task->real_parent == start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) !(list_empty(&task->sibling))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (list_is_last(&task->sibling, &start->children))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) task = list_first_entry(&task->sibling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct task_struct, sibling);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) pid = get_pid(task_pid(task));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * Slow search case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * We might miss some children here if children
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * are exited while we were not holding the lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * but it was never promised to be accurate that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * much.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * "Just suppose that the parent sleeps, but N children
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * exit after we printed their tids. Now the slow paths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * skips N extra children, we miss N tasks." (c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * So one need to stop or freeze the leader and all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * its children to get a precise result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) list_for_each_entry(task, &start->children, sibling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (pos-- == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) pid = get_pid(task_pid(task));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) read_unlock(&tasklist_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int children_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct inode *inode = file_inode(seq->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode->i_sb)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static void *children_seq_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return get_children_pid(file_inode(seq->file), NULL, *pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct pid *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) put_pid(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static void children_seq_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) put_pid(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static const struct seq_operations children_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .start = children_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .next = children_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .stop = children_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .show = children_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static int children_seq_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return seq_open(file, &children_seq_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) const struct file_operations proc_tid_children_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .open = children_seq_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) .read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .release = seq_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) #endif /* CONFIG_PROC_CHILDREN */