2023-06-07 03:37:41 +00:00
|
|
|
From 342cf340ed0386880fe2a3115d6bef32eabb511b Mon Sep 17 00:00:00 2001
|
|
|
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
|
|
|
Date: Thu, 18 May 2023 11:48:28 +0900
|
2023-09-11 08:55:01 +00:00
|
|
|
Subject: [PATCH 03/30] Fix "kmem -v" option displaying no regions on Linux 6.3
|
2023-06-07 03:37:41 +00:00
|
|
|
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 <k-hagio-ab@nec.com>
|
|
|
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|
|
|
---
|
|
|
|
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
|
|
|
|
|