From: Kazuhito Hagio <k-hagio-ab(a)nec.com>
Kernel commit 5ba6bc27b1f9 ("slab: decouple pointer to barn from
kmem_cache_node") changed kmem_cache.node array into struct
kmem_cache_per_node_ptrs kmem_cache.per_node array.
Without the patch, "kmem <slab address>" and "kmem -s" option
fail with
the following error.
crash> kmem -s
kmem: invalid structure member offset: kmem_cache_local_node
FILE: memory.c LINE: 19563 FUNCTION: get_kmem_cache_slub_data()
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
This patch needs to be applied on the top of the patch [1], so 2/2.
[1] [PATCH] Fix compound_head() and "bt -F" option on Linux 7.1 and later
https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg02256.html
defs.h | 3 +++
memory.c | 19 +++++++++++++++----
symbols.c | 4 ++++
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index 88b7bbeb2372..ef34db90113f 100644
--- a/defs.h
+++ b/defs.h
@@ -2296,6 +2296,8 @@ struct offset_table { /* stash of commonly-used
offsets */
long folio__folio_order;
long folio__flags_1;
long page_compound_info;
+ long kmem_cache_per_node;
+ long kmem_cache_per_node_ptrs_node;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2478,6 +2480,7 @@ struct size_table { /* stash of commonly-used sizes */
long page_compound_order;
long folio__folio_order;
long folio__flags_1;
+ long kmem_cache_per_node_ptrs;
};
struct array_table {
diff --git a/memory.c b/memory.c
index 7102e951f1d5..7c3ab506217a 100644
--- a/memory.c
+++ b/memory.c
@@ -871,6 +871,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(kmem_cache_inuse, "kmem_cache", "inuse");
MEMBER_OFFSET_INIT(kmem_cache_align, "kmem_cache", "align");
MEMBER_OFFSET_INIT(kmem_cache_node, "kmem_cache", "node");
+ if (INVALID_MEMBER(kmem_cache_node))
+ MEMBER_OFFSET_INIT(kmem_cache_per_node, "kmem_cache",
"per_node");
MEMBER_OFFSET_INIT(kmem_cache_cpu_slab, "kmem_cache", "cpu_slab");
MEMBER_OFFSET_INIT(kmem_cache_list, "kmem_cache", "list");
MEMBER_OFFSET_INIT(kmem_cache_red_left_pad, "kmem_cache",
"red_left_pad");
@@ -922,7 +924,12 @@ vm_init(void)
if (INVALID_MEMBER(page_objects))
ANON_MEMBER_OFFSET_INIT(page_objects, "slab", "objects");
}
- if (VALID_MEMBER(kmem_cache_node)) {
+ if (VALID_MEMBER(kmem_cache_per_node)) { /* Linux 7.1 and later */
+ MEMBER_OFFSET_INIT(kmem_cache_per_node_ptrs_node,
+ "kmem_cache_per_node_ptrs", "node");
+ STRUCT_SIZE_INIT(kmem_cache_per_node_ptrs, "kmem_cache_per_node_ptrs");
+ vt->flags |= CONFIG_NUMA;
+ } else if (VALID_MEMBER(kmem_cache_node)) {
ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.node", NULL, 0);
vt->flags |= CONFIG_NUMA;
}
@@ -19555,9 +19562,13 @@ get_kmem_cache_slub_data(long cmd, struct meminfo *si)
for (n = 0; n < vt->numnodes; n++) {
if (vt->flags & CONFIG_NUMA) {
nt = &vt->node_table[n];
- node_ptr = ULONG(si->cache_buf +
- OFFSET(kmem_cache_node) +
- (sizeof(void *) * nt->node_id));
+ if (VALID_MEMBER(kmem_cache_per_node)) /* Linux 7.1 and later */
+ node_ptr = ULONG(si->cache_buf + OFFSET(kmem_cache_per_node) +
+ (SIZE(kmem_cache_per_node_ptrs) * nt->node_id) +
+ OFFSET(kmem_cache_per_node_ptrs_node));
+ else
+ node_ptr = ULONG(si->cache_buf + OFFSET(kmem_cache_node) +
+ (sizeof(void *) * nt->node_id));
} else
node_ptr = si->cache +
OFFSET(kmem_cache_local_node);
diff --git a/symbols.c b/symbols.c
index 2071bdf77819..ae7fa7b416a4 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10932,6 +10932,9 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(kmem_cache_oo));
fprintf(fp, " kmem_cache_random: %ld\n",
OFFSET(kmem_cache_random));
+ fprintf(fp, " kmem_cache_per_node: %ld\n",
OFFSET(kmem_cache_per_node));
+
+ fprintf(fp, " kmem_cache_per_node_ptrs_node: %ld\n",
OFFSET(kmem_cache_per_node_ptrs_node));
fprintf(fp, " kmem_cache_node_nr_partial: %ld\n",
OFFSET(kmem_cache_node_nr_partial));
@@ -12043,6 +12046,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " kmem_cache: %ld\n",
SIZE(kmem_cache));
fprintf(fp, " kmem_cache_node: %ld\n",
SIZE(kmem_cache_node));
fprintf(fp, " kmem_cache_cpu: %ld\n",
SIZE(kmem_cache_cpu));
+ fprintf(fp, " kmem_cache_per_node_ptrs: %ld\n",
SIZE(kmem_cache_per_node_ptrs));
fprintf(fp, " swap_info_struct: %ld\n",
SIZE(swap_info_struct));
--
2.31.1