Skip to content

Commit

Permalink
Fix "ps/vm" commands to display correct memory usage
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
lian-bo authored and k-hagio committed Aug 15, 2023
1 parent 558aecc commit 69f38d7
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
1 change: 1 addition & 0 deletions defs.h
Expand Up @@ -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)
Expand Down
59 changes: 44 additions & 15 deletions memory.c
Expand Up @@ -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;
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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) +
Expand All @@ -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;
Expand All @@ -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 */
Expand Down Expand Up @@ -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;
Expand All @@ -4894,19 +4916,26 @@ 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;

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++;
Expand Down
1 change: 1 addition & 0 deletions task.c
Expand Up @@ -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)
Expand Down

0 comments on commit 69f38d7

Please sign in to comment.