Hi Harshvardhan, On Mon, Aug 17, 2026 at 12: 02 AM Harshvardhan Jha
<harshvardhan. j. jha(a) oracle. com> wrote: > > Linux commit 5ba6bc27b1f9
("slab: decouple pointer to barn from > kmem_cache_node") moved the
kmem_cache_node pointers
Hi Harshvardhan,
On Mon, Aug 17, 2026 at 12:02 AM Harshvardhan Jha
<harshvardhan.j.jha(a)oracle.com> wrote:
>
> Linux commit 5ba6bc27b1f9 ("slab: decouple pointer to barn from
> kmem_cache_node") moved the kmem_cache_node pointers from
> kmem_cache.node[] to kmem_cache.per_node[].node.
>
> Teach the SLUB traversal code to recognize and handle both layouts.
> Without this, crash treats the new layout as non-NUMA and kmem -s fails
> while looking for the removed kmem_cache.local_node member.
>
> Signed-off-by: Harshvardhan Jha <harshvardhan.j.jha(a)oracle.com>
> ---
> Testing was performed manually on x86_64 VMs:
>
> - Linux 7.1.0-rc7 with the new per_node layout: upstream crash failed
> with the kmem_cache_local_node invalid-offset error, while the patched
> crash completed kmem -s and displayed the slab-cache table.
> - Linux 6.18.0-rc7 with the old node[1024] layout: the patched crash
> completed kmem -s and displayed the slab-cache table.
>
> defs.h | 3 +++
> memory.c | 39 ++++++++++++++++++++++++++++++---------
> symbols.c | 6 ++++++
> 3 files changed, 39 insertions(+), 9 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index e3027e2..ccd84a0 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -1766,6 +1766,8 @@ struct offset_table { /* stash of
commonly-used offsets */
> long kmem_cache_name;
> long kmem_cache_list;
> long kmem_cache_node;
> + long kmem_cache_per_node;
> + long kmem_cache_per_node_node;
> long kmem_cache_cpu_slab;
> long page_inuse;
> /* long page_offset; use "old" page->offset */
> @@ -2395,6 +2397,7 @@ struct size_table { /* stash of commonly-used sizes */
> long rlimit;
> long kmem_cache;
> long kmem_cache_node;
> + long kmem_cache_per_node_ptrs;
The offset_table & size_table, any new added members should be
appended at the end of the struct, not in the middle. Please check
https://urldefense.com/v3/__https://github.com/crash-utility/crash/
wiki*writing-patches__;Iw!!ACWV5N9M2RV99hQ!
O1Hf-3Yy5Z2kcbB75VvSaoFma69uN3QLn5J1UKeIbTvRAvowZJrHLu3BkU7jc4hhXGWmI3MhLcfPYQC29tY$
<
https://urldefense.com/v3/__https://github.com/crash-utility/crash/wiki*w...
> long upid;
> long kmem_cache_cpu;
> long cfs_rq;
> diff --git a/memory.c b/memory.c
> index 3f3aa27..cf26bd4 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -306,6 +306,7 @@ static int get_kmem_cache_list(ulong **);
> static int get_kmem_cache_root_list(ulong **);
> static int get_kmem_cache_child_list(ulong **, ulong);
> static int get_kmem_cache_slub_data(long, struct meminfo *);
> +static ulong get_kmem_cache_node_ptr(struct meminfo *, int);
> static ulong compound_head(ulong);
> static long count_partial(ulong, struct meminfo *, ulong *);
> static short count_cpu_partial(struct meminfo *, int);
> @@ -869,6 +870,9 @@ 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");
> + MEMBER_OFFSET_INIT(kmem_cache_per_node, "kmem_cache",
"per_node");
> + MEMBER_OFFSET_INIT(kmem_cache_per_node_node,
> + "kmem_cache_per_node_ptrs", "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");
> @@ -920,9 +924,16 @@ vm_init(void)
> if (INVALID_MEMBER(page_objects))
> ANON_MEMBER_OFFSET_INIT(page_objects,
"slab", "objects");
> }
> + STRUCT_SIZE_INIT(kmem_cache_per_node_ptrs,
> + "kmem_cache_per_node_ptrs");
> if (VALID_MEMBER(kmem_cache_node)) {
> ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.node",
NULL, 0);
> vt->flags |= CONFIG_NUMA;
> + } else if (VALID_MEMBER(kmem_cache_per_node) &&
> + VALID_MEMBER(kmem_cache_per_node_node) &&
> + VALID_SIZE(kmem_cache_per_node_ptrs)) {
> + ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.per_node",
NULL, 0);
> + vt->flags |= CONFIG_NUMA;
> }
> ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.cpu_slab", NULL,
0);
>
> @@ -19460,6 +19471,22 @@ count_cpu_partial(struct meminfo *si, int cpu)
> return free_objects;
> }
>
> +static ulong
> +get_kmem_cache_node_ptr(struct meminfo *si, int node)
> +{
> + char *node_addr;
> +
> + if (VALID_MEMBER(kmem_cache_node))
> + node_addr = si->cache_buf + OFFSET(kmem_cache_node) +
> + (sizeof(void *) * node);
> + else
> + node_addr = si->cache_buf + OFFSET(kmem_cache_per_node) +
> + (SIZE(kmem_cache_per_node_ptrs) * node) +
> + OFFSET(kmem_cache_per_node_node);
I suggest making the old approach the default (else) branch and the
new approach the if (condition) branch:
if (VALID_MEMBER(kmem_cache_per_node) &&
VALID_MEMBER(kmem_cache_per_node_node)) {
node_addr = si->cache_buf + OFFSET(kmem_cache_per_node) +
(SIZE(kmem_cache_per_node_ptrs) * node) +
OFFSET(kmem_cache_per_node_node);
} else {
node_addr = si->cache_buf + OFFSET(kmem_cache_node) +
(sizeof(void *) * node);
}
Since we have used the old branch for a longer time, I'd prefer
anything that doesn't match the new condition to fall into the old
one.
Thanks,
Tao Liu
The issue my patch was trying to fix is already fixed by bb9a3fa. So I
guess we can ignore this now.
Thanks,
Harshvardhan>> +
> + return ULONG(node_addr);
> +}
> +
> /*
> * Emulate the total count calculation done by the
> * slab_objects() sysfs function in slub.c.
> @@ -19537,9 +19564,7 @@ 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));
> + node_ptr = get_kmem_cache_node_ptr(si, nt->node_id);
> } else
> node_ptr = si->cache +
> OFFSET(kmem_cache_local_node);
> @@ -19709,9 +19734,7 @@ do_kmem_cache_slub(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));
> + node_ptr = get_kmem_cache_node_ptr(si, nt->node_id);
> } else
> node_ptr = si->cache +
> OFFSET(kmem_cache_local_node);
> @@ -20515,9 +20538,7 @@ slab_to_kmem_cache_node(struct meminfo *si, ulong slab_page)
>
> if (vt->flags & CONFIG_NUMA) {
> node = page_to_nid(slab_page);
> - node_ptr = ULONG(si->cache_buf +
> - OFFSET(kmem_cache_node) +
> - (sizeof(void *)*node));
> + node_ptr = get_kmem_cache_node_ptr(si, node);
> } else
> node_ptr = si->cache + OFFSET(kmem_cache_local_node);
>
> diff --git a/symbols.c b/symbols.c
> index a7ccdb1..652fce4 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -10922,6 +10922,10 @@ dump_offset_table(char *spec, ulong makestruct)
> OFFSET(kmem_cache_red_left_pad));
> fprintf(fp, " kmem_cache_node: %ld\n",
> OFFSET(kmem_cache_node));
> + fprintf(fp, " kmem_cache_per_node: %ld\n",
> + OFFSET(kmem_cache_per_node));
> + fprintf(fp, " kmem_cache_per_node_node: %ld\n",
> + OFFSET(kmem_cache_per_node_node));
> fprintf(fp, " kmem_cache_cpu_slab: %ld\n",
> OFFSET(kmem_cache_cpu_slab));
> fprintf(fp, " kmem_cache_cpu_partial: %ld\n",
> @@ -12042,6 +12046,8 @@ dump_offset_table(char *spec, ulong makestruct)
> SIZE(kmem_bufctl_t));
> fprintf(fp, " kmem_cache: %ld\n",
SIZE(kmem_cache));
> fprintf(fp, " kmem_cache_node: %ld\n",
SIZE(kmem_cache_node));
> + fprintf(fp, " kmem_cache_per_node_ptrs: %ld\n",
> + SIZE(kmem_cache_per_node_ptrs));
> fprintf(fp, " kmem_cache_cpu: %ld\n",
SIZE(kmem_cache_cpu));
>
> fprintf(fp, " swap_info_struct: %ld\n",
> --
> 2.52.0
> --
> Crash-utility mailing list -- devel(a)lists.crash-utility.osci.io
> To unsubscribe send an email to devel-leave(a)lists.crash-utility.osci.io
>
https://urldefense.com/v3/__https://$*7Bdomain_name*7D/admin/lists/
devel.lists.crash-utility.osci.io/__;JSU!!ACWV5N9M2RV99hQ!
O1Hf-3Yy5Z2kcbB75VvSaoFma69uN3QLn5J1UKeIbTvRAvowZJrHLu3BkU7jc4hhXGWmI3MhLcfPyzDp8kQ$
<
https://urldefense.com/v3/__https://$*7Bdomain_name*7D/admin/lists/devel....
> Contribution Guidelines:
https://urldefense.com/v3/__https://github.com/crash-utility/crash/
wiki__;!!ACWV5N9M2RV99hQ!
O1Hf-3Yy5Z2kcbB75VvSaoFma69uN3QLn5J1UKeIbTvRAvowZJrHLu3BkU7jc4hhXGWmI3MhLcfPiU2f23U$
<
https://urldefense.com/v3/__https://github.com/crash-utility/crash/wiki__...
>