[PATCH] Fix "ps/vm" commands to display correct memory usage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Kernel commit eca56ff906bd ("mm, shmem: add internal shmem resident
memory accounting"), which adds internal shmem resident memory
accounting, and tallies into the mm_rss_stat counter.

As a result, the "ps/vm" commands 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
                                                                  ^^^

Currently, the "ps/vm" commands missed the shmem pages count, 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@xxxxxxxxxx>
Signed-off-by: Lianbo Jiang <lijiang@xxxxxxxxxx>
---
 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..df85b69963b6 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

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux