Blame view

fs/proc/array.c 21.3 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  /*
   *  linux/fs/proc/array.c
   *
   *  Copyright (C) 1992  by Linus Torvalds
   *  based on ideas by Darren Senn
   *
   * Fixes:
   * Michael. K. Johnson: stat,statm extensions.
   *                      <johnsonm@stolaf.edu>
   *
   * Pauline Middelink :  Made cmdline,envline only break at '\0's, to
   *                      make sure SET_PROCTITLE works. Also removed
   *                      bad '!' which forced address recalculation for
   *                      EVERY character on the current page.
   *                      <middelin@polyware.iaf.nl>
   *
   * Danny ter Haar    :	added cpuinfo
   *			<dth@cistron.nl>
   *
   * Alessandro Rubini :  profile extension.
   *                      <rubini@ipvvis.unipv.it>
   *
   * Jeff Tranter      :  added BogoMips field to cpuinfo
   *                      <Jeff_Tranter@Mitel.COM>
   *
   * Bruno Haible      :  remove 4K limit for the maps file
   *			<haible@ma2s2.mathematik.uni-karlsruhe.de>
   *
   * Yves Arrouye      :  remove removal of trailing spaces in get_array.
   *			<Yves.Arrouye@marin.fdn.fr>
   *
   * Jerome Forissier  :  added per-CPU time information to /proc/stat
   *                      and /proc/<pid>/cpu extension
   *                      <forissier@isia.cma.fr>
   *			- Incorporation and non-SMP safe operation
   *			of forissier patch in 2.1.78 by
   *			Hans Marcus <crowbar@concepts.nl>
   *
   * aeb@cwi.nl        :  /proc/partitions
   *
   *
   * Alan Cox	     :  security fixes.
526719ba5   Alan Cox   Switch to a valid...
44
   *			<alan@lxorguk.ukuu.org.uk>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
47
48
49
50
51
52
53
54
   *
   * Al Viro           :  safe handling of mm_struct
   *
   * Gerhard Wichert   :  added BIGMEM support
   * Siemens AG           <Gerhard.Wichert@pdb.siemens.de>
   *
   * Al Viro & Jeff Garzik :  moved most of the thing into base.c and
   *			 :  proc_misc.c. The rest may eventually go into
   *			 :  base.c too.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
62
  #include <linux/types.h>
  #include <linux/errno.h>
  #include <linux/time.h>
  #include <linux/kernel.h>
  #include <linux/kernel_stat.h>
  #include <linux/tty.h>
  #include <linux/string.h>
  #include <linux/mman.h>
6e84f3152   Ingo Molnar   sched/headers: Pr...
63
  #include <linux/sched/mm.h>
6a3827d75   Ingo Molnar   sched/headers: Pr...
64
  #include <linux/sched/numa_balancing.h>
fd7d56270   John Ogness   fs/proc: Report e...
65
  #include <linux/sched/task_stack.h>
299300258   Ingo Molnar   sched/headers: Pr...
66
  #include <linux/sched/task.h>
32ef5517c   Ingo Molnar   sched/headers: Pr...
67
  #include <linux/sched/cputime.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
  #include <linux/proc_fs.h>
  #include <linux/ioport.h>
8ea026066   Ingo Molnar   [PATCH] sched: fi...
70
71
  #include <linux/uaccess.h>
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
  #include <linux/mm.h>
  #include <linux/hugetlb.h>
  #include <linux/pagemap.h>
  #include <linux/swap.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
  #include <linux/smp.h>
  #include <linux/signal.h>
  #include <linux/highmem.h>
  #include <linux/file.h>
9f3acc314   Al Viro   [PATCH] split lin...
80
  #include <linux/fdtable.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
  #include <linux/times.h>
  #include <linux/cpuset.h>
4fb3a5386   Dipankar Sarma   [PATCH] files: fi...
83
  #include <linux/rcupdate.h>
258904546   Shailabh Nagar   [PATCH] per-task-...
84
  #include <linux/delayacct.h>
ee992744e   Eric W. Biederman   proc: rewrite do_...
85
  #include <linux/seq_file.h>
b488893a3   Pavel Emelyanov   pid namespaces: c...
86
  #include <linux/pid_namespace.h>
fae1fa0fc   Kees Cook   proc: Provide det...
87
  #include <linux/prctl.h>
f83ce3e6b   Jake Edge   proc: avoid infor...
88
  #include <linux/ptrace.h>
0d094efeb   Roland McGrath   tracehook: traceh...
89
  #include <linux/tracehook.h>
edc924e02   Andy Shevchenko   fs/proc/array.c: ...
90
  #include <linux/string_helpers.h>
ae2975bc3   Eric W. Biederman   userns: Convert g...
91
  #include <linux/user_namespace.h>
3e42979e6   Richard W.M. Jones   procfs: expose um...
92
  #include <linux/fs_struct.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
  #include <asm/processor.h>
  #include "internal.h"
88b72b31e   Tejun Heo   proc: Consolidate...
96
  void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  {
edc924e02   Andy Shevchenko   fs/proc/array.c: ...
98
  	char *buf;
3a49f3d2a   Andy Shevchenko   fs/proc/array.c: ...
99
  	size_t size;
6b59808bf   Tejun Heo   workqueue: Show t...
100
  	char tcomm[64];
3a49f3d2a   Andy Shevchenko   fs/proc/array.c: ...
101
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102

6b59808bf   Tejun Heo   workqueue: Show t...
103
104
105
106
  	if (p->flags & PF_WQ_WORKER)
  		wq_worker_comm(tcomm, sizeof(tcomm), p);
  	else
  		__get_task_comm(tcomm, sizeof(tcomm), p);
edc924e02   Andy Shevchenko   fs/proc/array.c: ...
107

3a49f3d2a   Andy Shevchenko   fs/proc/array.c: ...
108
  	size = seq_get_buf(m, &buf);
88b72b31e   Tejun Heo   proc: Consolidate...
109
110
111
112
113
114
115
116
117
  	if (escape) {
  		ret = string_escape_str(tcomm, buf, size,
  					ESCAPE_SPACE | ESCAPE_SPECIAL, "
  \\");
  		if (ret >= size)
  			ret = -1;
  	} else {
  		ret = strscpy(buf, tcomm, size);
  	}
edc924e02   Andy Shevchenko   fs/proc/array.c: ...
118

88b72b31e   Tejun Heo   proc: Consolidate...
119
  	seq_commit(m, ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
124
125
126
127
  }
  
  /*
   * The task state array is a strange "bitmap" of
   * reasons to sleep. Thus "running" is zero, and
   * you can test for combinations of others with
   * simple bit tests.
   */
e130aa70f   Mike Frysinger   proc: constify st...
128
  static const char * const task_state_array[] = {
06eb61844   Peter Zijlstra   sched/debug: Add ...
129
130
131
132
133
134
135
136
137
  
  	/* states in TASK_REPORT: */
  	"R (running)",		/* 0x00 */
  	"S (sleeping)",		/* 0x01 */
  	"D (disk sleep)",	/* 0x02 */
  	"T (stopped)",		/* 0x04 */
  	"t (tracing stop)",	/* 0x08 */
  	"X (dead)",		/* 0x10 */
  	"Z (zombie)",		/* 0x20 */
8ef9925b0   Peter Zijlstra   sched/debug: Add ...
138
  	"P (parked)",		/* 0x40 */
06eb61844   Peter Zijlstra   sched/debug: Add ...
139
140
  
  	/* states beyond TASK_REPORT: */
8ef9925b0   Peter Zijlstra   sched/debug: Add ...
141
  	"I (idle)",		/* 0x80 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  };
8ea026066   Ingo Molnar   [PATCH] sched: fi...
143
  static inline const char *get_task_state(struct task_struct *tsk)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  {
06eb61844   Peter Zijlstra   sched/debug: Add ...
145
  	BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array));
1d48b080b   Peter Zijlstra   sched/debug: Rena...
146
  	return task_state_array[task_state_index(tsk)];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  }
df5f8314c   Eric W. Biederman   proc: seqfile con...
148
149
  static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
  				struct pid *pid, struct task_struct *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
  {
e9f238c30   Eric W. Biederman   procfs: Print tas...
151
  	struct user_namespace *user_ns = seq_user_ns(m);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  	struct group_info *group_info;
68c3411ff   Mateusz Guzik   proc: get rid of ...
153
  	int g, umask = -1;
abdba6e9e   Oleg Nesterov   proc: task_state:...
154
  	struct task_struct *tracer;
c69e8d9c0   David Howells   CRED: Use RCU to ...
155
  	const struct cred *cred;
abdba6e9e   Oleg Nesterov   proc: task_state:...
156
  	pid_t ppid, tpid = 0, tgid, ngid;
0f4a0d53f   Oleg Nesterov   proc: task_state:...
157
  	unsigned int max_fds = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158

b0fa9db6a   Oleg Nesterov   [PATCH] proc: dro...
159
  	rcu_read_lock();
b488893a3   Pavel Emelyanov   pid namespaces: c...
160
161
  	ppid = pid_alive(p) ?
  		task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
abdba6e9e   Oleg Nesterov   proc: task_state:...
162
163
164
165
  
  	tracer = ptrace_parent(p);
  	if (tracer)
  		tpid = task_pid_nr_ns(tracer, ns);
b0fafc111   Oleg Nesterov   proc: task_state:...
166
167
168
  
  	tgid = task_tgid_nr_ns(p, ns);
  	ngid = task_numa_group_id(p);
de09a9771   David Howells   CRED: Fix get_tas...
169
  	cred = get_task_cred(p);
0f4a0d53f   Oleg Nesterov   proc: task_state:...
170
171
  
  	task_lock(p);
68c3411ff   Mateusz Guzik   proc: get rid of ...
172
173
  	if (p->fs)
  		umask = p->fs->umask;
0f4a0d53f   Oleg Nesterov   proc: task_state:...
174
175
176
  	if (p->files)
  		max_fds = files_fdtable(p->files)->max_fds;
  	task_unlock(p);
b0fafc111   Oleg Nesterov   proc: task_state:...
177
  	rcu_read_unlock();
0f4a0d53f   Oleg Nesterov   proc: task_state:...
178

68c3411ff   Mateusz Guzik   proc: get rid of ...
179
180
181
  	if (umask >= 0)
  		seq_printf(m, "Umask:\t%#04o
  ", umask);
d0f022312   Andrei Vagin   proc: replace seq...
182
183
  	seq_puts(m, "State:\t");
  	seq_puts(m, get_task_state(p));
f7a5f132b   Alexey Dobriyan   proc: faster /pro...
184

75ba1d07f   Joe Perches   seq/proc: modify ...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
  	seq_put_decimal_ull(m, "
  Tgid:\t", tgid);
  	seq_put_decimal_ull(m, "
  Ngid:\t", ngid);
  	seq_put_decimal_ull(m, "
  Pid:\t", pid_nr_ns(pid, ns));
  	seq_put_decimal_ull(m, "
  PPid:\t", ppid);
  	seq_put_decimal_ull(m, "
  TracerPid:\t", tpid);
  	seq_put_decimal_ull(m, "
  Uid:\t", from_kuid_munged(user_ns, cred->uid));
  	seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->euid));
  	seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->suid));
  	seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->fsuid));
  	seq_put_decimal_ull(m, "
  Gid:\t", from_kgid_munged(user_ns, cred->gid));
  	seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->egid));
  	seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->sgid));
  	seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->fsgid));
  	seq_put_decimal_ull(m, "
  FDSize:\t", max_fds);
f7a5f132b   Alexey Dobriyan   proc: faster /pro...
207
208
209
  
  	seq_puts(m, "
  Groups:\t");
c69e8d9c0   David Howells   CRED: Use RCU to ...
210
  	group_info = cred->group_info;
8d238027b   Artem Bityutskiy   proc: pid/status:...
211
  	for (g = 0; g < group_info->ngroups; g++)
75ba1d07f   Joe Perches   seq/proc: modify ...
212
  		seq_put_decimal_ull(m, g ? " " : "",
81243eacf   Alexey Dobriyan   cred: simpler, 1D...
213
  				from_kgid_munged(user_ns, group_info->gid[g]));
c69e8d9c0   David Howells   CRED: Use RCU to ...
214
  	put_cred(cred);
f7a5f132b   Alexey Dobriyan   proc: faster /pro...
215
216
  	/* Trailing space shouldn't have been added in the first place. */
  	seq_putc(m, ' ');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

e4bc33245   Chen Hanxiao   /proc/PID/status:...
218
219
220
221
  #ifdef CONFIG_PID_NS
  	seq_puts(m, "
  NStgid:");
  	for (g = ns->level; g <= pid->level; g++)
75ba1d07f   Joe Perches   seq/proc: modify ...
222
  		seq_put_decimal_ull(m, "\t", task_tgid_nr_ns(p, pid->numbers[g].ns));
e4bc33245   Chen Hanxiao   /proc/PID/status:...
223
224
225
  	seq_puts(m, "
  NSpid:");
  	for (g = ns->level; g <= pid->level; g++)
75ba1d07f   Joe Perches   seq/proc: modify ...
226
  		seq_put_decimal_ull(m, "\t", task_pid_nr_ns(p, pid->numbers[g].ns));
e4bc33245   Chen Hanxiao   /proc/PID/status:...
227
228
229
  	seq_puts(m, "
  NSpgid:");
  	for (g = ns->level; g <= pid->level; g++)
75ba1d07f   Joe Perches   seq/proc: modify ...
230
  		seq_put_decimal_ull(m, "\t", task_pgrp_nr_ns(p, pid->numbers[g].ns));
e4bc33245   Chen Hanxiao   /proc/PID/status:...
231
232
233
  	seq_puts(m, "
  NSsid:");
  	for (g = ns->level; g <= pid->level; g++)
75ba1d07f   Joe Perches   seq/proc: modify ...
234
  		seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
e4bc33245   Chen Hanxiao   /proc/PID/status:...
235
  #endif
9d6de12f7   Alexey Dobriyan   proc: use seq_put...
236
237
  	seq_putc(m, '
  ');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
  }
138d22b58   Cyrill Gorcunov   fs, epoll: add pr...
239
  void render_sigset_t(struct seq_file *m, const char *header,
df5f8314c   Eric W. Biederman   proc: seqfile con...
240
  				sigset_t *set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
  {
df5f8314c   Eric W. Biederman   proc: seqfile con...
242
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243

9d6de12f7   Alexey Dobriyan   proc: use seq_put...
244
  	seq_puts(m, header);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
250
251
252
253
254
  
  	i = _NSIG;
  	do {
  		int x = 0;
  
  		i -= 4;
  		if (sigismember(set, i+1)) x |= 1;
  		if (sigismember(set, i+2)) x |= 2;
  		if (sigismember(set, i+3)) x |= 4;
  		if (sigismember(set, i+4)) x |= 8;
209b14dc0   Rasmus Villemoes   fs/proc/array.c: ...
255
  		seq_putc(m, hex_asc[x]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  	} while (i >= 4);
9d6de12f7   Alexey Dobriyan   proc: use seq_put...
257
258
  	seq_putc(m, '
  ');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  }
8977a27b6   Alexey Dobriyan   proc: rename "cat...
260
261
  static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *sigign,
  				    sigset_t *sigcatch)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
268
  {
  	struct k_sigaction *k;
  	int i;
  
  	k = p->sighand->action;
  	for (i = 1; i <= _NSIG; ++i, ++k) {
  		if (k->sa.sa_handler == SIG_IGN)
8977a27b6   Alexey Dobriyan   proc: rename "cat...
269
  			sigaddset(sigign, i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  		else if (k->sa.sa_handler != SIG_DFL)
8977a27b6   Alexey Dobriyan   proc: rename "cat...
271
  			sigaddset(sigcatch, i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
  	}
  }
df5f8314c   Eric W. Biederman   proc: seqfile con...
274
  static inline void task_sig(struct seq_file *m, struct task_struct *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  {
5e6b3f42e   Oleg Nesterov   [PATCH] proc: con...
276
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
  	sigset_t pending, shpending, blocked, ignored, caught;
  	int num_threads = 0;
197850a1e   Alexey Dobriyan   proc: use "unsign...
279
  	unsigned int qsize = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
282
283
284
285
286
  	unsigned long qlim = 0;
  
  	sigemptyset(&pending);
  	sigemptyset(&shpending);
  	sigemptyset(&blocked);
  	sigemptyset(&ignored);
  	sigemptyset(&caught);
5e6b3f42e   Oleg Nesterov   [PATCH] proc: con...
287
  	if (lock_task_sighand(p, &flags)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
289
290
291
  		pending = p->pending.signal;
  		shpending = p->signal->shared_pending.signal;
  		blocked = p->blocked;
  		collect_sigign_sigcatch(p, &ignored, &caught);
7e49827cc   Oleg Nesterov   proc: get_nr_thre...
292
  		num_threads = get_nr_threads(p);
7dc521579   Paul E. McKenney   vfs: Apply lockde...
293
  		rcu_read_lock();  /* FIXME: is this correct? */
c69e8d9c0   David Howells   CRED: Use RCU to ...
294
  		qsize = atomic_read(&__task_cred(p)->user->sigpending);
7dc521579   Paul E. McKenney   vfs: Apply lockde...
295
  		rcu_read_unlock();
d554ed895   Jiri Slaby   fs: use rlimit he...
296
  		qlim = task_rlimit(p, RLIMIT_SIGPENDING);
5e6b3f42e   Oleg Nesterov   [PATCH] proc: con...
297
  		unlock_task_sighand(p, &flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299

75ba1d07f   Joe Perches   seq/proc: modify ...
300
301
302
303
  	seq_put_decimal_ull(m, "Threads:\t", num_threads);
  	seq_put_decimal_ull(m, "
  SigQ:\t", qsize);
  	seq_put_decimal_ull(m, "/", qlim);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
  
  	/* render them all */
f7a5f132b   Alexey Dobriyan   proc: faster /pro...
306
307
  	render_sigset_t(m, "
  SigPnd:\t", &pending);
df5f8314c   Eric W. Biederman   proc: seqfile con...
308
309
310
311
  	render_sigset_t(m, "ShdPnd:\t", &shpending);
  	render_sigset_t(m, "SigBlk:\t", &blocked);
  	render_sigset_t(m, "SigIgn:\t", &ignored);
  	render_sigset_t(m, "SigCgt:\t", &caught);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  }
df5f8314c   Eric W. Biederman   proc: seqfile con...
313
314
  static void render_cap_t(struct seq_file *m, const char *header,
  			kernel_cap_t *a)
e338d263a   Andrew Morgan   Add 64-bit capabi...
315
316
  {
  	unsigned __capi;
9d6de12f7   Alexey Dobriyan   proc: use seq_put...
317
  	seq_puts(m, header);
e338d263a   Andrew Morgan   Add 64-bit capabi...
318
  	CAP_FOR_EACH_U32(__capi) {
d0f022312   Andrei Vagin   proc: replace seq...
319
320
  		seq_put_hex_ll(m, NULL,
  			   a->cap[CAP_LAST_U32 - __capi], 8);
e338d263a   Andrew Morgan   Add 64-bit capabi...
321
  	}
9d6de12f7   Alexey Dobriyan   proc: use seq_put...
322
323
  	seq_putc(m, '
  ');
e338d263a   Andrew Morgan   Add 64-bit capabi...
324
  }
df5f8314c   Eric W. Biederman   proc: seqfile con...
325
  static inline void task_cap(struct seq_file *m, struct task_struct *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  {
c69e8d9c0   David Howells   CRED: Use RCU to ...
327
  	const struct cred *cred;
58319057b   Andy Lutomirski   capabilities: amb...
328
329
  	kernel_cap_t cap_inheritable, cap_permitted, cap_effective,
  			cap_bset, cap_ambient;
b6dff3ec5   David Howells   CRED: Separate ta...
330

c69e8d9c0   David Howells   CRED: Use RCU to ...
331
332
333
334
335
336
  	rcu_read_lock();
  	cred = __task_cred(p);
  	cap_inheritable	= cred->cap_inheritable;
  	cap_permitted	= cred->cap_permitted;
  	cap_effective	= cred->cap_effective;
  	cap_bset	= cred->cap_bset;
58319057b   Andy Lutomirski   capabilities: amb...
337
  	cap_ambient	= cred->cap_ambient;
c69e8d9c0   David Howells   CRED: Use RCU to ...
338
339
340
341
342
343
  	rcu_read_unlock();
  
  	render_cap_t(m, "CapInh:\t", &cap_inheritable);
  	render_cap_t(m, "CapPrm:\t", &cap_permitted);
  	render_cap_t(m, "CapEff:\t", &cap_effective);
  	render_cap_t(m, "CapBnd:\t", &cap_bset);
58319057b   Andy Lutomirski   capabilities: amb...
344
  	render_cap_t(m, "CapAmb:\t", &cap_ambient);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
  }
2f4b3bf6b   Kees Cook   /proc/pid/status:...
346
347
  static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
  {
af884cd4a   Kees Cook   proc: report no_n...
348
  	seq_put_decimal_ull(m, "NoNewPrivs:\t", task_no_new_privs(p));
2f4b3bf6b   Kees Cook   /proc/pid/status:...
349
  #ifdef CONFIG_SECCOMP
af884cd4a   Kees Cook   proc: report no_n...
350
351
  	seq_put_decimal_ull(m, "
  Seccomp:\t", p->seccomp.mode);
c818c03b6   Kees Cook   seccomp: Report n...
352
353
354
  	seq_put_decimal_ull(m, "
  Seccomp_filters:\t",
  			    atomic_read(&p->seccomp.filter_count));
2f4b3bf6b   Kees Cook   /proc/pid/status:...
355
  #endif
08b557751   Alexey Dobriyan   proc: use seq_put...
356
357
  	seq_puts(m, "
  Speculation_Store_Bypass:\t");
fae1fa0fc   Kees Cook   proc: Provide det...
358
359
  	switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
  	case -EINVAL:
08b557751   Alexey Dobriyan   proc: use seq_put...
360
  		seq_puts(m, "unknown");
fae1fa0fc   Kees Cook   proc: Provide det...
361
362
  		break;
  	case PR_SPEC_NOT_AFFECTED:
08b557751   Alexey Dobriyan   proc: use seq_put...
363
  		seq_puts(m, "not vulnerable");
fae1fa0fc   Kees Cook   proc: Provide det...
364
  		break;
356e4bfff   Thomas Gleixner   prctl: Add force ...
365
  	case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
08b557751   Alexey Dobriyan   proc: use seq_put...
366
  		seq_puts(m, "thread force mitigated");
356e4bfff   Thomas Gleixner   prctl: Add force ...
367
  		break;
fae1fa0fc   Kees Cook   proc: Provide det...
368
  	case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
08b557751   Alexey Dobriyan   proc: use seq_put...
369
  		seq_puts(m, "thread mitigated");
fae1fa0fc   Kees Cook   proc: Provide det...
370
371
  		break;
  	case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
08b557751   Alexey Dobriyan   proc: use seq_put...
372
  		seq_puts(m, "thread vulnerable");
fae1fa0fc   Kees Cook   proc: Provide det...
373
374
  		break;
  	case PR_SPEC_DISABLE:
08b557751   Alexey Dobriyan   proc: use seq_put...
375
  		seq_puts(m, "globally mitigated");
fae1fa0fc   Kees Cook   proc: Provide det...
376
377
  		break;
  	default:
08b557751   Alexey Dobriyan   proc: use seq_put...
378
  		seq_puts(m, "vulnerable");
fae1fa0fc   Kees Cook   proc: Provide det...
379
380
  		break;
  	}
af884cd4a   Kees Cook   proc: report no_n...
381
382
  	seq_putc(m, '
  ');
2f4b3bf6b   Kees Cook   /proc/pid/status:...
383
  }
df5f8314c   Eric W. Biederman   proc: seqfile con...
384
385
  static inline void task_context_switch_counts(struct seq_file *m,
  						struct task_struct *p)
b663a79c1   Maxim Uvarov   taskstats: add co...
386
  {
75ba1d07f   Joe Perches   seq/proc: modify ...
387
388
389
  	seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw);
  	seq_put_decimal_ull(m, "
  nonvoluntary_ctxt_switches:\t", p->nivcsw);
f7a5f132b   Alexey Dobriyan   proc: faster /pro...
390
391
  	seq_putc(m, '
  ');
b663a79c1   Maxim Uvarov   taskstats: add co...
392
  }
d01d48278   Heiko Carstens   sched: Always sho...
393
394
  static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
  {
a0c2e07d6   Tejun Heo   proc: use %*pb[l]...
395
396
  	seq_printf(m, "Cpus_allowed:\t%*pb
  ",
3bd370625   Sebastian Andrzej Siewior   sched/core: Provi...
397
  		   cpumask_pr_args(task->cpus_ptr));
a0c2e07d6   Tejun Heo   proc: use %*pb[l]...
398
399
  	seq_printf(m, "Cpus_allowed_list:\t%*pbl
  ",
3bd370625   Sebastian Andrzej Siewior   sched/core: Provi...
400
  		   cpumask_pr_args(task->cpus_ptr));
d01d48278   Heiko Carstens   sched: Always sho...
401
  }
c64340121   Roman Gushchin   proc, coredump: a...
402
403
  static inline void task_core_dumping(struct seq_file *m, struct mm_struct *mm)
  {
d0f022312   Andrei Vagin   proc: replace seq...
404
405
406
  	seq_put_decimal_ull(m, "CoreDumping:\t", !!mm->core_state);
  	seq_putc(m, '
  ');
c64340121   Roman Gushchin   proc, coredump: a...
407
  }
a1400af75   Michal Hocko   mm, proc: report ...
408
409
410
411
412
413
414
415
416
  static inline void task_thp_status(struct seq_file *m, struct mm_struct *mm)
  {
  	bool thp_enabled = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE);
  
  	if (thp_enabled)
  		thp_enabled = !test_bit(MMF_DISABLE_THP, &mm->flags);
  	seq_printf(m, "THP_enabled:\t%d
  ", thp_enabled);
  }
df5f8314c   Eric W. Biederman   proc: seqfile con...
417
418
  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
  			struct pid *pid, struct task_struct *task)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  	struct mm_struct *mm = get_task_mm(task);
88b72b31e   Tejun Heo   proc: Consolidate...
421
422
423
424
  	seq_puts(m, "Name:\t");
  	proc_task_name(m, task, true);
  	seq_putc(m, '
  ');
df5f8314c   Eric W. Biederman   proc: seqfile con...
425
  	task_state(m, ns, pid, task);
8ea026066   Ingo Molnar   [PATCH] sched: fi...
426

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
  	if (mm) {
df5f8314c   Eric W. Biederman   proc: seqfile con...
428
  		task_mem(m, mm);
c64340121   Roman Gushchin   proc, coredump: a...
429
  		task_core_dumping(m, mm);
a1400af75   Michal Hocko   mm, proc: report ...
430
  		task_thp_status(m, mm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
432
  		mmput(mm);
  	}
df5f8314c   Eric W. Biederman   proc: seqfile con...
433
434
  	task_sig(m, task);
  	task_cap(m, task);
2f4b3bf6b   Kees Cook   /proc/pid/status:...
435
  	task_seccomp(m, task);
d01d48278   Heiko Carstens   sched: Always sho...
436
  	task_cpus_allowed(m, task);
df5f8314c   Eric W. Biederman   proc: seqfile con...
437
  	cpuset_task_status_allowed(m, task);
df5f8314c   Eric W. Biederman   proc: seqfile con...
438
439
  	task_context_switch_counts(m, task);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  }
ee992744e   Eric W. Biederman   proc: rewrite do_...
441
442
  static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
  			struct pid *pid, struct task_struct *task, int whole)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
443
  {
b2f73922d   Ingo Molnar   fs/proc, core/deb...
444
  	unsigned long vsize, eip, esp, wchan = 0;
715be1fce   Jan Engelhardt   procfs: use more ...
445
  	int priority, nice;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
447
448
  	int tty_pgrp = -1, tty_nr = 0;
  	sigset_t sigign, sigcatch;
  	char state;
8ea026066   Ingo Molnar   [PATCH] sched: fi...
449
  	pid_t ppid = 0, pgid = -1, sid = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  	int num_threads = 0;
f83ce3e6b   Jake Edge   proc: avoid infor...
451
  	int permitted;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
454
455
  	struct mm_struct *mm;
  	unsigned long long start_time;
  	unsigned long cmin_flt = 0, cmaj_flt = 0;
  	unsigned long  min_flt = 0,  maj_flt = 0;
5613fda9a   Frederic Weisbecker   sched/cputime: Co...
456
  	u64 cutime, cstime, utime, stime;
16a6d9be9   Frederic Weisbecker   sched/cputime: Co...
457
  	u64 cgtime, gtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
  	unsigned long rsslim = 0;
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
459
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
461
462
  
  	state = *get_task_state(task);
  	vsize = eip = esp = 0;
caaee6234   Jann Horn   ptrace: use fsuid...
463
  	permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
  	mm = get_task_mm(task);
  	if (mm) {
  		vsize = task_vsize(mm);
0a1eb2d47   Andy Lutomirski   fs/proc: Stop rep...
467
468
469
470
  		/*
  		 * esp and eip are intentionally zeroed out.  There is no
  		 * non-racy way to read them without freezing the task.
  		 * Programs that need reliable values can use ptrace(2).
fd7d56270   John Ogness   fs/proc: Report e...
471
472
473
474
  		 *
  		 * The only exception is if the task is core dumping because
  		 * a program is not able to use ptrace(2) in that case. It is
  		 * safe because the task has stopped executing permanently.
0a1eb2d47   Andy Lutomirski   fs/proc: Stop rep...
475
  		 */
cb8f381f1   John Ogness   fs/proc/array.c: ...
476
  		if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) {
8bb2ee192   Alexey Dobriyan   proc: fix coredum...
477
478
479
480
481
  			if (try_get_task_stack(task)) {
  				eip = KSTK_EIP(task);
  				esp = KSTK_ESP(task);
  				put_task_stack(task);
  			}
fd7d56270   John Ogness   fs/proc: Report e...
482
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
485
  	sigemptyset(&sigign);
  	sigemptyset(&sigcatch);
648616343   Martin Schwidefsky   [S390] cputime: a...
486
487
  	cutime = cstime = utime = stime = 0;
  	cgtime = gtime = 0;
3cfd0885f   Alan Cox   [PATCH] tty: stop...
488

a593d6ede   Oleg Nesterov   [PATCH] proc: con...
489
490
  	if (lock_task_sighand(task, &flags)) {
  		struct signal_struct *sig = task->signal;
915935041   Oleg Nesterov   [PATCH] do_task_s...
491
492
  
  		if (sig->tty) {
5d0fdf1e0   Alan Cox   tty_io: fix remai...
493
494
495
  			struct pid *pgrp = tty_get_pgrp(sig->tty);
  			tty_pgrp = pid_nr_ns(pgrp, ns);
  			put_pid(pgrp);
915935041   Oleg Nesterov   [PATCH] do_task_s...
496
  			tty_nr = new_encode_dev(tty_devnum(sig->tty));
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
497
  		}
7e49827cc   Oleg Nesterov   proc: get_nr_thre...
498
  		num_threads = get_nr_threads(task);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
499
  		collect_sigign_sigcatch(task, &sigign, &sigcatch);
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
500
501
502
503
  		cmin_flt = sig->cmin_flt;
  		cmaj_flt = sig->cmaj_flt;
  		cutime = sig->cutime;
  		cstime = sig->cstime;
9ac52315d   Laurent Vivier   sched: guest CPU ...
504
  		cgtime = sig->cgtime;
6aa7de059   Mark Rutland   locking/atomics: ...
505
  		rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
506

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
  		/* add up live thread stats at the group level */
  		if (whole) {
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
509
  			struct task_struct *t = task;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
512
  			do {
  				min_flt += t->min_flt;
  				maj_flt += t->maj_flt;
6fac4829c   Frederic Weisbecker   cputime: Use acce...
513
  				gtime += task_gtime(t);
185ee40ee   Oleg Nesterov   fs/proc/array.c: ...
514
  			} while_each_thread(task, t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515

a593d6ede   Oleg Nesterov   [PATCH] proc: con...
516
517
  			min_flt += sig->min_flt;
  			maj_flt += sig->maj_flt;
e80d0a1ae   Frederic Weisbecker   cputime: Rename t...
518
  			thread_group_cputime_adjusted(task, &utime, &stime);
648616343   Martin Schwidefsky   [S390] cputime: a...
519
  			gtime += sig->gtime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
  		}
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
521

b488893a3   Pavel Emelyanov   pid namespaces: c...
522
  		sid = task_session_nr_ns(task, ns);
a98fdcef9   Oleg Nesterov   fix the "remove t...
523
  		ppid = task_tgid_nr_ns(task->real_parent, ns);
b488893a3   Pavel Emelyanov   pid namespaces: c...
524
  		pgid = task_pgrp_nr_ns(task, ns);
a593d6ede   Oleg Nesterov   [PATCH] proc: con...
525
526
  
  		unlock_task_sighand(task, &flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528

f83ce3e6b   Jake Edge   proc: avoid infor...
529
  	if (permitted && (!whole || num_threads < 2))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
532
533
  		wchan = get_wchan(task);
  	if (!whole) {
  		min_flt = task->min_flt;
  		maj_flt = task->maj_flt;
e80d0a1ae   Frederic Weisbecker   cputime: Rename t...
534
  		task_cputime_adjusted(task, &utime, &stime);
6fac4829c   Frederic Weisbecker   cputime: Use acce...
535
  		gtime = task_gtime(task);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
538
539
540
541
  	}
  
  	/* scale priority and nice values from timeslices to -20..20 */
  	/* to make it look like a "normal" Unix priority/nice value  */
  	priority = task_prio(task);
  	nice = task_nice(task);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
  	/* convert nsec -> ticks */
cf25e24db   Peter Zijlstra   time: Rename tsk-...
543
  	start_time = nsec_to_clock_t(task->start_boottime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544

d0f022312   Andrei Vagin   proc: replace seq...
545
546
  	seq_put_decimal_ull(m, "", pid_nr_ns(pid, ns));
  	seq_puts(m, " (");
88b72b31e   Tejun Heo   proc: Consolidate...
547
  	proc_task_name(m, task, false);
d0f022312   Andrei Vagin   proc: replace seq...
548
549
  	seq_puts(m, ") ");
  	seq_putc(m, state);
75ba1d07f   Joe Perches   seq/proc: modify ...
550
551
552
553
554
555
556
557
558
559
  	seq_put_decimal_ll(m, " ", ppid);
  	seq_put_decimal_ll(m, " ", pgid);
  	seq_put_decimal_ll(m, " ", sid);
  	seq_put_decimal_ll(m, " ", tty_nr);
  	seq_put_decimal_ll(m, " ", tty_pgrp);
  	seq_put_decimal_ull(m, " ", task->flags);
  	seq_put_decimal_ull(m, " ", min_flt);
  	seq_put_decimal_ull(m, " ", cmin_flt);
  	seq_put_decimal_ull(m, " ", maj_flt);
  	seq_put_decimal_ull(m, " ", cmaj_flt);
5613fda9a   Frederic Weisbecker   sched/cputime: Co...
560
561
562
563
  	seq_put_decimal_ull(m, " ", nsec_to_clock_t(utime));
  	seq_put_decimal_ull(m, " ", nsec_to_clock_t(stime));
  	seq_put_decimal_ll(m, " ", nsec_to_clock_t(cutime));
  	seq_put_decimal_ll(m, " ", nsec_to_clock_t(cstime));
75ba1d07f   Joe Perches   seq/proc: modify ...
564
565
566
567
568
569
570
571
572
573
574
575
576
  	seq_put_decimal_ll(m, " ", priority);
  	seq_put_decimal_ll(m, " ", nice);
  	seq_put_decimal_ll(m, " ", num_threads);
  	seq_put_decimal_ull(m, " ", 0);
  	seq_put_decimal_ull(m, " ", start_time);
  	seq_put_decimal_ull(m, " ", vsize);
  	seq_put_decimal_ull(m, " ", mm ? get_mm_rss(mm) : 0);
  	seq_put_decimal_ull(m, " ", rsslim);
  	seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->start_code : 1) : 0);
  	seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->end_code : 1) : 0);
  	seq_put_decimal_ull(m, " ", (permitted && mm) ? mm->start_stack : 0);
  	seq_put_decimal_ull(m, " ", esp);
  	seq_put_decimal_ull(m, " ", eip);
bda7bad62   KAMEZAWA Hiroyuki   procfs: speed up ...
577
578
579
580
  	/* The signal information here is obsolete.
  	 * It must be decimal for Linux 2.0 compatibility.
  	 * Use /proc/#/status for real-time signals.
  	 */
75ba1d07f   Joe Perches   seq/proc: modify ...
581
582
583
584
  	seq_put_decimal_ull(m, " ", task->pending.signal.sig[0] & 0x7fffffffUL);
  	seq_put_decimal_ull(m, " ", task->blocked.sig[0] & 0x7fffffffUL);
  	seq_put_decimal_ull(m, " ", sigign.sig[0] & 0x7fffffffUL);
  	seq_put_decimal_ull(m, " ", sigcatch.sig[0] & 0x7fffffffUL);
b2f73922d   Ingo Molnar   fs/proc, core/deb...
585
586
587
588
589
590
591
592
593
594
595
596
  
  	/*
  	 * We used to output the absolute kernel address, but that's an
  	 * information leak - so instead we show a 0/1 flag here, to signal
  	 * to user-space whether there's a wchan field in /proc/PID/wchan.
  	 *
  	 * This works with older implementations of procps as well.
  	 */
  	if (wchan)
  		seq_puts(m, " 1");
  	else
  		seq_puts(m, " 0");
75ba1d07f   Joe Perches   seq/proc: modify ...
597
598
599
600
601
602
603
  	seq_put_decimal_ull(m, " ", 0);
  	seq_put_decimal_ull(m, " ", 0);
  	seq_put_decimal_ll(m, " ", task->exit_signal);
  	seq_put_decimal_ll(m, " ", task_cpu(task));
  	seq_put_decimal_ull(m, " ", task->rt_priority);
  	seq_put_decimal_ull(m, " ", task->policy);
  	seq_put_decimal_ull(m, " ", delayacct_blkio_ticks(task));
16a6d9be9   Frederic Weisbecker   sched/cputime: Co...
604
605
  	seq_put_decimal_ull(m, " ", nsec_to_clock_t(gtime));
  	seq_put_decimal_ll(m, " ", nsec_to_clock_t(cgtime));
5b172087f   Cyrill Gorcunov   c/r: procfs: add ...
606
607
  
  	if (mm && permitted) {
75ba1d07f   Joe Perches   seq/proc: modify ...
608
609
610
611
612
613
614
  		seq_put_decimal_ull(m, " ", mm->start_data);
  		seq_put_decimal_ull(m, " ", mm->end_data);
  		seq_put_decimal_ull(m, " ", mm->start_brk);
  		seq_put_decimal_ull(m, " ", mm->arg_start);
  		seq_put_decimal_ull(m, " ", mm->arg_end);
  		seq_put_decimal_ull(m, " ", mm->env_start);
  		seq_put_decimal_ull(m, " ", mm->env_end);
5b172087f   Cyrill Gorcunov   c/r: procfs: add ...
615
  	} else
75ba1d07f   Joe Perches   seq/proc: modify ...
616
  		seq_puts(m, " 0 0 0 0 0 0 0");
5b172087f   Cyrill Gorcunov   c/r: procfs: add ...
617
618
  
  	if (permitted)
75ba1d07f   Joe Perches   seq/proc: modify ...
619
  		seq_put_decimal_ll(m, " ", task->exit_code);
5b172087f   Cyrill Gorcunov   c/r: procfs: add ...
620
  	else
75ba1d07f   Joe Perches   seq/proc: modify ...
621
  		seq_puts(m, " 0");
5b172087f   Cyrill Gorcunov   c/r: procfs: add ...
622

bda7bad62   KAMEZAWA Hiroyuki   procfs: speed up ...
623
624
  	seq_putc(m, '
  ');
8ea026066   Ingo Molnar   [PATCH] sched: fi...
625
  	if (mm)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
  		mmput(mm);
ee992744e   Eric W. Biederman   proc: rewrite do_...
627
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  }
ee992744e   Eric W. Biederman   proc: rewrite do_...
629
630
  int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
  			struct pid *pid, struct task_struct *task)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  {
ee992744e   Eric W. Biederman   proc: rewrite do_...
632
  	return do_task_stat(m, ns, pid, task, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
  }
ee992744e   Eric W. Biederman   proc: rewrite do_...
634
635
  int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
  			struct pid *pid, struct task_struct *task)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  {
ee992744e   Eric W. Biederman   proc: rewrite do_...
637
  	return do_task_stat(m, ns, pid, task, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  }
a56d3fc74   Eric W. Biederman   seqfile convert p...
639
640
  int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
  			struct pid *pid, struct task_struct *task)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
  	struct mm_struct *mm = get_task_mm(task);
8ea026066   Ingo Molnar   [PATCH] sched: fi...
643

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  	if (mm) {
5c5ab9714   Alexey Dobriyan   proc: speed up /p...
645
646
647
648
649
  		unsigned long size;
  		unsigned long resident = 0;
  		unsigned long shared = 0;
  		unsigned long text = 0;
  		unsigned long data = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
  		size = task_statm(mm, &shared, &text, &data, &resident);
  		mmput(mm);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652

5c5ab9714   Alexey Dobriyan   proc: speed up /p...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
  		/*
  		 * For quick read, open code by putting numbers directly
  		 * expected format is
  		 * seq_printf(m, "%lu %lu %lu %lu 0 %lu 0
  ",
  		 *               size, resident, shared, text, data);
  		 */
  		seq_put_decimal_ull(m, "", size);
  		seq_put_decimal_ull(m, " ", resident);
  		seq_put_decimal_ull(m, " ", shared);
  		seq_put_decimal_ull(m, " ", text);
  		seq_put_decimal_ull(m, " ", 0);
  		seq_put_decimal_ull(m, " ", data);
  		seq_put_decimal_ull(m, " ", 0);
  		seq_putc(m, '
  ');
  	} else {
  		seq_write(m, "0 0 0 0 0 0 0
  ", 14);
  	}
a56d3fc74   Eric W. Biederman   seqfile convert p...
673
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  }
818411616   Cyrill Gorcunov   fs, proc: introdu...
675

2e13ba54a   Iago López Galeiras   fs, proc: introdu...
676
  #ifdef CONFIG_PROC_CHILDREN
818411616   Cyrill Gorcunov   fs, proc: introdu...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
  static struct pid *
  get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
  {
  	struct task_struct *start, *task;
  	struct pid *pid = NULL;
  
  	read_lock(&tasklist_lock);
  
  	start = pid_task(proc_pid(inode), PIDTYPE_PID);
  	if (!start)
  		goto out;
  
  	/*
  	 * Lets try to continue searching first, this gives
  	 * us significant speedup on children-rich processes.
  	 */
  	if (pid_prev) {
  		task = pid_task(pid_prev, PIDTYPE_PID);
  		if (task && task->real_parent == start &&
  		    !(list_empty(&task->sibling))) {
  			if (list_is_last(&task->sibling, &start->children))
  				goto out;
  			task = list_first_entry(&task->sibling,
  						struct task_struct, sibling);
  			pid = get_pid(task_pid(task));
  			goto out;
  		}
  	}
  
  	/*
  	 * Slow search case.
  	 *
  	 * We might miss some children here if children
  	 * are exited while we were not holding the lock,
  	 * but it was never promised to be accurate that
  	 * much.
  	 *
  	 * "Just suppose that the parent sleeps, but N children
  	 *  exit after we printed their tids. Now the slow paths
  	 *  skips N extra children, we miss N tasks." (c)
  	 *
  	 * So one need to stop or freeze the leader and all
  	 * its children to get a precise result.
  	 */
  	list_for_each_entry(task, &start->children, sibling) {
  		if (pos-- == 0) {
  			pid = get_pid(task_pid(task));
  			break;
  		}
  	}
  
  out:
  	read_unlock(&tasklist_lock);
  	return pid;
  }
  
  static int children_seq_show(struct seq_file *seq, void *v)
  {
04015e3fa   Christoph Hellwig   proc: don't detou...
735
  	struct inode *inode = file_inode(seq->file);
25ce31916   Joe Perches   proc: remove use ...
736

9d78edeae   Alexey Gladkov   proc: proc_pid_ns...
737
  	seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode->i_sb)));
25ce31916   Joe Perches   proc: remove use ...
738
  	return 0;
818411616   Cyrill Gorcunov   fs, proc: introdu...
739
740
741
742
  }
  
  static void *children_seq_start(struct seq_file *seq, loff_t *pos)
  {
04015e3fa   Christoph Hellwig   proc: don't detou...
743
  	return get_children_pid(file_inode(seq->file), NULL, *pos);
818411616   Cyrill Gorcunov   fs, proc: introdu...
744
745
746
747
748
  }
  
  static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
  	struct pid *pid;
04015e3fa   Christoph Hellwig   proc: don't detou...
749
  	pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
818411616   Cyrill Gorcunov   fs, proc: introdu...
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  	put_pid(v);
  
  	++*pos;
  	return pid;
  }
  
  static void children_seq_stop(struct seq_file *seq, void *v)
  {
  	put_pid(v);
  }
  
  static const struct seq_operations children_seq_ops = {
  	.start	= children_seq_start,
  	.next	= children_seq_next,
  	.stop	= children_seq_stop,
  	.show	= children_seq_show,
  };
  
  static int children_seq_open(struct inode *inode, struct file *file)
  {
04015e3fa   Christoph Hellwig   proc: don't detou...
770
  	return seq_open(file, &children_seq_ops);
818411616   Cyrill Gorcunov   fs, proc: introdu...
771
  }
818411616   Cyrill Gorcunov   fs, proc: introdu...
772
773
774
775
  const struct file_operations proc_tid_children_operations = {
  	.open    = children_seq_open,
  	.read    = seq_read,
  	.llseek  = seq_lseek,
171ef917d   Alexey Dobriyan   fs/proc/array.c: ...
776
  	.release = seq_release,
818411616   Cyrill Gorcunov   fs, proc: introdu...
777
  };
2e13ba54a   Iago López Galeiras   fs, proc: introdu...
778
  #endif /* CONFIG_PROC_CHILDREN */