On Thu, May 18, 2023 at 12:28 PM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
wrote:
 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
 
Thank you for the fix, Kazu.
It looks good to me. So: Ack.
Thanks.
Lianbo
 Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.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.31.1