Date: Wed, 8 Jan 2025 12:30:11 +1300
From: Tao Liu <ltao@redhat.com>
Subject: [Crash-utility] Re: [PATCH] Fix "net -a" option on Linux 6.13
and later kernels
To: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@nec.com>
Cc: "devel@lists.crash-utility.osci.io"
<devel@lists.crash-utility.osci.io>
Message-ID:
<CAO7dBbVYFpdtgMOvtnxp4MJJB_p4GyG=2_je7yMt33H40JmZZA@mail.gmail.com>
Content-Type: text/plain; charset="UTF-8"
Hi Kazu,
Thanks for the fix, the patch LGTM, so ack.
Applied:
Thanks
Lianbo
Thanks,
Tao Liu
On Tue, Jan 7, 2025 at 3:46 PM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@nec.com> wrote:
>
> From: Kazuhito Hagio <k-hagio-ab@nec.com>
>
> Kernel commit e4e3fd0a99d5 ("Merge branch 'improve-neigh_flush_dev-performance'")
> and its patch set, which are contained in Linux 6.13 and later kernels,
> removed neigh_hash_table.hash_buckets and neighbour.next members, and
> introduced neigh_hash_table.hash_heads and neighbour.hash members
> instead with the hlist implementation.
>
> Without the patch, the "net -a" option fails with the following error:
>
> crash> net -a
>
> net: invalid structure member offset: neigh_table_hash_buckets
> FILE: net.c LINE: 701 FUNCTION: dump_arp()
> ...
>
> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
> ---
> defs.h | 2 ++
> net.c | 26 +++++++++++++++++++++-----
> symbols.c | 2 ++
> 3 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/defs.h b/defs.h
> index d8d378ef94b1..8378cbab2f73 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2269,6 +2269,8 @@ struct offset_table { /* stash of commonly-used offsets */
> long task_struct_thread_context_x26;
> long task_struct_thread_context_x27;
> long task_struct_thread_context_x28;
> + long neigh_table_hash_heads;
> + long neighbour_hash;
> };
>
> struct size_table { /* stash of commonly-used sizes */
> diff --git a/net.c b/net.c
> index 31d3f2bf7c2f..4e14f19fc097 100644
> --- a/net.c
> +++ b/net.c
> @@ -169,6 +169,11 @@ net_init(void)
> "neigh_hash_table", "hash_shift");
> MEMBER_OFFSET_INIT(neigh_table_hash_buckets,
> "neigh_hash_table", "hash_buckets");
> + /* Linux 6.13 and later */
> + if (INVALID_MEMBER(neigh_table_hash_buckets)) {
> + MEMBER_OFFSET_INIT(neigh_table_hash_heads, "neigh_hash_table", "hash_heads");
> + MEMBER_OFFSET_INIT(neighbour_hash, "neighbour", "hash");
> + }
> } else {
> MEMBER_OFFSET_INIT(neigh_table_hash_buckets,
> "neigh_table", "hash_buckets");
> @@ -698,9 +703,13 @@ dump_arp(void)
> "neigh_table key_len", FAULT_ON_ERROR);
>
> if (VALID_MEMBER(neigh_table_nht_ptr)) {
> - readmem(nht + OFFSET(neigh_table_hash_buckets),
> - KVADDR, &hash, sizeof(hash),
> - "neigh_hash_table hash_buckets ptr", FAULT_ON_ERROR);
> + /* Linux 6.13 and later */
> + if (VALID_MEMBER(neigh_table_hash_heads))
> + readmem(nht + OFFSET(neigh_table_hash_heads), KVADDR, &hash,
> + sizeof(hash), "neigh_hash_table hash_heads ptr", FAULT_ON_ERROR);
> + else
> + readmem(nht + OFFSET(neigh_table_hash_buckets), KVADDR, &hash,
> + sizeof(hash), "neigh_hash_table hash_buckets ptr", FAULT_ON_ERROR);
>
> readmem(hash, KVADDR, hash_buckets, hash_bytes,
> "neigh_hash_table hash_buckets", FAULT_ON_ERROR);
> @@ -831,8 +840,15 @@ print_neighbour_q(ulong addr, int key_len)
>
> arp_state_to_flags(state);
>
> - readmem(addr + OFFSET(neighbour_next), KVADDR,
> - &addr, sizeof(addr), "neighbour next", FAULT_ON_ERROR);
> + /* Linux 6.13 and later kernels use hlist. */
> + if (VALID_MEMBER(neighbour_hash)) {
> + readmem(addr + OFFSET(neighbour_hash), KVADDR, &addr,
> + sizeof(addr), "neighbour hash", FAULT_ON_ERROR);
> + if (addr)
> + addr -= OFFSET(neighbour_hash);
> + } else
> + readmem(addr + OFFSET(neighbour_next), KVADDR, &addr,
> + sizeof(addr), "neighbour next", FAULT_ON_ERROR);
> }
>
> FREEBUF(ha_buf);
> diff --git a/symbols.c b/symbols.c
> index a3cd0f3f6e1f..0b63e11fa567 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -11028,6 +11028,7 @@ dump_offset_table(char *spec, ulong makestruct)
>
> fprintf(fp, " neighbour_next: %ld\n",
> OFFSET(neighbour_next));
> + fprintf(fp, " neighbour_hash: %ld\n", OFFSET(neighbour_hash));
> fprintf(fp, " neighbour_primary_key: %ld\n",
> OFFSET(neighbour_primary_key));
> fprintf(fp, " neighbour_ha: %ld\n",
> @@ -11038,6 +11039,7 @@ dump_offset_table(char *spec, ulong makestruct)
> OFFSET(neighbour_nud_state));
> fprintf(fp, " neigh_table_hash_buckets: %ld\n",
> OFFSET(neigh_table_hash_buckets));
> + fprintf(fp, " neigh_table_hash_heads: %ld\n", OFFSET(neigh_table_hash_heads));
> fprintf(fp, " neigh_table_hash_mask: %ld\n",
> OFFSET(neigh_table_hash_mask));
> fprintf(fp, " neigh_table_hash_shift: %ld\n",
> --
> 2.31.1