From 342cf340ed0386880fe2a3115d6bef32eabb511b Mon Sep 17 00:00:00 2001 From: Kazuhito Hagio Date: Thu, 18 May 2023 11:48:28 +0900 Subject: [PATCH 3/6] Fix "kmem -v" option displaying no regions on Linux 6.3 and later Kernel commit 869176a09606 ("mm/vmalloc.c: add flags to mark vm_map_ram area"), which is contained in Linux 6.3 and later, added "flags" member to struct vmap_area. This was the revival of the "flags" member as kernel commit 688fcbfc06e4 had eliminated it before. As a result, crash started to use the old procedure using the member and displays no vmalloc'd regions, because it does not have the same flag value as the old one. crash> kmem -v VMAP_AREA VM_STRUCT ADDRESS RANGE SIZE crash> To fix this, also check if vmap_area.purge_list exists, which was introduced with the flags and removed later, to determine that the flags member is the old one. Related vmap_area history: v2.6.28 db64fe02258f introduced vmap_area with flags and purge_list v5.4 688fcbfc06e4 removed flags v5.11 96e2db456135 removed purge_list v6.3 869176a09606 added flags again Signed-off-by: Kazuhito Hagio Signed-off-by: Lianbo Jiang --- defs.h | 1 + memory.c | 4 +++- symbols.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/defs.h b/defs.h index 21cc760444d1..bfa07c3f5150 100644 --- a/defs.h +++ b/defs.h @@ -2216,6 +2216,7 @@ struct offset_table { /* stash of commonly-used offsets */ long in6_addr_in6_u; long kset_kobj; long subsys_private_subsys; + long vmap_area_purge_list; }; struct size_table { /* stash of commonly-used sizes */ diff --git a/memory.c b/memory.c index 953fc380c03c..15fa8b2f08f1 100644 --- a/memory.c +++ b/memory.c @@ -429,6 +429,7 @@ vm_init(void) MEMBER_OFFSET_INIT(vmap_area_vm, "vmap_area", "vm"); if (INVALID_MEMBER(vmap_area_vm)) MEMBER_OFFSET_INIT(vmap_area_vm, "vmap_area", "private"); + MEMBER_OFFSET_INIT(vmap_area_purge_list, "vmap_area", "purge_list"); STRUCT_SIZE_INIT(vmap_area, "vmap_area"); if (VALID_MEMBER(vmap_area_va_start) && VALID_MEMBER(vmap_area_va_end) && @@ -9063,7 +9064,8 @@ dump_vmap_area(struct meminfo *vi) readmem(ld->list_ptr[i], KVADDR, vmap_area_buf, SIZE(vmap_area), "vmap_area struct", FAULT_ON_ERROR); - if (VALID_MEMBER(vmap_area_flags)) { + if (VALID_MEMBER(vmap_area_flags) && + VALID_MEMBER(vmap_area_purge_list)) { flags = ULONG(vmap_area_buf + OFFSET(vmap_area_flags)); if (flags != VM_VM_AREA) continue; diff --git a/symbols.c b/symbols.c index f0721023816d..7b1d59203b90 100644 --- a/symbols.c +++ b/symbols.c @@ -9169,6 +9169,7 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(vmap_area_vm)); fprintf(fp, " vmap_area_flags: %ld\n", OFFSET(vmap_area_flags)); + fprintf(fp, " vmap_area_purge_list: %ld\n", OFFSET(vmap_area_purge_list)); fprintf(fp, " module_size_of_struct: %ld\n", OFFSET(module_size_of_struct)); -- 2.37.1