On Fri, Aug 30, 2024 at 7:39 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
Date: Fri, 30 Aug 2024 10:33:03 -0000
From: qiwu.chen(a)transsion.com
Subject: [Crash-utility] [PATCH] kmem: fix the determination for slab
page
To: devel(a)lists.crash-utility.osci.io
Message-ID: <20240830103303.2824.23557(a)lists.crash-utility.osci.io>
Content-Type: text/plain; charset="utf-8"
The determination for a slab page is changed since kernel commit
8db00ad564617 which migrates PG_slab flag from page flags to the
lower 16 bit of the page type.
Thank you for the fix, qiwu.
Can you help double check if the code related to PG_* flags in the crash
tool needs to be changed accordingly?
Thanks
Lianbo
Before apply this patch:
crash> kmem -s ffff000002aa4100
kmem: address is not allocated in slab subsystem: ffff000002aa4100
After apply this patch:
crash> kmem -s ffff000002aa4100
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
ffff00000140f900 4096 94 126 18 32k task_struct
SLAB MEMORY NODE TOTAL ALLOCATED FREE
fffffdffc00aa800 ffff000002aa0000 0 7 5 2
FREE / [ALLOCATED]
[ffff000002aa4100]
Signed-off-by: qiwu.chen <qiwu.chen(a)transsion.com>
---
defs.h | 1 +
memory.c | 23 +++++++++++++++++++----
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index e9eb9e3..9ef7f97 100644
--- a/defs.h
+++ b/defs.h
@@ -2289,6 +2289,7 @@ struct offset_table { /* stash of
commonly-used offsets */
long track_cpu;
long track_when;
long track_handle;
+ long page_page_type;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/memory.c b/memory.c
index 7bf8f86..f9ad6e4 100644
--- a/memory.c
+++ b/memory.c
@@ -509,6 +509,8 @@ vm_init(void)
ANON_MEMBER_OFFSET_INIT(page_compound_head, "page",
"compound_head");
MEMBER_OFFSET_INIT(page_private, "page", "private");
MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
+ if (MEMBER_EXISTS("page", "page_type"))
+ MEMBER_OFFSET_INIT(page_page_type, "page",
"page_type");
MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd");
@@ -10114,7 +10116,7 @@ static char *
vaddr_to_kmem_cache(ulong vaddr, char *buf, int verbose)
{
physaddr_t paddr;
- ulong page, cache, page_flags;
+ ulong page, cache, page_flags, page_type;
if (!kvtop(NULL, vaddr, &paddr, 0)) {
if (verbose)
@@ -10143,7 +10145,10 @@ vaddr_to_kmem_cache(ulong vaddr, char *buf, int
verbose)
readmem(compound_head(page)+OFFSET(page_flags), KVADDR,
&page_flags, sizeof(ulong),
"page.flags",
FAULT_ON_ERROR);
- if (!(page_flags & (1 << vt->PG_slab)))
+ readmem(page + OFFSET(page_page_type),
KVADDR, &page_type,
+ sizeof(ulong), "page type",
FAULT_ON_ERROR);
+ if (!(page_flags & (1 << vt->PG_slab))
&&
+ !(page_type & (1 << vt->PG_slab)))
return NULL;
} else
return NULL;
@@ -20688,7 +20693,7 @@ char *
is_slab_page(struct meminfo *si, char *buf)
{
int i, cnt;
- ulong page_slab, page_flags, name;
+ ulong page_slab, page_flags, page_type, name;
ulong *cache_list;
char *retval;
@@ -20703,7 +20708,17 @@ is_slab_page(struct meminfo *si, char *buf)
RETURN_ON_ERROR|QUIET))
return NULL;
- if (!(page_flags & (1 << vt->PG_slab)))
+ if (!readmem(si->spec_addr + OFFSET(page_page_type), KVADDR,
+ &page_type, sizeof(ulong), "page.page_type",
+ RETURN_ON_ERROR|QUIET))
+ return NULL;
+
+ /*
+ * PG_slab is migrated from the page flags to the lower 16 bit
+ * of the page type since linux commit 8db00ad564617.
+ */
+ if (!(page_flags & (1 << vt->PG_slab)) &&
+ !(page_type & (1 << vt->PG_slab)))
return NULL;
if (!readmem(si->spec_addr + OFFSET(page_slab), KVADDR,
--
2.25.1