kernel commit 06eb61844d ("sched/debug: Add explicit TASK_IDLE
printing") exposed the TASK_IDLE task state to user space as
'I (idle)' state.
On the other hand, crash still shows 'UN' for TASK_IDLE state.
It is confusing for support folks, and 'foreach UN bt', which shows
useful information for troubles like system stall, includes unexpected
idle tasks. So let's print TASK_IDLE as 'ID' state.
Signed-off-by: Kazuhito Hagio <k-hagio(a)ab.jp.nec.com>
---
help.c | 4 ++--
task.c | 22 +++++++++++++++++++++-
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/help.c b/help.c
index 54bf9b4..14cae8e 100644
--- a/help.c
+++ b/help.c
@@ -837,7 +837,7 @@ char *help_foreach[] = {
" kernel perform the command(s) on all kernel threads.",
" active perform the command(s) on the active thread on each CPU.",
" state perform the command(s) on all tasks in the specified state,
which",
-" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA or PA.\n",
+" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA, PA or ID.\n",
" If none of the task-identifying arguments above are entered, the command",
" will be performed on all tasks.\n",
" command select one or more of the following commands to be run on the
tasks",
@@ -1292,7 +1292,7 @@ char *help_ps[] = {
" 3. the CPU number that the task ran on last.",
" 4. the task_struct address or the kernel stack pointer of the process.",
" (see -s option below)",
-" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA).",
+" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA, ID).",
" 6. the percentage of physical memory being used by this task.",
" 7. the virtual address size of this task in kilobytes.",
" 8. the resident set size of this task in kilobytes.",
diff --git a/task.c b/task.c
index 164e546..5412215 100644
--- a/task.c
+++ b/task.c
@@ -5539,7 +5539,11 @@ task_state_string(ulong task, char *buf, int verbose)
}
if (state & _UNINTERRUPTIBLE_) {
- sprintf(buf, "UN");
+ if (valid_task_state(_NOLOAD_) &&
+ (state & _NOLOAD_))
+ sprintf(buf, "ID");
+ else
+ sprintf(buf, "UN");
valid++;
set++;
}
@@ -6282,6 +6286,7 @@ cmd_foreach(void)
STREQ(args[optind], "DE") ||
STREQ(args[optind], "PA") ||
STREQ(args[optind], "WA") ||
+ STREQ(args[optind], "ID") ||
STREQ(args[optind], "SW")) {
if (fd->flags & FOREACH_STATE)
@@ -6307,6 +6312,8 @@ cmd_foreach(void)
fd->state = _PARKED_;
else if (STREQ(args[optind], "WA"))
fd->state = _WAKING_;
+ else if (STREQ(args[optind], "ID"))
+ fd->state = _UNINTERRUPTIBLE_|_NOLOAD_;
if (fd->state == TASK_STATE_UNINITIALIZED)
error(FATAL,
@@ -6687,6 +6694,19 @@ foreach(struct foreach_data *fd)
if (fd->state == _RUNNING_) {
if (task_state(tc->task) != _RUNNING_)
continue;
+ } else if (fd->state & _UNINTERRUPTIBLE_) {
+ if (!(task_state(tc->task) & _UNINTERRUPTIBLE_))
+ continue;
+
+ if (valid_task_state(_NOLOAD_)) {
+ if (fd->state & _NOLOAD_) {
+ if (!(task_state(tc->task) & _NOLOAD_))
+ continue;
+ } else {
+ if ((task_state(tc->task) & _NOLOAD_))
+ continue;
+ }
+ }
} else if (!(task_state(tc->task) & fd->state))
continue;
}
--
1.8.3.1