[Crash-utility] [PATCH] speed up "ps -r" by storing the length of rlim array

Kazuhito Hagio k-hagio at ab.jp.nec.com
Mon Apr 16 15:32:22 UTC 2018


Without this patch, the "ps -r" command takes one minute or more per 1,000
tasks.  The cause is that getting the length of {task,signal}_struct.rlim
array takes some time and it is done for each task.

This patch stores the value, and it will take only about 0.5 seconds per
1,000 tasks.

Signed-off-by: Kazuhito Hagio <k-hagio at ab.jp.nec.com>
---
 defs.h    | 2 ++
 symbols.c | 8 ++++++++
 task.c    | 6 ++++--
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/defs.h b/defs.h
index adddb9f..4b6ebc2 100644
--- a/defs.h
+++ b/defs.h
@@ -2191,6 +2191,8 @@ struct array_table {
 	int kmem_cache_cpu_slab;
 	int rt_prio_array_queue;
 	int height_to_maxnodes;
+	int task_struct_rlim;
+	int signal_struct_rlim;
 };
 
 /*
diff --git a/symbols.c b/symbols.c
index 638800a..e934e7f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -8440,6 +8440,10 @@ builtin_array_length(char *s, int len, int *two_dim)
 		lenptr = &array_table.kmem_cache_cpu_slab;
 	else if (STREQ(s, "rt_prio_array.queue"))
 		lenptr = &array_table.rt_prio_array_queue;
+	else if (STREQ(s, "task_struct.rlim"))
+		lenptr = &array_table.task_struct_rlim;
+	else if (STREQ(s, "signal_struct.rlim"))
+		lenptr = &array_table.signal_struct_rlim;
 
 	if (!lenptr)                /* not stored */
 		return(len);        
@@ -10520,6 +10524,10 @@ dump_offset_table(char *spec, ulong makestruct)
 		ARRAY_LENGTH(kmem_cache_cpu_slab));
         fprintf(fp, "           rt_prio_array_queue: %d\n",
                 ARRAY_LENGTH(rt_prio_array_queue));
+	fprintf(fp, "              task_struct_rlim: %d\n",
+		ARRAY_LENGTH(task_struct_rlim));
+	fprintf(fp, "            signal_struct_rlim: %d\n",
+		ARRAY_LENGTH(signal_struct_rlim));
 
 	if (spec) {
 		int in_size_table, in_array_table, arrays, offsets, sizes;
diff --git a/task.c b/task.c
index 560adfa..2418e4c 100644
--- a/task.c
+++ b/task.c
@@ -4027,12 +4027,14 @@ show_task_rlimit(struct task_context *tc)
 	in_task_struct = in_signal_struct = FALSE;
 
 	if (VALID_MEMBER(task_struct_rlim)) {
-		rlimit_index = get_array_length("task_struct.rlim", NULL, 0);
+		rlimit_index = (i = ARRAY_LENGTH(task_struct_rlim)) ?
+			i : get_array_length("task_struct.rlim", NULL, 0);
 		in_task_struct = TRUE;
 	} else if (VALID_MEMBER(signal_struct_rlim)) {
 		if (!VALID_MEMBER(task_struct_signal))
 			error(FATAL, "cannot determine rlimit array location\n");
-		rlimit_index = get_array_length("signal_struct.rlim", NULL, 0);
+		rlimit_index = (i = ARRAY_LENGTH(signal_struct_rlim)) ?
+			i : get_array_length("signal_struct.rlim", NULL, 0);
 		in_signal_struct = TRUE;
 	}
 
-- 
1.8.3.1




More information about the Crash-utility mailing list