From: Alexander Bluhm Subject: ddb mbuf chains To: tech@openbsd.org Date: Wed, 28 Aug 2024 22:43:16 +0200 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_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