190 lines
6.1 KiB
Diff
190 lines
6.1 KiB
Diff
|
From 69f38d777450c3fe4f089eaa403434815eecdbd7 Mon Sep 17 00:00:00 2001
|
||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||
|
Date: Tue, 8 Aug 2023 21:25:31 +0800
|
||
|
Subject: [PATCH 24/30] Fix "ps/vm" commands to display correct memory usage
|
||
|
|
||
|
Kernel commit eca56ff906bd ("mm, shmem: add internal shmem resident
|
||
|
memory accounting") added shmem resident memory accounting and it's
|
||
|
tallied up into the mm_rss_stat counter.
|
||
|
|
||
|
As a result, the "ps/vm" commands miss the shmem pages count and fail to
|
||
|
show correct memory usage when a process uses an anonymous shared memory
|
||
|
region.
|
||
|
|
||
|
Without the patch:
|
||
|
crash> ps 2150
|
||
|
PID PPID CPU TASK ST %MEM VSZ RSS COMM
|
||
|
2150 2105 14 ffff8fba86d74d40 IN 0.0 10488392 444 mmap_test
|
||
|
^^^
|
||
|
|
||
|
Let's count the shmem pages together with regular files and anonymous
|
||
|
pages.
|
||
|
|
||
|
With the patch:
|
||
|
crash> ps 2150
|
||
|
PID PPID CPU TASK ST %MEM VSZ RSS COMM
|
||
|
2150 2105 14 ffff8fba86d74d40 IN 20.8 10488392 3659008 mmap_test
|
||
|
|
||
|
Reported-by: Buland Kumar Singh <bsingh@redhat.com>
|
||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||
|
---
|
||
|
defs.h | 1 +
|
||
|
memory.c | 59 ++++++++++++++++++++++++++++++++++++++++++--------------
|
||
|
task.c | 1 +
|
||
|
3 files changed, 46 insertions(+), 15 deletions(-)
|
||
|
|
||
|
diff --git a/defs.h b/defs.h
|
||
|
index 5ee60f1eb3a5..f784d40c0b17 100644
|
||
|
--- a/defs.h
|
||
|
+++ b/defs.h
|
||
|
@@ -887,6 +887,7 @@ struct task_table { /* kernel/local task table data */
|
||
|
int callbacks;
|
||
|
struct task_context **context_by_task; /* task_context sorted by task addr */
|
||
|
ulong pid_xarray;
|
||
|
+ long shmempages;
|
||
|
};
|
||
|
|
||
|
#define TASK_INIT_DONE (0x1)
|
||
|
diff --git a/memory.c b/memory.c
|
||
|
index acbee6389472..3f524fa40eb4 100644
|
||
|
--- a/memory.c
|
||
|
+++ b/memory.c
|
||
|
@@ -4466,13 +4466,13 @@ in_user_stack(ulong task, ulong vaddr)
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * Set the const value of filepages and anonpages
|
||
|
- * according to MM_FILEPAGES and MM_ANONPAGES.
|
||
|
+ * Set the const value of filepages, anonpages and shmempages
|
||
|
+ * according to MM_FILEPAGES, MM_ANONPAGES and MM_SHMEMPAGES.
|
||
|
*/
|
||
|
static void
|
||
|
rss_page_types_init(void)
|
||
|
{
|
||
|
- long anonpages, filepages;
|
||
|
+ long anonpages, filepages, shmempages;
|
||
|
|
||
|
if (VALID_MEMBER(mm_struct_rss))
|
||
|
return;
|
||
|
@@ -4487,6 +4487,15 @@ rss_page_types_init(void)
|
||
|
}
|
||
|
tt->filepages = filepages;
|
||
|
tt->anonpages = anonpages;
|
||
|
+
|
||
|
+ /*
|
||
|
+ * The default value(MM_SHMEMPAGES) is 3, which is introduced
|
||
|
+ * in linux v4.5-rc1 and later. See commit eca56ff906bd.
|
||
|
+ */
|
||
|
+ if (!enumerator_value("MM_SHMEMPAGES", &shmempages))
|
||
|
+ tt->shmempages = -1;
|
||
|
+ else
|
||
|
+ tt->shmempages = shmempages;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -4812,10 +4821,11 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||
|
* Latest kernels have mm_struct.mm_rss_stat[].
|
||
|
*/
|
||
|
if (VALID_MEMBER(mm_struct_rss_stat) && VALID_MEMBER(mm_rss_stat_count)) {
|
||
|
- long anonpages, filepages, count;
|
||
|
+ long anonpages, filepages, shmempages, count;
|
||
|
|
||
|
anonpages = tt->anonpages;
|
||
|
filepages = tt->filepages;
|
||
|
+ shmempages = tt->shmempages;
|
||
|
count = LONG(tt->mm_struct +
|
||
|
OFFSET(mm_struct_rss_stat) +
|
||
|
OFFSET(mm_rss_stat_count) +
|
||
|
@@ -4836,6 +4846,15 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||
|
if (count > 0)
|
||
|
rss += count;
|
||
|
|
||
|
+ if (shmempages > 0) {
|
||
|
+ count = LONG(tt->mm_struct +
|
||
|
+ OFFSET(mm_struct_rss_stat) +
|
||
|
+ OFFSET(mm_rss_stat_count) +
|
||
|
+ (shmempages * sizeof(long)));
|
||
|
+ if (count > 0)
|
||
|
+ rss += count;
|
||
|
+ }
|
||
|
+
|
||
|
} else if (VALID_MEMBER(mm_struct_rss_stat)) {
|
||
|
/* 6.2: struct percpu_counter rss_stat[NR_MM_COUNTERS] */
|
||
|
ulong fbc;
|
||
|
@@ -4847,6 +4866,10 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||
|
fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) +
|
||
|
(tt->anonpages * SIZE(percpu_counter));
|
||
|
rss += percpu_counter_sum_positive(fbc);
|
||
|
+
|
||
|
+ fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) +
|
||
|
+ (tt->shmempages * SIZE(percpu_counter));
|
||
|
+ rss += percpu_counter_sum_positive(fbc);
|
||
|
}
|
||
|
|
||
|
/* Check whether SPLIT_RSS_COUNTING is enabled */
|
||
|
@@ -4880,12 +4903,11 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||
|
if (ACTIVE() || last->rss_cache == UNINITIALIZED) {
|
||
|
while (first <= last)
|
||
|
{
|
||
|
+ ulong addr = first->task + OFFSET(task_struct_rss_stat) +
|
||
|
+ OFFSET(task_rss_stat_count);
|
||
|
+
|
||
|
/* count 0 -> filepages */
|
||
|
- if (!readmem(first->task +
|
||
|
- OFFSET(task_struct_rss_stat) +
|
||
|
- OFFSET(task_rss_stat_count), KVADDR,
|
||
|
- &sync_rss,
|
||
|
- sizeof(int),
|
||
|
+ if (!readmem(addr, KVADDR, &sync_rss, sizeof(int),
|
||
|
"task_struct rss_stat MM_FILEPAGES",
|
||
|
RETURN_ON_ERROR))
|
||
|
continue;
|
||
|
@@ -4894,12 +4916,7 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||
|
rss_cache += sync_rss;
|
||
|
|
||
|
/* count 1 -> anonpages */
|
||
|
- if (!readmem(first->task +
|
||
|
- OFFSET(task_struct_rss_stat) +
|
||
|
- OFFSET(task_rss_stat_count) +
|
||
|
- sizeof(int),
|
||
|
- KVADDR, &sync_rss,
|
||
|
- sizeof(int),
|
||
|
+ if (!readmem(addr + sizeof(int), KVADDR, &sync_rss, sizeof(int),
|
||
|
"task_struct rss_stat MM_ANONPAGES",
|
||
|
RETURN_ON_ERROR))
|
||
|
continue;
|
||
|
@@ -4907,6 +4924,18 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
||
|
if (sync_rss > 0)
|
||
|
rss_cache += sync_rss;
|
||
|
|
||
|
+ /* count 3 -> shmempages */
|
||
|
+ if (tt->shmempages >= 0) {
|
||
|
+ if (!readmem(addr + tt->shmempages * sizeof(int), KVADDR,
|
||
|
+ &sync_rss, sizeof(int),
|
||
|
+ "task_struct rss_stat MM_SHMEMPAGES",
|
||
|
+ RETURN_ON_ERROR))
|
||
|
+ continue;
|
||
|
+
|
||
|
+ if (sync_rss > 0)
|
||
|
+ rss_cache += sync_rss;
|
||
|
+ }
|
||
|
+
|
||
|
if (first == last)
|
||
|
break;
|
||
|
first++;
|
||
|
diff --git a/task.c b/task.c
|
||
|
index c9206f50c679..4018a543b715 100644
|
||
|
--- a/task.c
|
||
|
+++ b/task.c
|
||
|
@@ -7873,6 +7873,7 @@ dump_task_table(int verbose)
|
||
|
fprintf(fp, " init_pid_ns: %lx\n", tt->init_pid_ns);
|
||
|
fprintf(fp, " filepages: %ld\n", tt->filepages);
|
||
|
fprintf(fp, " anonpages: %ld\n", tt->anonpages);
|
||
|
+ fprintf(fp, " shmempages: %ld\n", tt->shmempages);
|
||
|
fprintf(fp, " stack_end_magic: %lx\n", tt->stack_end_magic);
|
||
|
fprintf(fp, " pf_kthread: %lx ", tt->pf_kthread);
|
||
|
switch (tt->pf_kthread)
|
||
|
--
|
||
|
2.37.1
|
||
|
|