2017-08-09 01:30:18

by Xie XiuQi

[permalink] [raw]
Subject: [PATCH v2 0/2] sched/debug: show task state on /proc/sched_debug

Currently, we print the runnable task in /proc/sched_debug, but there is no task state information.
We don't know which task is in runqueue, and which task is in sleep. For the convenience of debugging,
in this patch, we add task state in runnable task list, like this:

runnable tasks:
S task PID tree-key switches prio wait-time sum-exec sum-sleep
-----------------------------------------------------------------------------------------------------------
S watchdog/239 1452 -11.917445 2811 0 0.000000 8.949306 0.000000 7 0 /
S migration/239 1453 20686.367740 8 0 0.000000 16215.720897 0.000000 7 0 /
S ksoftirqd/239 1454 115383.841071 12 120 0.000000 0.200683 0.000000 7 0 /
>R test 21287 4872.190970 407 120 0.000000 4874.911790 0.000000 7 0 /autogroup-150
R test 21288 4868.385454 401 120 0.000000 3672.341489 0.000000 7 0 /autogroup-150
R test 21289 4868.326776 384 120 0.000000 3424.934159 0.000000 7 0 /autogroup-150

---
v2:
fix complile error in patch 2.

Xie XiuQi (2):
sched/debug: show task state on /proc/sched_debug
sched/debug: intruduce task_state_to_char helper function

include/linux/sched.h | 13 +++++++++++++
kernel/sched/core.c | 15 ++++-----------
kernel/sched/debug.c | 10 ++++++----
3 files changed, 23 insertions(+), 15 deletions(-)

--
1.8.3.1


2017-08-09 01:30:16

by Xie XiuQi

[permalink] [raw]
Subject: [PATCH v2 2/2] sched/debug: intruduce task_state_to_char helper function

Now we have more than one place to get the task state,
so intruduce task_state_to_char helper to save some code.

No function changed.

Signed-off-by: Xie XiuQi <[email protected]>
---
include/linux/sched.h | 13 +++++++++++++
kernel/sched/core.c | 15 ++++-----------
kernel/sched/debug.c | 10 +++-------
3 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2b69fc6..d20edc0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1189,6 +1189,19 @@ static inline pid_t task_pgrp_nr(struct task_struct *tsk)
return task_pgrp_nr_ns(tsk, &init_pid_ns);
}

+static inline char task_state_to_char(struct task_struct *task)
+{
+ const char stat_nam[] = TASK_STATE_TO_CHAR_STR;
+ unsigned long state = task->state;
+
+ state = state ? __ffs(state) + 1 : 0;
+
+ /* Make sure the string lines up properly with the number of task states: */
+ BUILD_BUG_ON(sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1);
+
+ return state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?';
+}
+
/**
* is_global_init - check if a task structure is init. Since init
* is free to have sub-threads we need to check tgid.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 326d4f8..79a3841 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5316,24 +5316,17 @@ void io_schedule(void)
return retval;
}

-static const char stat_nam[] = TASK_STATE_TO_CHAR_STR;
-
void sched_show_task(struct task_struct *p)
{
unsigned long free = 0;
int ppid;
- unsigned long state = p->state;
-
- /* Make sure the string lines up properly with the number of task states: */
- BUILD_BUG_ON(sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1);

if (!try_get_task_stack(p))
return;
- if (state)
- state = __ffs(state) + 1;
- printk(KERN_INFO "%-15.15s %c", p->comm,
- state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
- if (state == TASK_RUNNING)
+
+ printk(KERN_INFO "%-15.15s %c", p->comm, task_state_to_char(p));
+
+ if (p->state == TASK_RUNNING)
printk(KERN_CONT " running task ");
#ifdef CONFIG_DEBUG_STACK_USAGE
free = stack_not_used(p);
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 60f7e20..b6ed776 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -426,14 +426,10 @@ static char *task_group_path(struct task_group *tg)
static void
print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
{
- unsigned long state;
-
- if (rq->curr == p) {
+ if (rq->curr == p)
SEQ_printf(m, ">R");
- } else {
- state = p->state ? __ffs(p->state) + 1 : 0;
- SEQ_printf(m, " %c", state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
- }
+ else
+ SEQ_printf(m, " %c", task_state_to_char(p));

SEQ_printf(m, "%15s %5d %9Ld.%06ld %9Ld %5d ",
p->comm, task_pid_nr(p),
--
1.8.3.1

2017-08-09 01:30:20

by Xie XiuQi

[permalink] [raw]
Subject: [PATCH v2 1/2] sched/debug: show task state on /proc/sched_debug

Currently, we print the runnable task in /proc/sched_debug, but there is no task state information.
We don't know which task is in runqueue, and which task is in sleep. For the convenience of debugging,
in this patch, we add task state in runnable task list, like this:

runnable tasks:
S task PID tree-key switches prio wait-time sum-exec sum-sleep
-----------------------------------------------------------------------------------------------------------
S watchdog/239 1452 -11.917445 2811 0 0.000000 8.949306 0.000000 7 0 /
S migration/239 1453 20686.367740 8 0 0.000000 16215.720897 0.000000 7 0 /
S ksoftirqd/239 1454 115383.841071 12 120 0.000000 0.200683 0.000000 7 0 /
>R test 21287 4872.190970 407 120 0.000000 4874.911790 0.000000 7 0 /autogroup-150
R test 21288 4868.385454 401 120 0.000000 3672.341489 0.000000 7 0 /autogroup-150
R test 21289 4868.326776 384 120 0.000000 3424.934159 0.000000 7 0 /autogroup-150

Signed-off-by: Xie XiuQi <[email protected]>
---
kernel/sched/debug.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 38f0193..60f7e20 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -421,13 +421,19 @@ static char *task_group_path(struct task_group *tg)
}
#endif

+static const char stat_nam[] = TASK_STATE_TO_CHAR_STR;
+
static void
print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
{
- if (rq->curr == p)
- SEQ_printf(m, "R");
- else
- SEQ_printf(m, " ");
+ unsigned long state;
+
+ if (rq->curr == p) {
+ SEQ_printf(m, ">R");
+ } else {
+ state = p->state ? __ffs(p->state) + 1 : 0;
+ SEQ_printf(m, " %c", state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
+ }

SEQ_printf(m, "%15s %5d %9Ld.%06ld %9Ld %5d ",
p->comm, task_pid_nr(p),
@@ -456,9 +462,9 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)

SEQ_printf(m,
"\nrunnable tasks:\n"
- " task PID tree-key switches prio"
+ " S task PID tree-key switches prio"
" wait-time sum-exec sum-sleep\n"
- "------------------------------------------------------"
+ "-------------------------------------------------------"
"----------------------------------------------------\n");

rcu_read_lock();
--
1.8.3.1