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@nec.com>
---
 defs.h    |  2 ++
 memory.c  | 63 +++++++++++++++++++++++++++++++++++++++++++++++++------
 symbols.c |  2 ++
 3 files changed, 61 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..592a5ef49d50 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,60 @@ 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[32];
+               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", FAULT_ON_ERROR);
+                       read_string(name, buf, sizeof(buf)-1);
+                       if (CRASHDEBUG(1))
+                               fprintf(fp, "kobject: %lx name: %s\n", ld->list_ptr[i], buf);
+                       if (STREQ(buf, "memory")) {
Thank you for the update, Kazu.
For the v2: Ack