[Crash-utility] [PATCH] Fix "net -a" option on Linux 6.13 and later kernels

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Kazuhito Hagio <k-hagio-ab@xxxxxxx>

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@xxxxxxx>
---
 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
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux