diff options
Diffstat (limited to 'fs/proc/array.c')
-rw-r--r-- | fs/proc/array.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 88c355574aa0..77a8eacbe032 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/mman.h> | 62 | #include <linux/mman.h> |
63 | #include <linux/sched/mm.h> | 63 | #include <linux/sched/mm.h> |
64 | #include <linux/sched/numa_balancing.h> | 64 | #include <linux/sched/numa_balancing.h> |
65 | #include <linux/sched/task_stack.h> | ||
65 | #include <linux/sched/task.h> | 66 | #include <linux/sched/task.h> |
66 | #include <linux/sched/cputime.h> | 67 | #include <linux/sched/cputime.h> |
67 | #include <linux/proc_fs.h> | 68 | #include <linux/proc_fs.h> |
@@ -118,30 +119,25 @@ static inline void task_name(struct seq_file *m, struct task_struct *p) | |||
118 | * simple bit tests. | 119 | * simple bit tests. |
119 | */ | 120 | */ |
120 | static const char * const task_state_array[] = { | 121 | static const char * const task_state_array[] = { |
121 | "R (running)", /* 0 */ | 122 | |
122 | "S (sleeping)", /* 1 */ | 123 | /* states in TASK_REPORT: */ |
123 | "D (disk sleep)", /* 2 */ | 124 | "R (running)", /* 0x00 */ |
124 | "T (stopped)", /* 4 */ | 125 | "S (sleeping)", /* 0x01 */ |
125 | "t (tracing stop)", /* 8 */ | 126 | "D (disk sleep)", /* 0x02 */ |
126 | "X (dead)", /* 16 */ | 127 | "T (stopped)", /* 0x04 */ |
127 | "Z (zombie)", /* 32 */ | 128 | "t (tracing stop)", /* 0x08 */ |
129 | "X (dead)", /* 0x10 */ | ||
130 | "Z (zombie)", /* 0x20 */ | ||
131 | "P (parked)", /* 0x40 */ | ||
132 | |||
133 | /* states beyond TASK_REPORT: */ | ||
134 | "I (idle)", /* 0x80 */ | ||
128 | }; | 135 | }; |
129 | 136 | ||
130 | static inline const char *get_task_state(struct task_struct *tsk) | 137 | static inline const char *get_task_state(struct task_struct *tsk) |
131 | { | 138 | { |
132 | unsigned int state = (tsk->state | tsk->exit_state) & TASK_REPORT; | 139 | BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array)); |
133 | 140 | return task_state_array[__get_task_state(tsk)]; | |
134 | /* | ||
135 | * Parked tasks do not run; they sit in __kthread_parkme(). | ||
136 | * Without this check, we would report them as running, which is | ||
137 | * clearly wrong, so we report them as sleeping instead. | ||
138 | */ | ||
139 | if (tsk->state == TASK_PARKED) | ||
140 | state = TASK_INTERRUPTIBLE; | ||
141 | |||
142 | BUILD_BUG_ON(1 + ilog2(TASK_REPORT) != ARRAY_SIZE(task_state_array)-1); | ||
143 | |||
144 | return task_state_array[fls(state)]; | ||
145 | } | 141 | } |
146 | 142 | ||
147 | static inline int get_task_umask(struct task_struct *tsk) | 143 | static inline int get_task_umask(struct task_struct *tsk) |
@@ -421,7 +417,15 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
421 | * esp and eip are intentionally zeroed out. There is no | 417 | * esp and eip are intentionally zeroed out. There is no |
422 | * non-racy way to read them without freezing the task. | 418 | * non-racy way to read them without freezing the task. |
423 | * Programs that need reliable values can use ptrace(2). | 419 | * Programs that need reliable values can use ptrace(2). |
420 | * | ||
421 | * The only exception is if the task is core dumping because | ||
422 | * a program is not able to use ptrace(2) in that case. It is | ||
423 | * safe because the task has stopped executing permanently. | ||
424 | */ | 424 | */ |
425 | if (permitted && (task->flags & PF_DUMPCORE)) { | ||
426 | eip = KSTK_EIP(task); | ||
427 | esp = KSTK_ESP(task); | ||
428 | } | ||
425 | } | 429 | } |
426 | 430 | ||
427 | get_task_comm(tcomm, task); | 431 | get_task_comm(tcomm, task); |