Blame SOURCES/0028-Fix-for-ps-vm-commands-to-display-correct-MEM-and-RS.patch

56ae9b
From 74fe453f2b5ddf1e1571d006d486cb214817a0ed Mon Sep 17 00:00:00 2001
56ae9b
From: Lianbo Jiang <lijiang@redhat.com>
56ae9b
Date: Wed, 9 Nov 2022 14:21:57 +0800
56ae9b
Subject: [PATCH 28/28] Fix for "ps/vm" commands to display correct %MEM and
56ae9b
 RSS values
56ae9b
56ae9b
The ps/vm commands may print the bogus value of the %MEM and RSS, the
56ae9b
reason is that the counter of rss stat is updated in asynchronous manner
56ae9b
and may become negative, when the SPLIT_RSS_COUNTING is enabled in kernel.
56ae9b
56ae9b
As a result, crash will read it from memory and convert from negative to
56ae9b
unsigned long integer, eventually it overflows and gets a big integer. For
56ae9b
example:
56ae9b
56ae9b
  crash> ps 1393
56ae9b
      PID    PPID  CPU       TASK        ST  %MEM      VSZ      RSS  COMM
56ae9b
     1393       1  24  ffff9584bb542100  RU  541298032135.9     4132 18014398509481908  enlinuxpc64
56ae9b
                                             ^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^^^
56ae9b
56ae9b
This is unexpected, crash needs to correct its value for this case.
56ae9b
56ae9b
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
56ae9b
---
56ae9b
 memory.c | 23 ++++++++++++++++++-----
56ae9b
 1 file changed, 18 insertions(+), 5 deletions(-)
56ae9b
56ae9b
diff --git a/memory.c b/memory.c
56ae9b
index ddbf458277f0..2167281b6039 100644
56ae9b
--- a/memory.c
56ae9b
+++ b/memory.c
56ae9b
@@ -4714,18 +4714,29 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
56ae9b
 		 *  Latest kernels have mm_struct.mm_rss_stat[].
56ae9b
 		 */ 
56ae9b
 		if (VALID_MEMBER(mm_struct_rss_stat)) {
56ae9b
-			long anonpages, filepages;
56ae9b
+			long anonpages, filepages, count;
56ae9b
 
56ae9b
 			anonpages = tt->anonpages;
56ae9b
 			filepages = tt->filepages;
56ae9b
-			rss += LONG(tt->mm_struct +
56ae9b
+			count = LONG(tt->mm_struct +
56ae9b
 				OFFSET(mm_struct_rss_stat) +
56ae9b
 				OFFSET(mm_rss_stat_count) +
56ae9b
 				(filepages * sizeof(long)));
56ae9b
-			rss += LONG(tt->mm_struct +
56ae9b
+
56ae9b
+			/*
56ae9b
+			 * The counter is updated in asynchronous manner
56ae9b
+			 * and may become negative, see:
56ae9b
+			 * include/linux/mm.h: get_mm_counter()
56ae9b
+			 */
56ae9b
+			if (count > 0)
56ae9b
+				rss += count;
56ae9b
+
56ae9b
+			count = LONG(tt->mm_struct +
56ae9b
 				OFFSET(mm_struct_rss_stat) +
56ae9b
 				OFFSET(mm_rss_stat_count) +
56ae9b
 				(anonpages * sizeof(long)));
56ae9b
+			if (count > 0)
56ae9b
+				rss += count;
56ae9b
 		}
56ae9b
 
56ae9b
 		/* Check whether SPLIT_RSS_COUNTING is enabled */
56ae9b
@@ -4769,7 +4780,8 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
56ae9b
 							RETURN_ON_ERROR))
56ae9b
 								continue;
56ae9b
 
56ae9b
-						rss_cache += sync_rss;
56ae9b
+						if (sync_rss > 0)
56ae9b
+							rss_cache += sync_rss;
56ae9b
 
56ae9b
 						/* count 1 -> anonpages */
56ae9b
 						if (!readmem(first->task +
56ae9b
@@ -4782,7 +4794,8 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
56ae9b
 							RETURN_ON_ERROR))
56ae9b
 								continue;
56ae9b
 
56ae9b
-						rss_cache += sync_rss;
56ae9b
+						if (sync_rss > 0)
56ae9b
+							rss_cache += sync_rss;
56ae9b
 
56ae9b
 						if (first == last)
56ae9b
 							break;
56ae9b
-- 
56ae9b
2.37.1
56ae9b