From 69f38d777450c3fe4f089eaa403434815eecdbd7 Mon Sep 17 00:00:00 2001 From: Lianbo Jiang 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 Signed-off-by: Lianbo Jiang --- 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