diff options
Diffstat (limited to 'fs/proc/array.c')
| -rw-r--r-- | fs/proc/array.c | 45 | 
1 files changed, 25 insertions, 20 deletions
| diff --git a/fs/proc/array.c b/fs/proc/array.c index 88c355574aa0..9390032a11e1 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  /*   *  linux/fs/proc/array.c   * @@ -62,6 +63,7 @@  #include <linux/mman.h>  #include <linux/sched/mm.h>  #include <linux/sched/numa_balancing.h> +#include <linux/sched/task_stack.h>  #include <linux/sched/task.h>  #include <linux/sched/cputime.h>  #include <linux/proc_fs.h> @@ -118,30 +120,25 @@ static inline void task_name(struct seq_file *m, struct task_struct *p)   * simple bit tests.   */  static const char * const task_state_array[] = { -	"R (running)",		/*   0 */ -	"S (sleeping)",		/*   1 */ -	"D (disk sleep)",	/*   2 */ -	"T (stopped)",		/*   4 */ -	"t (tracing stop)",	/*   8 */ -	"X (dead)",		/*  16 */ -	"Z (zombie)",		/*  32 */ + +	/* 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 */ +	"P (parked)",		/* 0x40 */ + +	/* states beyond TASK_REPORT: */ +	"I (idle)",		/* 0x80 */  };  static inline const char *get_task_state(struct task_struct *tsk)  { -	unsigned int state = (tsk->state | tsk->exit_state) & TASK_REPORT; - -	/* -	 * Parked tasks do not run; they sit in __kthread_parkme(). -	 * Without this check, we would report them as running, which is -	 * clearly wrong, so we report them as sleeping instead. -	 */ -	if (tsk->state == TASK_PARKED) -		state = TASK_INTERRUPTIBLE; - -	BUILD_BUG_ON(1 + ilog2(TASK_REPORT) != ARRAY_SIZE(task_state_array)-1); - -	return task_state_array[fls(state)]; +	BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array)); +	return task_state_array[__get_task_state(tsk)];  }  static inline int get_task_umask(struct task_struct *tsk) @@ -421,7 +418,15 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,  		 * 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). +		 * +		 * 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.  		 */ +		if (permitted && (task->flags & PF_DUMPCORE)) { +			eip = KSTK_EIP(task); +			esp = KSTK_ESP(task); +		}  	}  	get_task_comm(tcomm, task); |