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