From cada55e284d3e7c2a9feb9eae6bb59f1816eb8da Mon Sep 17 00:00:00 2001
From: xueguolun <xueguolun@xiaomi.com>
Date: Wed, 29 Nov 2023 17:36:32 +0800
Subject: [PATCH] [kmem]fix bug of CACHED in kmem -i show memory

It can obviously see that kmem -i show memory info of system.
But CACHED have wrong output for add up size of cached memory.

The reason of this bug is:
newest kernel version use "struct address_space *swapper_spaces[MAX_SWAPFILES]"
instead of "struct address_space swapper_spaces[MAX_SWAPFILES]" in old kernel.

So newest version need to readmem twice, first is address of one struct address_space
second is value of struct address_space

fix before:
crash> kmem -i
                 PAGES        TOTAL      PERCENTAGE
    TOTAL MEM  2854115      10.9 GB         ----
         FREE   169699     662.9 MB    5% of TOTAL MEM
         USED  2684416      10.2 GB   94% of TOTAL MEM
       SHARED   891094       3.4 GB   31% of TOTAL MEM
      BUFFERS      329       1.3 MB    0% of TOTAL MEM
       CACHED  873327085626  3331478.4 GB  30598875% of TOTAL MEM
         SLAB   230128     898.9 MB    8% of TOTAL MEM

fix after:
crash> kmem -i
                 PAGES        TOTAL      PERCENTAGE
    TOTAL MEM  2854115      10.9 GB         ----
         FREE   169699     662.9 MB    5% of TOTAL MEM
         USED  2684416      10.2 GB   94% of TOTAL MEM
       SHARED   891094       3.4 GB   31% of TOTAL MEM
      BUFFERS      329       1.3 MB    0% of TOTAL MEM
       CACHED  1729018       6.6 GB   60% of TOTAL MEM
         SLAB   230128     898.9 MB    8% of TOTAL MEM

Signed-off-by: xueguolun <xueguolun@xiaomi.com>
---
 memory.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/memory.c b/memory.c
index 791194a..a14e8d3 100644
--- a/memory.c
+++ b/memory.c
@@ -8479,6 +8479,7 @@ dump_kmeminfo(void)
         ulong freehighmem_pages;
         ulong totallowmem_pages;
         ulong freelowmem_pages;
+        ulong address_space_ptr;
 	ulong allowed;
 	long committed;
 	ulong overcommit_kbytes = 0;
@@ -8649,11 +8650,26 @@ dump_kmeminfo(void)
 		} else if (symbol_exists("swapper_spaces") &&
 		    (len = get_array_length("swapper_spaces", NULL, 0))) {
 			for (i = 0; i < len; i++) {
-		    		if (!readmem(symbol_value("swapper_spaces") + 
-				    i * SIZE(address_space), KVADDR, 
-		    		    swapper_space, SIZE(address_space), 
-				    "swapper_space", RETURN_ON_ERROR))
-					break;
+
+                                if (THIS_KERNEL_VERSION < LINUX(4,11,0)) {
+		    		        if (!readmem(symbol_value("swapper_spaces") +
+				        i * SIZE(address_space), KVADDR,
+		    		        swapper_space, SIZE(address_space),
+				        "swapper_space", RETURN_ON_ERROR))
+					        break;
+                                } else {
+                                        if (!readmem(symbol_value("swapper_spaces") +
+                                        i * sizeof(unsigned long), KVADDR,
+                                        &address_space_ptr, sizeof(unsigned long),
+                                        "swapper_space ptr", RETURN_ON_ERROR))
+                                                break;
+
+                                        if (address_space_ptr > 0 && !readmem(address_space_ptr,
+                                        KVADDR, swapper_space, SIZE(address_space),
+                                        "swapper_space", RETURN_ON_ERROR))
+                                                break;
+                                }
+
 				swapper_space_nrpages += ULONG(swapper_space + 
 					OFFSET(address_space_nrpages));
 			}
-- 
2.43.0

