<div dir="ltr"><div dir="ltr">On Thu, Mar 3, 2022 at 10:43 AM <<a href="mailto:crash-utility-request@redhat.com">crash-utility-request@redhat.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Date: Wed, 2 Mar 2022 21:37:45 +0000<br>
From: Austin Kim <<a href="mailto:austindh.kim@gmail.com" target="_blank">austindh.kim@gmail.com</a>><br>
To: <a href="mailto:k-hagio-ab@nec.com" target="_blank">k-hagio-ab@nec.com</a>, <a href="mailto:lijiang@redhat.com" target="_blank">lijiang@redhat.com</a>, <a href="mailto:crash-utility@redhat.com" target="_blank">crash-utility@redhat.com</a><br>
Cc: <a href="mailto:kernel-team@lge.com" target="_blank">kernel-team@lge.com</a>, <a href="mailto:mikeseohyungjin@gmail.com" target="_blank">mikeseohyungjin@gmail.com</a><br>
Subject: [Crash-utility] [PATCH v3] ps: Add support to "ps -l|-m" to<br>
properly display process<br>
Message-ID: <20220302213745.GA868@raspberrypi><br>
Content-Type: text/plain; charset=us-ascii<br>
<br>
Sometimes kernel image is generated without CONFIG_SCHEDSTATS or CONFIG_SCHED_INFO.<br>
Where relevant commit id is f6db83479932 ("sched/stat: Simplify the sched_info accounting")<br>
<br>
- CONFIG_SCHED_INFO: KERNEL_VERSION >= LINUX(4,2,0)<br>
- CONFIG_SCHEDSTATS: KERNEL_VERSION < LINUX(4,2,0)<br>
<br>
Running crash-utility with above kernel image,<br>
"ps -l" option cannot display all processes sorted with most recently-run process.<br>
Also "ps -m" option cannot display all processes with timestamp.<br>
<br>
crash> ps -l or crash> ps -m<br>
ps: last-run timestamps do not exist in this kernel<br>
Usage: ps [-k|-u|-G] [-s]<br>
[-p|-c|-t|-[l|m][-C cpu]|-a|-g|-r|-S]<br>
[pid | task | command] ...<br>
Enter "help ps" for details.<br>
<br>
This is because output of "ps -l|-m" depends on task_struct.sched_info.last_arrival.<br>
<br>
Without CONFIG_SCHEDSTATS or CONFIG_SCHED_INFO, 'sched_info' field is not included<br>
in task_struct. In this case we make "ps -l|-m" option to access 'exec_start' <br>
field of sched_entity where 'exec_start' is task_struct.se.exec_start.<br>
<br>
The 'task_struct.se.exec_start' contains the most recently-executed timestamp <br>
when process is running in the below cases;<br>
<br>
- enqueued to runqueue<br>
- dequeued from runqueue<br>
- scheduler tick is invoked<br>
- etc<br>
<br>
'task_struct.se.exec_start' could be one of statistics which indicates the most <br>
recently-run timestamp of process activity.<br></blockquote><div><br></div><div>Thank you for the update, Austin.</div><div><br></div><div>If the task is migraged, the value of the 'task_struct.se.exec_start ' will be set to zero and may be updated in the next scheduling with the new time. In this case, does the patch still work well as expected?</div><div><br></div><div>Thanks.</div><div>Lianbo</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
With this patch, "ps -l|-m" option works well without CONFIG_SCHEDSTATS or<br>
CONFIG_SCHED_INFO.<br>
<br>
Signed-off-by: Austin Kim <<a href="mailto:austindh.kim@gmail.com" target="_blank">austindh.kim@gmail.com</a>><br>
---<br>
defs.h | 1 +<br>
help.c | 5 +++--<br>
symbols.c | 2 ++<br>
task.c | 20 ++++++++++++++++----<br>
4 files changed, 22 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/defs.h b/defs.h<br>
index bf2c59b..841bd0b 100644<br>
--- a/defs.h<br>
+++ b/defs.h<br>
@@ -2168,6 +2168,7 @@ struct offset_table { /* stash of commonly-used offsets */<br>
long sbitmap_queue_min_shallow_depth;<br>
long sbq_wait_state_wait_cnt;<br>
long sbq_wait_state_wait;<br>
+ long sched_entity_exec_start;<br>
};<br>
<br>
struct size_table { /* stash of commonly-used sizes */<br>
diff --git a/help.c b/help.c<br>
index 8347668..6ca7c92 100644<br>
--- a/help.c<br>
+++ b/help.c<br>
@@ -1442,7 +1442,8 @@ char *help_ps[] = {<br>
" and system times.",<br>
" -l display the task's last-run timestamp value, using either the",<br>
" task_struct's last_run value, the task_struct's timestamp value",<br>
-" or the task_struct's sched_entity last_arrival value, whichever",<br>
+" the task_struct's sched_info last_arrival value",<br>
+" or the task_struct's sched_entity exec_start value, whichever",<br>
" applies, of selected, or all, tasks; the list is sorted with the",<br>
" most recently-run task (with the largest timestamp) shown first,",<br>
" followed by the task's current state.",<br>
@@ -1621,7 +1622,7 @@ char *help_ps[] = {<br>
" > 9497 1 0 ffff880549ec2ab0 RU 0.0 42314692 138664 oracle",<br>
" ",<br>
" Show all tasks sorted by their task_struct's last_run, timestamp, or", <br>
-" sched_entity last_arrival timestamp value, whichever applies:\n",<br>
+" sched_info last_arrival or sched_entity exec_start timestamp value, whichever applies:\n",<br>
" %s> ps -l",<br>
" [20811245123] [IN] PID: 37 TASK: f7153030 CPU: 2 COMMAND: \"events/2\"",<br>
" [20811229959] [IN] PID: 1756 TASK: f2a5a570 CPU: 2 COMMAND: \"ntpd\"",<br>
diff --git a/symbols.c b/symbols.c<br>
index ba5e274..1c40586 100644<br>
--- a/symbols.c<br>
+++ b/symbols.c<br>
@@ -10290,6 +10290,8 @@ dump_offset_table(char *spec, ulong makestruct)<br>
OFFSET(sched_entity_my_q));<br>
fprintf(fp, " sched_entity_on_rq: %ld\n",<br>
OFFSET(sched_entity_on_rq));<br>
+ fprintf(fp, " sched_entity_exec_start: %ld\n",<br>
+ OFFSET(sched_entity_exec_start));<br>
fprintf(fp, " cfs_rq_nr_running: %ld\n",<br>
OFFSET(cfs_rq_nr_running));<br>
fprintf(fp, " cfs_rq_rb_leftmost: %ld\n",<br>
diff --git a/task.c b/task.c<br>
index 864c838..2c12196 100644<br>
--- a/task.c<br>
+++ b/task.c<br>
@@ -334,9 +334,15 @@ task_init(void)<br>
if (VALID_MEMBER(task_struct_sched_info))<br>
MEMBER_OFFSET_INIT(sched_info_last_arrival, <br>
"sched_info", "last_arrival");<br>
+ MEMBER_OFFSET_INIT(task_struct_se, "task_struct", "se");<br>
+ if (VALID_MEMBER(task_struct_se)) {<br>
+ STRUCT_SIZE_INIT(sched_entity, "sched_entity");<br>
+ MEMBER_OFFSET_INIT(sched_entity_exec_start, "sched_entity", "exec_start");<br>
+ }<br>
if (VALID_MEMBER(task_struct_last_run) || <br>
VALID_MEMBER(task_struct_timestamp) ||<br>
- VALID_MEMBER(sched_info_last_arrival)) {<br>
+ VALID_MEMBER(sched_info_last_arrival) ||<br>
+ VALID_MEMBER(sched_entity_exec_start)) {<br>
char buf[BUFSIZE];<br>
strcpy(buf, "alias last ps -l");<br>
alias_init(buf);<br>
@@ -3559,7 +3565,8 @@ cmd_ps(void)<br>
case 'm':<br>
if (INVALID_MEMBER(task_struct_last_run) &&<br>
INVALID_MEMBER(task_struct_timestamp) &&<br>
- INVALID_MEMBER(sched_info_last_arrival)) {<br>
+ INVALID_MEMBER(sched_info_last_arrival) &&<br>
+ INVALID_MEMBER(sched_entity_exec_start)) {<br>
error(INFO, <br>
"last-run timestamps do not exist in this kernel\n");<br>
argerrs++;<br>
@@ -3574,7 +3581,8 @@ cmd_ps(void)<br>
case 'l':<br>
if (INVALID_MEMBER(task_struct_last_run) &&<br>
INVALID_MEMBER(task_struct_timestamp) &&<br>
- INVALID_MEMBER(sched_info_last_arrival)) {<br>
+ INVALID_MEMBER(sched_info_last_arrival) &&<br>
+ INVALID_MEMBER(sched_entity_exec_start)) {<br>
error(INFO, <br>
"last-run timestamps do not exist in this kernel\n");<br>
argerrs++;<br>
@@ -6020,7 +6028,11 @@ task_last_run(ulong task)<br>
timestamp = tt->last_task_read ? ULONGLONG(tt->task_struct + <br>
OFFSET(task_struct_sched_info) + <br>
OFFSET(sched_info_last_arrival)) : 0;<br>
- <br>
+ else if (VALID_MEMBER(sched_entity_exec_start))<br>
+ timestamp = tt->last_task_read ? ULONGLONG(tt->task_struct +<br>
+ OFFSET(task_struct_se) +<br>
+ OFFSET(sched_entity_exec_start)) : 0;<br>
+<br>
return timestamp;<br>
}<br>
<br>
-- <br>
2.20.1<br>
</blockquote></div></div>