Thank you for the fix, Kazu. On Thu, Mar 9, 2023 at 9:44 AM HAGIO KAZUHITO(萩尾 一仁) <k-hagio...@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...@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", > 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? + 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. Other changes look good to me. Thanks. Lianbo > + if (STREQ(buf, "memory")) { > + /* entry is subsys_private.subsys.kobj. > See bus_to_subsys(). */ > + private = ld->list_ptr[i] - > OFFSET(kset_kobj) > + - > OFFSET(subsys_private_subsys); > + break; > + } > + } > + FREEBUF(ld->list_ptr); > + } else { > + ulong memory_subsys = symbol_value("memory_subsys"); > + readmem(memory_subsys + OFFSET(bus_type_p), KVADDR, > &private, > + sizeof(void *), "memory_subsys.private", > FAULT_ON_ERROR); > + } > + > + if (!private) > + error(FATAL, "cannot determine subsys_private for > memory.\n"); > + > klist = private + OFFSET(subsys_private_klist_devices) + > OFFSET(klist_k_list); > BZERO(ld, sizeof(struct list_data)); > @@ -17875,7 +17928,6 @@ dump_memory_blocks(int initialize) > ulong memory_block, device; > ulong *klistbuf; > int klistcnt, i; > - struct list_data list_data; > char mb_hdr[BUFSIZE]; > char paddr_hdr[BUFSIZE]; > char buf1[BUFSIZE]; > @@ -17892,7 +17944,7 @@ dump_memory_blocks(int initialize) > if (initialize) > return; > > - init_memory_block(&list_data, &klistcnt, &klistbuf); > + init_memory_block(&klistcnt, &klistbuf); > > if ((symbol_exists("memory_block_size_probed")) || > (MEMBER_EXISTS("memory_block", "end_section_nr"))) > diff --git a/symbols.c b/symbols.c > index 28846d06273c..f0721023816d 100644 > --- a/symbols.c > +++ b/symbols.c > @@ -10404,6 +10404,7 @@ dump_offset_table(char *spec, ulong makestruct) > OFFSET(kobject_entry)); > fprintf(fp, " kset_list: %ld\n", > OFFSET(kset_list)); > + fprintf(fp, " kset_kobj: %ld\n", > OFFSET(kset_kobj)); > fprintf(fp, " request_list_count: %ld\n", > OFFSET(request_list_count)); > fprintf(fp, " request_cmd_flags: %ld\n", > @@ -10441,6 +10442,7 @@ dump_offset_table(char *spec, ulong makestruct) > fprintf(fp, " blk_mq_tags_rqs: %ld\n", > OFFSET(blk_mq_tags_rqs)); > > + fprintf(fp, " subsys_private_subsys: %ld\n", > OFFSET(subsys_private_subsys)); > fprintf(fp, " subsys_private_klist_devices: %ld\n", > OFFSET(subsys_private_klist_devices)); > fprintf(fp, " subsystem_kset: %ld\n", > -- > 2.31.1 > >
-- Crash-utility mailing list Crash-utility@redhat.com https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki