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.
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