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

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