Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
ddb mbuf chains
To:
tech@openbsd.org
Date:
Wed, 28 Aug 2024 22:43:16 +0200

Download raw body.

Thread
Hi,

I want to print the layout of mbuf chains in ddb.  For debugging
hardware offloading, DMA requirements and bounce buffers, I need
to know the layout of the mbuf chain by m_next and m_nextpkt pointer.
So I implemented /c and /p modifiers for ddb show mbuf.

ddb> show mbuf /c 0xfffffd8006fd5100
-+- mbuf 0xfffffd8006fd5100, len 10136, pktlen 17376, clsize 65536
 +- mbuf 0xfffffd807df8f800, len 7240, pktlen 7240, clsize 8192
 +- mbuf 0xfffffd8006fd5d00, len 2896, pktlen 2896, clsize 4096
 \- total chain 3, len 20272, size 77824

ddb> show mbuf /pc 0xfffffd8006fd5100
++- mbuf 0xfffffd8006fd5100, len 10136, pktlen 17376, clsize 65536
|+- mbuf 0xfffffd807df8f800, len 7240, pktlen 7240, clsize 8192
|+- mbuf 0xfffffd8006fd5d00, len 2896, pktlen 2896, clsize 4096
|\- total chain 3, len 20272, size 77824
\-- total packets 1

ddb> show mbuf /p 0xfffffd8006fd5100
+-- mbuf 0xfffffd8006fd5100, chain 3, pktlen 17376, len 20272, size 77824
\-- total packets 1

ddb> show mbuf 0xfffffd8006fd5100
mbuf 0xfffffd8006fd5100
m_type: 1       m_flags: b<M_EXT,M_PKTHDR,M_EXTWR>
m_next: 0xfffffd807df8f800      m_nextpkt: 0x0
m_data: 0xfffffd8006d69c48      m_len: 10136
m_dat: 0xfffffd8006fd5120       m_pktdat: 0xfffffd8006fd5170
m_ptkhdr.ph_ifidx: 0    m_pkthdr.len: 17376
m_ptkhdr.ph_tags: 0x0   m_pkthdr.ph_tagsset: 0
m_pkthdr.ph_flowid: 0   m_pkthdr.ph_loopcnt: 0
m_pkthdr.csum_flags: 0
m_pkthdr.ether_vtag: 0  m_ptkhdr.ph_rtableid: 0
m_pkthdr.pf.statekey: 0x0       m_pkthdr.pf.inp 0x0
m_pkthdr.pf.qid: 0      m_pkthdr.pf.tag: 0
m_pkthdr.pf.flags: 0
m_pkthdr.pf.routed: 0   m_pkthdr.pf.prio: 3
m_ext.ext_buf: 0xfffffd8006d68000       m_ext.ext_size: 65536
m_ext.ext_free_fn: 0    m_ext.ext_arg: 0xffffffff828b2148
m_ext.ext_nextref: 0xfffffd8006fd5100   m_ext.ext_prevref: 0xfffffd8006fd5100

ok?

bluhm

Index: sys/ddb/db_command.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/ddb/db_command.c,v
diff -u -p -r1.101 db_command.c
--- sys/ddb/db_command.c	13 May 2024 01:15:50 -0000	1.101
+++ sys/ddb/db_command.c	28 Aug 2024 19:47:43 -0000
@@ -340,7 +340,15 @@ db_malloc_print_cmd(db_expr_t addr, int 
 void
 db_mbuf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
 {
-	m_print((void *)addr, db_printf);
+	if ((modif[0] == 'c' && modif[1] == 'p') ||
+	    (modif[0] == 'p' && modif[1] == 'c'))
+		m_print_packet((void *)addr, 1, db_printf);
+	else if (modif[0] == 'c')
+		m_print_chain((void *)addr, 0, db_printf);
+	else if (modif[0] == 'p')
+		m_print_packet((void *)addr, 0, db_printf);
+	else
+		m_print((void *)addr, db_printf);
 }
 
 void
Index: sys/ddb/db_interface.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/ddb/db_interface.h,v
diff -u -p -r1.27 db_interface.h
--- sys/ddb/db_interface.h	3 Feb 2024 18:51:58 -0000	1.27
+++ sys/ddb/db_interface.h	28 Aug 2024 19:44:28 -0000
@@ -61,6 +61,8 @@ void db_show_all_pools(db_expr_t, int, d
 
 /* kern/uipc_mbuf.c */
 void m_print(void *, int (*)(const char *, ...));
+void m_print_chain(void *, int, int (*)(const char *, ...));
+void m_print_packet(void *, int, int (*)(const char *, ...));
 
 /* kern/uipc_socket.c */
 void so_print(void *, int (*)(const char *, ...));
Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/kern/uipc_mbuf.c,v
diff -u -p -r1.290 uipc_mbuf.c
--- sys/kern/uipc_mbuf.c	5 Mar 2024 18:52:41 -0000	1.290
+++ sys/kern/uipc_mbuf.c	28 Aug 2024 20:27:48 -0000
@@ -1542,6 +1542,73 @@ m_print(void *v,
 
 	}
 }
+
+void
+m_print_chain(void *v, int deep,
+    int (*pr)(const char *, ...) __attribute__((__format__(__kprintf__,1,2))))
+{
+	struct mbuf *m;
+	const char *indent = deep ? "++-" : "-+-";
+	size_t chain = 0, len = 0, size = 0;
+
+	for (m = v; m != NULL; m = m->m_next) {
+		chain++;
+		(*pr)("%s mbuf %p, len %u", indent, m, m->m_len);
+		len += m->m_len;
+		if (m->m_flags & M_PKTHDR)
+			(*pr)(", pktlen %d", m->m_pkthdr.len);
+		if (m->m_flags & M_EXT) {
+			(*pr)(", clsize %u", m->m_ext.ext_size);
+			size += m->m_ext.ext_size;
+		} else if (m->m_flags & M_PKTHDR)
+			size += MHLEN;
+		else
+			size += MLEN;
+		(*pr)("\n");
+		indent = deep ? "|+-" : " +-";
+	}
+	indent = deep ? "|\\-" : " \\-";
+	if (v != NULL) {
+		(*pr)("%s total chain %zu, len %zu, size %zu\n",
+		    indent, chain, len, size);
+	}
+}
+
+void
+m_print_packet(void *v, int deep,
+    int (*pr)(const char *, ...) __attribute__((__format__(__kprintf__,1,2))))
+{
+	struct mbuf *m, *n;
+	const char *indent = "+--";
+	size_t pkts = 0;
+
+	for (m = v; m != NULL; m = m->m_nextpkt) {
+		size_t chain = 0, len = 0, size = 0;
+
+		pkts++;
+		if (deep) {
+			m_print_chain(m, deep, pr);
+			continue;
+		}
+		for (n = m; n != NULL; n = n->m_next) {
+			chain++;
+			len += n->m_len;
+			if (n->m_flags & M_EXT)
+				size += n->m_ext.ext_size;
+			else if (n->m_flags & M_PKTHDR)
+				size += MHLEN;
+			else
+				size += MLEN;
+		}
+		(*pr)("%s mbuf %p, chain %zu", indent, m, chain);
+		if (m->m_flags & M_PKTHDR)
+			(*pr)(", pktlen %d", m->m_pkthdr.len);
+		(*pr)(", len %zu, size %zu\n", len, size);
+	}
+	indent = "\\--";
+	if (v != NULL)
+		(*pr)("%s total packets %zu\n", indent, pkts);
+}
 #endif
 
 /*
Index: share/man/man4/ddb.4
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/share/man/man4/ddb.4,v
diff -u -p -r1.107 ddb.4
--- share/man/man4/ddb.4	5 Feb 2024 21:33:00 -0000	1.107
+++ share/man/man4/ddb.4	28 Aug 2024 19:51:26 -0000
@@ -658,7 +658,11 @@ If the
 .Cm /f
 modifier is specified, the complete map is printed.
 .\" --------------------
-.It Ic show mbuf Ar addr
+.It Xo
+.Ic show mbuf
+.Op Cm /cp
+.Ar addr
+.Xc
 Prints the
 .Vt struct mbuf
 header at
@@ -668,6 +672,13 @@ Depending on the mbuf flags
 and
 .Vt struct m_ext
 are printed as well.
+If the
+.Cm /c
+modifier is specified, print the mbuf chain linked with the m_next
+pointer.
+.Cm /p
+does the same using m_nextpkt.
+Both can be combined.
 .\" --------------------
 .It Xo
 .Ic show mount