161 lines
5.4 KiB
Diff
161 lines
5.4 KiB
Diff
From b29bd2b531502ca0274ad9c4531417920102fb26 Mon Sep 17 00:00:00 2001
|
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
|
Date: Fri, 10 Mar 2023 02:38:26 +0000
|
|
Subject: [PATCH 81/89] Fix "kmem -n" option to display memory blocks on Linux
|
|
6.3-rc1 and later
|
|
|
|
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>
|
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.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 6cfc21487497..9091397a7012 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")) {
|
|
+ /* 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 158c95459bec..1d083b876f87 100644
|
|
--- a/symbols.c
|
|
+++ b/symbols.c
|
|
@@ -10416,6 +10416,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",
|
|
@@ -10453,6 +10454,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.37.1
|
|
|