In ddb(4) print mbuf chain and packet list.
authorbluhm <bluhm@openbsd.org>
Thu, 5 Sep 2024 08:52:27 +0000 (08:52 +0000)
committerbluhm <bluhm@openbsd.org>
Thu, 5 Sep 2024 08:52:27 +0000 (08:52 +0000)
For debugging hardware offloading, DMA requirements, bounce buffers,
and performance optimizations, knowing the memory layout of mbuf
content helps.
Implement /c and /p modifiers in ddb show mbuf.  It traverses the
pointer m_next for mbuf chain or m_nextpkt for packet list.  Show
mbuf type, data offset, mbuf length, packet length, cluster size,
and total number of elements, length and size.

OK claudio@ mvs@

share/man/man4/ddb.4
sys/ddb/db_command.c
sys/ddb/db_interface.h
sys/kern/uipc_mbuf.c

index 6904051..6ca75c4 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ddb.4,v 1.107 2024/02/05 21:33:00 jmc Exp $
+.\"    $OpenBSD: ddb.4,v 1.108 2024/09/05 08:52:27 bluhm Exp $
 .\"    $NetBSD: ddb.4,v 1.5 1994/11/30 16:22:09 jtc Exp $
 .\"
 .\" Mach Operating System
@@ -25,7 +25,7 @@
 .\" any improvements or extensions that they make and grant Carnegie Mellon
 .\" the rights to redistribute these changes.
 .\"
-.Dd $Mdocdate: February 5 2024 $
+.Dd $Mdocdate: September 5 2024 $
 .Dt DDB 4
 .Os
 .Sh NAME
@@ -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
index 562053d..1e129c2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_command.c,v 1.101 2024/05/13 01:15:50 jsg Exp $    */
+/*     $OpenBSD: db_command.c,v 1.102 2024/09/05 08:52:27 bluhm Exp $  */
 /*     $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */
 
 /*
@@ -340,7 +340,15 @@ db_malloc_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
 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 cccec9e..bdde7ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: db_interface.h,v 1.27 2024/02/03 18:51:58 beck Exp $  */
+/*     $OpenBSD: db_interface.h,v 1.28 2024/09/05 08:52:27 bluhm Exp $ */
 /*     $NetBSD: db_interface.h,v 1.1 1996/02/05 01:57:03 christos Exp $        */
 
 /*
@@ -61,6 +61,8 @@ void db_show_all_pools(db_expr_t, int, db_expr_t, char *);
 
 /* 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 db942bf..a0c0ebc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_mbuf.c,v 1.291 2024/08/29 10:44:40 bluhm Exp $   */
+/*     $OpenBSD: uipc_mbuf.c,v 1.292 2024/09/05 08:52:27 bluhm Exp $   */
 /*     $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $   */
 
 /*
@@ -1533,6 +1533,80 @@ m_print(void *v,
 
        }
 }
+
+const char *m_types[MT_NTYPES] = {
+       "fre",
+       "dat",
+       "hdr",
+       "nam",
+       "opt",
+       "ftb",
+       "ctl",
+       "oob",
+};
+
+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) {
+               const char *type;
+
+               chain++;
+               len += m->m_len;
+               size += M_SIZE(m);
+               type = (m->m_type >= 0 && m->m_type < MT_NTYPES) ?
+                   m_types[m->m_type] : "???";
+               (*pr)("%s mbuf %p, %s, off %zd, len %u", indent, m, type,
+                   m->m_data - M_DATABUF(m), 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);
+               (*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;
+                       size += M_SIZE(n);
+               }
+               (*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
 
 /*