|
|
e64a0b |
From e389667cf62ef5db82f9796cdbc0134ec38612dc Mon Sep 17 00:00:00 2001
|
|
|
e64a0b |
From: Tao Liu <ltao@redhat.com>
|
|
|
e64a0b |
Date: Fri, 21 Jan 2022 13:43:09 +0800
|
|
|
e64a0b |
Subject: [PATCH 08/10] Improve the ps performance for vmcores with large
|
|
|
e64a0b |
number of threads
|
|
|
e64a0b |
|
|
|
e64a0b |
Previously, the ps command will iterate over all threads which
|
|
|
e64a0b |
have the same tgid, to accumulate their rss value, in order to
|
|
|
e64a0b |
get a thread/process's final rss value as part of the final output.
|
|
|
e64a0b |
|
|
|
e64a0b |
For non-live systems, the rss accumulation values are identical for
|
|
|
e64a0b |
threads which have the same tgid, so there is no need to do the
|
|
|
e64a0b |
iteration and accumulation repeatly, thus a lot of readmem calls are
|
|
|
e64a0b |
skipped. Otherwise it will be the performance bottleneck if the
|
|
|
e64a0b |
vmcores have a large number of threads.
|
|
|
e64a0b |
|
|
|
e64a0b |
In this patch, the rss accumulation value will be stored in a cache,
|
|
|
e64a0b |
next time a thread with the same tgid will take it directly without
|
|
|
e64a0b |
the iteration.
|
|
|
e64a0b |
|
|
|
e64a0b |
For example, we can monitor the performance issue when a vmcore has
|
|
|
e64a0b |
~65k processes, most of which are threads for several specific
|
|
|
e64a0b |
processes. Without the patch, it will take ~7h for ps command
|
|
|
e64a0b |
to finish. With the patch, ps command will finish in 1min.
|
|
|
e64a0b |
|
|
|
e64a0b |
Signed-off-by: Tao Liu <ltao@redhat.com>
|
|
|
e64a0b |
---
|
|
|
e64a0b |
defs.h | 1 +
|
|
|
e64a0b |
memory.c | 70 +++++++++++++++++++++++++++++++-------------------------
|
|
|
e64a0b |
task.c | 1 +
|
|
|
e64a0b |
3 files changed, 41 insertions(+), 31 deletions(-)
|
|
|
e64a0b |
|
|
|
e64a0b |
diff --git a/defs.h b/defs.h
|
|
|
e64a0b |
index b63741c7d78b..55600d56ef1c 100644
|
|
|
e64a0b |
--- a/defs.h
|
|
|
e64a0b |
+++ b/defs.h
|
|
|
e64a0b |
@@ -829,6 +829,7 @@ struct task_context { /* context stored for each task */
|
|
|
e64a0b |
struct tgid_context { /* tgid and task stored for each task */
|
|
|
e64a0b |
ulong tgid;
|
|
|
e64a0b |
ulong task;
|
|
|
e64a0b |
+ long rss_cache;
|
|
|
e64a0b |
};
|
|
|
e64a0b |
|
|
|
e64a0b |
struct task_table { /* kernel/local task table data */
|
|
|
e64a0b |
diff --git a/memory.c b/memory.c
|
|
|
e64a0b |
index 5af45fd7d834..e80c59ea4534 100644
|
|
|
e64a0b |
--- a/memory.c
|
|
|
e64a0b |
+++ b/memory.c
|
|
|
e64a0b |
@@ -4665,7 +4665,7 @@ void
|
|
|
e64a0b |
get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
|
|
e64a0b |
{
|
|
|
e64a0b |
struct task_context *tc;
|
|
|
e64a0b |
- long rss = 0;
|
|
|
e64a0b |
+ long rss = 0, rss_cache = 0;
|
|
|
e64a0b |
|
|
|
e64a0b |
BZERO(tm, sizeof(struct task_mem_usage));
|
|
|
e64a0b |
|
|
|
e64a0b |
@@ -4730,38 +4730,46 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
|
|
e64a0b |
(last->tgid == (last + 1)->tgid))
|
|
|
e64a0b |
last++;
|
|
|
e64a0b |
|
|
|
e64a0b |
- while (first <= last)
|
|
|
e64a0b |
- {
|
|
|
e64a0b |
- /* count 0 -> filepages */
|
|
|
e64a0b |
- if (!readmem(first->task +
|
|
|
e64a0b |
- OFFSET(task_struct_rss_stat) +
|
|
|
e64a0b |
- OFFSET(task_rss_stat_count), KVADDR,
|
|
|
e64a0b |
- &sync_rss,
|
|
|
e64a0b |
- sizeof(int),
|
|
|
e64a0b |
- "task_struct rss_stat MM_FILEPAGES",
|
|
|
e64a0b |
- RETURN_ON_ERROR))
|
|
|
e64a0b |
- continue;
|
|
|
e64a0b |
-
|
|
|
e64a0b |
- rss += sync_rss;
|
|
|
e64a0b |
-
|
|
|
e64a0b |
- /* count 1 -> anonpages */
|
|
|
e64a0b |
- if (!readmem(first->task +
|
|
|
e64a0b |
- OFFSET(task_struct_rss_stat) +
|
|
|
e64a0b |
- OFFSET(task_rss_stat_count) +
|
|
|
e64a0b |
- sizeof(int),
|
|
|
e64a0b |
- KVADDR, &sync_rss,
|
|
|
e64a0b |
- sizeof(int),
|
|
|
e64a0b |
- "task_struct rss_stat MM_ANONPAGES",
|
|
|
e64a0b |
- RETURN_ON_ERROR))
|
|
|
e64a0b |
- continue;
|
|
|
e64a0b |
-
|
|
|
e64a0b |
- rss += sync_rss;
|
|
|
e64a0b |
-
|
|
|
e64a0b |
- if (first == last)
|
|
|
e64a0b |
- break;
|
|
|
e64a0b |
- first++;
|
|
|
e64a0b |
+ /*
|
|
|
e64a0b |
+ * Using rss cache for dumpfile is more beneficial than live debug
|
|
|
e64a0b |
+ * because its value never changes in dumpfile.
|
|
|
e64a0b |
+ */
|
|
|
e64a0b |
+ if (ACTIVE() || last->rss_cache == UNINITIALIZED) {
|
|
|
e64a0b |
+ while (first <= last)
|
|
|
e64a0b |
+ {
|
|
|
e64a0b |
+ /* count 0 -> filepages */
|
|
|
e64a0b |
+ if (!readmem(first->task +
|
|
|
e64a0b |
+ OFFSET(task_struct_rss_stat) +
|
|
|
e64a0b |
+ OFFSET(task_rss_stat_count), KVADDR,
|
|
|
e64a0b |
+ &sync_rss,
|
|
|
e64a0b |
+ sizeof(int),
|
|
|
e64a0b |
+ "task_struct rss_stat MM_FILEPAGES",
|
|
|
e64a0b |
+ RETURN_ON_ERROR))
|
|
|
e64a0b |
+ continue;
|
|
|
e64a0b |
+
|
|
|
e64a0b |
+ rss_cache += sync_rss;
|
|
|
e64a0b |
+
|
|
|
e64a0b |
+ /* count 1 -> anonpages */
|
|
|
e64a0b |
+ if (!readmem(first->task +
|
|
|
e64a0b |
+ OFFSET(task_struct_rss_stat) +
|
|
|
e64a0b |
+ OFFSET(task_rss_stat_count) +
|
|
|
e64a0b |
+ sizeof(int),
|
|
|
e64a0b |
+ KVADDR, &sync_rss,
|
|
|
e64a0b |
+ sizeof(int),
|
|
|
e64a0b |
+ "task_struct rss_stat MM_ANONPAGES",
|
|
|
e64a0b |
+ RETURN_ON_ERROR))
|
|
|
e64a0b |
+ continue;
|
|
|
e64a0b |
+
|
|
|
e64a0b |
+ rss_cache += sync_rss;
|
|
|
e64a0b |
+
|
|
|
e64a0b |
+ if (first == last)
|
|
|
e64a0b |
+ break;
|
|
|
e64a0b |
+ first++;
|
|
|
e64a0b |
+ }
|
|
|
e64a0b |
+ last->rss_cache = rss_cache;
|
|
|
e64a0b |
}
|
|
|
e64a0b |
|
|
|
e64a0b |
+ rss += last->rss_cache;
|
|
|
e64a0b |
tt->last_tgid = last;
|
|
|
e64a0b |
}
|
|
|
e64a0b |
}
|
|
|
e64a0b |
diff --git a/task.c b/task.c
|
|
|
e64a0b |
index a79ed0d96fb5..864c838637ee 100644
|
|
|
e64a0b |
--- a/task.c
|
|
|
e64a0b |
+++ b/task.c
|
|
|
e64a0b |
@@ -2947,6 +2947,7 @@ add_context(ulong task, char *tp)
|
|
|
e64a0b |
tg = tt->tgid_array + tt->running_tasks;
|
|
|
e64a0b |
tg->tgid = *tgid_addr;
|
|
|
e64a0b |
tg->task = task;
|
|
|
e64a0b |
+ tg->rss_cache = UNINITIALIZED;
|
|
|
e64a0b |
|
|
|
e64a0b |
if (do_verify && !verify_task(tc, do_verify)) {
|
|
|
e64a0b |
error(INFO, "invalid task address: %lx\n", tc->task);
|
|
|
e64a0b |
--
|
|
|
e64a0b |
2.20.1
|
|
|
e64a0b |
|