1
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
44
45
46
47
48
49
50
51
52
53
54
55#include <linux/types.h>
56#include <linux/errno.h>
57#include <linux/time.h>
58#include <linux/kernel.h>
59#include <linux/kernel_stat.h>
60#include <linux/tty.h>
61#include <linux/string.h>
62#include <linux/mman.h>
63#include <linux/proc_fs.h>
64#include <linux/ioport.h>
65#include <linux/uaccess.h>
66#include <linux/io.h>
67#include <linux/mm.h>
68#include <linux/hugetlb.h>
69#include <linux/pagemap.h>
70#include <linux/swap.h>
71#include <linux/slab.h>
72#include <linux/smp.h>
73#include <linux/signal.h>
74#include <linux/highmem.h>
75#include <linux/file.h>
76#include <linux/fdtable.h>
77#include <linux/times.h>
78#include <linux/cpuset.h>
79#include <linux/rcupdate.h>
80#include <linux/delayacct.h>
81#include <linux/seq_file.h>
82#include <linux/pid_namespace.h>
83#include <linux/ptrace.h>
84#include <linux/tracehook.h>
85#include <linux/swapops.h>
86
87#include <asm/pgtable.h>
88#include <asm/processor.h>
89#include "internal.h"
90
91static inline void task_name(struct seq_file *m, struct task_struct *p)
92{
93 int i;
94 char *buf, *end;
95 char *name;
96 char tcomm[sizeof(p->comm)];
97
98 get_task_comm(tcomm, p);
99
100 seq_printf(m, "Name:\t");
101 end = m->buf + m->size;
102 buf = m->buf + m->count;
103 name = tcomm;
104 i = sizeof(tcomm);
105 while (i && (buf < end)) {
106 unsigned char c = *name;
107 name++;
108 i--;
109 *buf = c;
110 if (!c)
111 break;
112 if (c == '\\') {
113 buf++;
114 if (buf < end)
115 *buf++ = c;
116 continue;
117 }
118 if (c == '\n') {
119 *buf++ = '\\';
120 if (buf < end)
121 *buf++ = 'n';
122 continue;
123 }
124 buf++;
125 }
126 m->count = buf - m->buf;
127 seq_printf(m, "\n");
128}
129
130
131
132
133
134
135
136static const char *task_state_array[] = {
137 "R (running)",
138 "S (sleeping)",
139 "D (disk sleep)",
140 "T (stopped)",
141 "t (tracing stop)",
142 "Z (zombie)",
143 "X (dead)",
144 "x (dead)",
145 "K (wakekill)",
146 "W (waking)",
147};
148
149static inline const char *get_task_state(struct task_struct *tsk)
150{
151 unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
152 const char **p = &task_state_array[0];
153
154 BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array));
155
156 while (state) {
157 p++;
158 state >>= 1;
159 }
160 return *p;
161}
162
163static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
164 struct pid *pid, struct task_struct *p)
165{
166 struct group_info *group_info;
167 int g;
168 struct fdtable *fdt = NULL;
169 const struct cred *cred;
170 pid_t ppid, tpid;
171
172 rcu_read_lock();
173 ppid = pid_alive(p) ?
174 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
175 tpid = 0;
176 if (pid_alive(p)) {
177 struct task_struct *tracer = tracehook_tracer_task(p);
178 if (tracer)
179 tpid = task_pid_nr_ns(tracer, ns);
180 }
181 cred = get_cred((struct cred *) __task_cred(p));
182 seq_printf(m,
183 "State:\t%s\n"
184 "Tgid:\t%d\n"
185 "Pid:\t%d\n"
186 "PPid:\t%d\n"
187 "TracerPid:\t%d\n"
188 "Uid:\t%d\t%d\t%d\t%d\n"
189 "Gid:\t%d\t%d\t%d\t%d\n",
190 get_task_state(p),
191 task_tgid_nr_ns(p, ns),
192 pid_nr_ns(pid, ns),
193 ppid, tpid,
194 cred->uid, cred->euid, cred->suid, cred->fsuid,
195 cred->gid, cred->egid, cred->sgid, cred->fsgid);
196
197 task_lock(p);
198 if (p->files)
199 fdt = files_fdtable(p->files);
200 seq_printf(m,
201 "FDSize:\t%d\n"
202 "Groups:\t",
203 fdt ? fdt->max_fds : 0);
204 rcu_read_unlock();
205
206 group_info = cred->group_info;
207 task_unlock(p);
208
209 for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
210 seq_printf(m, "%d ", GROUP_AT(group_info, g));
211 put_cred(cred);
212
213 seq_printf(m, "\n");
214}
215
216static void render_sigset_t(struct seq_file *m, const char *header,
217 sigset_t *set)
218{
219 int i;
220
221 seq_printf(m, "%s", header);
222
223 i = _NSIG;
224 do {
225 int x = 0;
226
227 i -= 4;
228 if (sigismember(set, i+1)) x |= 1;
229 if (sigismember(set, i+2)) x |= 2;
230 if (sigismember(set, i+3)) x |= 4;
231 if (sigismember(set, i+4)) x |= 8;
232 seq_printf(m, "%x", x);
233 } while (i >= 4);
234
235 seq_printf(m, "\n");
236}
237
238static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
239 sigset_t *catch)
240{
241 struct k_sigaction *k;
242 int i;
243
244 k = p->sighand->action;
245 for (i = 1; i <= _NSIG; ++i, ++k) {
246 if (k->sa.sa_handler == SIG_IGN)
247 sigaddset(ign, i);
248 else if (k->sa.sa_handler != SIG_DFL)
249 sigaddset(catch, i);
250 }
251}
252
253static inline void task_sig(struct seq_file *m, struct task_struct *p)
254{
255 unsigned long flags;
256 sigset_t pending, shpending, blocked, ignored, caught;
257 int num_threads = 0;
258 unsigned long qsize = 0;
259 unsigned long qlim = 0;
260
261 sigemptyset(&pending);
262 sigemptyset(&shpending);
263 sigemptyset(&blocked);
264 sigemptyset(&ignored);
265 sigemptyset(&caught);
266
267 if (lock_task_sighand(p, &flags)) {
268 pending = p->pending.signal;
269 shpending = p->signal->shared_pending.signal;
270 blocked = p->blocked;
271 collect_sigign_sigcatch(p, &ignored, &caught);
272 num_threads = atomic_read(&p->signal->count);
273 qsize = atomic_read(&__task_cred(p)->user->sigpending);
274 qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
275 unlock_task_sighand(p, &flags);
276 }
277
278 seq_printf(m, "Threads:\t%d\n", num_threads);
279 seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim);
280
281
282 render_sigset_t(m, "SigPnd:\t", &pending);
283 render_sigset_t(m, "ShdPnd:\t", &shpending);
284 render_sigset_t(m, "SigBlk:\t", &blocked);
285 render_sigset_t(m, "SigIgn:\t", &ignored);
286 render_sigset_t(m, "SigCgt:\t", &caught);
287}
288
289static void render_cap_t(struct seq_file *m, const char *header,
290 kernel_cap_t *a)
291{
292 unsigned __capi;
293
294 seq_printf(m, "%s", header);
295 CAP_FOR_EACH_U32(__capi) {
296 seq_printf(m, "%08x",
297 a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
298 }
299 seq_printf(m, "\n");
300}
301
302static inline void task_cap(struct seq_file *m, struct task_struct *p)
303{
304 const struct cred *cred;
305 kernel_cap_t cap_inheritable, cap_permitted, cap_effective, cap_bset;
306
307 rcu_read_lock();
308 cred = __task_cred(p);
309 cap_inheritable = cred->cap_inheritable;
310 cap_permitted = cred->cap_permitted;
311 cap_effective = cred->cap_effective;
312 cap_bset = cred->cap_bset;
313 rcu_read_unlock();
314
315 render_cap_t(m, "CapInh:\t", &cap_inheritable);
316 render_cap_t(m, "CapPrm:\t", &cap_permitted);
317 render_cap_t(m, "CapEff:\t", &cap_effective);
318 render_cap_t(m, "CapBnd:\t", &cap_bset);
319}
320
321static inline void task_context_switch_counts(struct seq_file *m,
322 struct task_struct *p)
323{
324 seq_printf(m, "voluntary_ctxt_switches:\t%lu\n"
325 "nonvoluntary_ctxt_switches:\t%lu\n",
326 p->nvcsw,
327 p->nivcsw);
328}
329
330static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
331{
332 seq_printf(m, "Cpus_allowed:\t");
333 seq_cpumask(m, &task->cpus_allowed);
334 seq_printf(m, "\n");
335 seq_printf(m, "Cpus_allowed_list:\t");
336 seq_cpumask_list(m, &task->cpus_allowed);
337 seq_printf(m, "\n");
338}
339
340int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
341 struct pid *pid, struct task_struct *task)
342{
343 struct mm_struct *mm = get_task_mm(task);
344
345 task_name(m, task);
346 task_state(m, ns, pid, task);
347
348 if (mm) {
349 task_mem(m, mm);
350 mmput(mm);
351 }
352 task_sig(m, task);
353 task_cap(m, task);
354 task_cpus_allowed(m, task);
355 cpuset_task_status_allowed(m, task);
356#if defined(CONFIG_S390)
357 task_show_regs(m, task);
358#endif
359 task_context_switch_counts(m, task);
360 return 0;
361}
362
363static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
364 struct pid *pid, struct task_struct *task, int whole)
365{
366 unsigned long vsize, eip, esp, wchan = ~0UL;
367 long priority, nice;
368 int tty_pgrp = -1, tty_nr = 0;
369 sigset_t sigign, sigcatch;
370 char state;
371 pid_t ppid = 0, pgid = -1, sid = -1;
372 int num_threads = 0;
373 int permitted;
374 struct mm_struct *mm;
375 unsigned long long start_time;
376 unsigned long cmin_flt = 0, cmaj_flt = 0;
377 unsigned long min_flt = 0, maj_flt = 0;
378 cputime_t cutime, cstime, utime, stime;
379 cputime_t cgtime, gtime;
380 unsigned long rsslim = 0;
381 char tcomm[sizeof(task->comm)];
382 unsigned long flags;
383
384 state = *get_task_state(task);
385 vsize = eip = esp = 0;
386 permitted = ptrace_may_access(task, PTRACE_MODE_READ);
387 mm = get_task_mm(task);
388 if (mm) {
389 vsize = task_vsize(mm);
390 if (permitted) {
391 eip = KSTK_EIP(task);
392 esp = KSTK_ESP(task);
393 }
394 }
395
396 get_task_comm(tcomm, task);
397
398 sigemptyset(&sigign);
399 sigemptyset(&sigcatch);
400 cutime = cstime = utime = stime = cputime_zero;
401 cgtime = gtime = cputime_zero;
402
403 if (lock_task_sighand(task, &flags)) {
404 struct signal_struct *sig = task->signal;
405
406 if (sig->tty) {
407 struct pid *pgrp = tty_get_pgrp(sig->tty);
408 tty_pgrp = pid_nr_ns(pgrp, ns);
409 put_pid(pgrp);
410 tty_nr = new_encode_dev(tty_devnum(sig->tty));
411 }
412
413 num_threads = atomic_read(&sig->count);
414 collect_sigign_sigcatch(task, &sigign, &sigcatch);
415
416 cmin_flt = sig->cmin_flt;
417 cmaj_flt = sig->cmaj_flt;
418 cutime = sig->cutime;
419 cstime = sig->cstime;
420 cgtime = sig->cgtime;
421 rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
422
423
424 if (whole) {
425 struct task_struct *t = task;
426 do {
427 min_flt += t->min_flt;
428 maj_flt += t->maj_flt;
429 gtime = cputime_add(gtime, t->gtime);
430 t = next_thread(t);
431 } while (t != task);
432
433 min_flt += sig->min_flt;
434 maj_flt += sig->maj_flt;
435 thread_group_times(task, &utime, &stime);
436 gtime = cputime_add(gtime, sig->gtime);
437 }
438
439 sid = task_session_nr_ns(task, ns);
440 ppid = task_tgid_nr_ns(task->real_parent, ns);
441 pgid = task_pgrp_nr_ns(task, ns);
442
443 unlock_task_sighand(task, &flags);
444 }
445
446 if (permitted && (!whole || num_threads < 2))
447 wchan = get_wchan(task);
448 if (!whole) {
449 min_flt = task->min_flt;
450 maj_flt = task->maj_flt;
451 task_times(task, &utime, &stime);
452 gtime = task->gtime;
453 }
454
455
456
457 priority = task_prio(task);
458 nice = task_nice(task);
459
460
461
462 start_time =
463 (unsigned long long)task->real_start_time.tv_sec * NSEC_PER_SEC
464 + task->real_start_time.tv_nsec;
465
466 start_time = nsec_to_clock_t(start_time);
467
468 seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
469%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
470%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
471 pid_nr_ns(pid, ns),
472 tcomm,
473 state,
474 ppid,
475 pgid,
476 sid,
477 tty_nr,
478 tty_pgrp,
479 task->flags,
480 min_flt,
481 cmin_flt,
482 maj_flt,
483 cmaj_flt,
484 cputime_to_clock_t(utime),
485 cputime_to_clock_t(stime),
486 cputime_to_clock_t(cutime),
487 cputime_to_clock_t(cstime),
488 priority,
489 nice,
490 num_threads,
491 start_time,
492 vsize,
493 mm ? get_mm_rss(mm) : 0,
494 rsslim,
495 mm ? mm->start_code : 0,
496 mm ? mm->end_code : 0,
497 (permitted && mm) ? task->stack_start : 0,
498 esp,
499 eip,
500
501
502
503
504 task->pending.signal.sig[0] & 0x7fffffffUL,
505 task->blocked.sig[0] & 0x7fffffffUL,
506 sigign .sig[0] & 0x7fffffffUL,
507 sigcatch .sig[0] & 0x7fffffffUL,
508 wchan,
509 0UL,
510 0UL,
511 task->exit_signal,
512 task_cpu(task),
513 task->rt_priority,
514 task->policy,
515 (unsigned long long)delayacct_blkio_ticks(task),
516 cputime_to_clock_t(gtime),
517 cputime_to_clock_t(cgtime));
518 if (mm)
519 mmput(mm);
520 return 0;
521}
522
523int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
524 struct pid *pid, struct task_struct *task)
525{
526 return do_task_stat(m, ns, pid, task, 0);
527}
528
529int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
530 struct pid *pid, struct task_struct *task)
531{
532 return do_task_stat(m, ns, pid, task, 1);
533}
534
535int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
536 struct pid *pid, struct task_struct *task)
537{
538 int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0;
539 struct mm_struct *mm = get_task_mm(task);
540
541 if (mm) {
542 size = task_statm(mm, &shared, &text, &data, &resident);
543 mmput(mm);
544 }
545 seq_printf(m, "%d %d %d %d %d %d %d\n",
546 size, resident, shared, text, lib, data, 0);
547
548 return 0;
549}
550