Hi, Kazu
On Fri, Mar 10, 2023 at 11:22 AM lijiang <lijiang(a)redhat.com> wrote:
On Fri, Mar 10, 2023 at 10:38 AM HAGIO KAZUHITO(萩尾 一仁)
<k-hagio-ab(a)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(a)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
Applied:
https://github.com/crash-utility/crash/commit/489093c2183f4f0365d8957e727...
Thanks.
Lianbo
> + /* 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 +17927,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 +17943,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
>
>