[Crash-utility] [PATCH] Fix "kmem -n" option to display memory blocks on Linux 6.3-rc1 and later

lijiang lijiang at redhat.com
Fri Mar 10 02:56:46 UTC 2023


On Fri, Mar 10, 2023 at 10:28 AM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab at nec.com>
wrote:

> On 2023/03/10 10:48, lijiang wrote:
> >> Thank you for the fix, Kazu.
> >> On Thu, Mar 9, 2023 at 9:44 AM HAGIO KAZUHITO(萩尾 一仁) <
> k-hagio-ab at nec.com <mailto:k-hagio-ab at nec.com>> wrote:
> >>
> >>     Kernel commit d2bf38c088e0 ("driver core: remove private pointer
> from
> >>     struct bus_type") removed the bus_type.p member, and the "kmem -n"
> >>     option fails with the following error before displaying memory block
> >>     information on Linux 6.3-rc1 and later kernels.
> >>
> >>       kmem: invalid structure member offset: bus_type_p
> >>             FILE: memory.c  LINE: 17852  FUNCTION: init_memory_block()
> >>
> >>     Search bus_kset.list instead for subsys_private of memory subsys.
> >>
> >>     Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com <mailto:
> k-hagio-ab at nec.com>>
> >>     ---
> >>      defs.h    |  2 ++
> >>      memory.c  | 64
> +++++++++++++++++++++++++++++++++++++++++++++++++------
> >>      symbols.c |  2 ++
> >>      3 files changed, 62 insertions(+), 6 deletions(-)
> >>
> >>     diff --git a/defs.h b/defs.h
> >>     index 1f2cf6e0ce01..12ad6aaa0998 100644
> >>     --- a/defs.h
> >>     +++ b/defs.h
> >>     @@ -2214,6 +2214,8 @@ struct offset_table {                    /*
> stash of commonly-used offsets */
> >>             long inet6_ifaddr_if_list;
> >>             long inet6_ifaddr_if_next;
> >>             long in6_addr_in6_u;
> >>     +       long kset_kobj;
> >>     +       long subsys_private_subsys;
> >>      };
> >>
> >>      struct size_table {         /* stash of commonly-used sizes */
> >>     diff --git a/memory.c b/memory.c
> >>     index c4a6ecd18004..292b15a0dbab 100644
> >>     --- a/memory.c
> >>     +++ b/memory.c
> >>     @@ -17822,6 +17822,13 @@ static void
> >>      init_memory_block_offset(void)
> >>      {
> >>             MEMBER_OFFSET_INIT(bus_type_p, "bus_type", "p");
> >>     +       if (INVALID_MEMBER(bus_type_p)) {
> >>     +               MEMBER_OFFSET_INIT(kset_list, "kset", "list");
> >>     +               MEMBER_OFFSET_INIT(kset_kobj, "kset", "kobj");
> >>     +               MEMBER_OFFSET_INIT(kobject_name, "kobject", "name");
> >>     +               MEMBER_OFFSET_INIT(kobject_entry, "kobject",
> "entry");
> >>     +               MEMBER_OFFSET_INIT(subsys_private_subsys,
> "subsys_private", "subsys");
> >>     +       }
> >>             MEMBER_OFFSET_INIT(subsys_private_klist_devices,
> >>                                     "subsys_private", "klist_devices");
> >>             MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
> >>     @@ -17842,15 +17849,61 @@ init_memory_block_offset(void)
> >>      }
> >>
> >>      static void
> >>     -init_memory_block(struct list_data *ld, int *klistcnt, ulong
> **klistbuf)
> >>     +init_memory_block(int *klistcnt, ulong **klistbuf)
> >>      {
> >>     -       ulong memory_subsys = symbol_value("memory_subsys");
> >>             ulong private, klist, start;
> >>     +       struct list_data list_data, *ld;
> >>     +
> >>     +       ld = &list_data;
> >>     +       private = 0;
> >>
> >>             init_memory_block_offset();
> >>
> >>     -       readmem(memory_subsys + OFFSET(bus_type_p), KVADDR,
> &private,
> >>     -               sizeof(void *), "memory_subsys.private",
> FAULT_ON_ERROR);
> >>     +       /*
> >>     +        * v6.3-rc1
> >>     +        * d2bf38c088e0 driver core: remove private pointer from
> struct bus_type
> >>     +        */
> >>     +       if (INVALID_MEMBER(bus_type_p)) {
> >>     +               int i, cnt;
> >>     +               char buf[8];    /* need 8 at least to exclude
> "memory_tiering" */
> >>     +               ulong bus_kset, list, name;
> >>     +
> >>     +               BZERO(ld, sizeof(struct list_data));
> >>     +
> >>     +               get_symbol_data("bus_kset", sizeof(ulong),
> &bus_kset);
> >>     +               readmem(bus_kset + OFFSET(kset_list), KVADDR, &list,
> >>     +                       sizeof(ulong), "bus_kset.list",
> FAULT_ON_ERROR);
> >>     +
> >>     +               ld->flags |= LIST_ALLOCATE;
> >>     +               ld->start = list;
> >>     +               ld->end = bus_kset + OFFSET(kset_list);
> >>     +               ld->list_head_offset = OFFSET(kobject_entry);
> >>     +
> >>     +               cnt = do_list(ld);
> >>     +               for (i = 0; i < cnt; i++) {
> >>     +                       readmem(ld->list_ptr[i] +
> OFFSET(kobject_name), KVADDR, &name,
> >>     +                               sizeof(ulong), "kobject.name <
> http://kobject.name>", FAULT_ON_ERROR);
> >>     +                       read_string(name, buf, sizeof(buf));
> >>     +                       buf[7] = '\0';
> >>
> >>
> >> The full name will be truncated, and  the STREQ(buf, "memory") will
> include two kinds of the "memory" and "memory_tiering", but the above code
> comment says to exclude "memory_tiering", looks weird to me. Do I
> misunderstand this?
>
> As the buf array has 8 bytes and the last is set to \0, so
>
>    "memory"         -> memory\0\0
>    "memory_tiering" -> memory_\0
>
> So we can distinguish these with STREQ(buf, "memory").


Thank you for the explanation, Kazu.


>
>
>>
> >>     +                       if (CRASHDEBUG(1))
> >>     +                               fprintf(fp, "kobject: %lx name:
> %s\n", ld->list_ptr[i], buf);
> >>
> >>
> >> BTW:  for the debug information, it might be good to output the full
> name of the memory subsys.
>
> Yes, I was not sure what is the max length of the name, so chose the
> minimum length in order to avoid read error due to out of bounds.
>
> But ok, looking at the usage of read_string() in crash, most of them
> have BUF_SIZE-1.  Maybe we don't need to care about it so much.
> I will change it to 32 in v2.
>
>
It should be good enough to distinguish it from the various subsys names.

an example without "break;"
>
> kobject: ffff8e1d83d83a18 name: platform
> kobject: ffff8e1d83d80e18 name: cpu
> kobject: ffff8e1d83d83c18 name: memory
> kobject: ffff8e1d83d81c18 name: node
> kobject: ffff8e1d83d80c18 name: container
> kobject: ffff8e1d83d80a18 name: workqueue
> kobject: ffff8e1d83d82e18 name: gpio
> kobject: ffff8e1d83d83418 name: virtio
> kobject: ffff8e19cb77da18 name: pci
> kobject: ffff8e19cb77e018 name: pci_express
> kobject: ffff8e19cb77ce18 name: spi
> kobject: ffff8e19cb77f818 name: i2c
> kobject: ffff8e19cb7c7a18 name: memory_tiering
> kobject: ffff8e1d8466ee18 name: acpi
> kobject: ffff8e1605d4e418 name: pnp
> kobject: ffff8e1605d4d018 name: xen
> kobject: ffff8e1605d4c418 name: dax
> kobject: ffff8e1605d4fc18 name: cxl
> kobject: ffff8e1605d4fa18 name: scsi
> kobject: ffff8e1605d4e218 name: mdio_bus
> kobject: ffff8e1605d4fe18 name: usb
> kobject: ffff8e1605d4c018 name: typec
> kobject: ffff8e1605d4f618 name: serio
> kobject: ffff8e1605e43018 name: edac
> kobject: ffff8e1605e41218 name: nvmem
> kobject: ffff8e16047d8a18 name: thunderbolt
> kobject: ffff8e160451e018 name: clocksource
> kobject: ffff8e160451da18 name: clockevents
> kobject: ffff8e160451f418 name: event_source
> kobject: ffff8e1d83e76018 name: usb-serial
> kobject: ffff8e1d86135418 name: hid
> kobject: ffff8e1611eea418 name: machinecheck
> kobject: ffff8e1d8d108618 name: wmi
> kobject: ffff8e160c187e18 name: mei
>
>
Thanks for the information.

Thanks.
Lianbo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/crash-utility/attachments/20230310/1e2bfafd/attachment.htm>


More information about the Crash-utility mailing list