Hi Harshvardhan, On Sun, Aug 16, 2026 at 03: 31: 07AM -0700,
Harshvardhan Jha
wrote: > Linux commit 5ba6bc27b1f9 ("slab: decouple pointer to barn from >
kmem_cache_node") moved the kmem_cache_node pointers from > kmem_cache. node[]
to
Hi Harshvardhan,
On Sun, Aug 16, 2026 at 03:31:07AM -0700, Harshvardhan Jha 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.
can you add some exact test steps?
>
> 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;
> 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);
> +
> + 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!
NV9i9INIATy1K2P36mNGArgHkfzy7iJd3jxNvj0tcvF-54fYyimeB1fA84a86N1JuctGmVmin1YxVbHQvbmkZtHI7O5uqzUI4w$
<
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!
NV9i9INIATy1K2P36mNGArgHkfzy7iJd3jxNvj0tcvF-54fYyimeB1fA84a86N1JuctGmVmin1YxVbHQvbmkZtHI7O4vB18Kaw$
<
https://urldefense.com/v3/__https://github.com/crash-utility/crash/wiki__...
I have applied a few patches which passed review. Can you rebase your
patches, resend, and try to get some review from active reviewers?
The issue which
this patch was trying to fix has already been fixed with
SHA bb9a3fa I guess we can ignore this now.
Thanks,
Harshvardhan>