diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -1591,6 +1591,25 @@ mb = m_free(mb); } +/* + * Free an entire chain of mbufs and associated external buffers, following + * both m_next and m_nextpkt linkage. + * Note: doesn't support NULL argument. + */ +void +m_freemp(struct mbuf *m) +{ + struct mbuf *n; + + MBUF_PROBE1(m__freemp, m); + do { + n = m->m_nextpkt; + while (m != NULL) + m = m_free(m); + m = n; + } while (m != NULL); +} + /* * Temporary primitive to allow freeing without going through m_free. */ diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -111,6 +111,9 @@ SDT_PROBE_DEFINE1_XLATE(sdt, , , m__freem, "struct mbuf *", "mbufinfo_t *"); +SDT_PROBE_DEFINE1_XLATE(sdt, , , m__freemp, + "struct mbuf *", "mbufinfo_t *"); + #include /* diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -65,6 +65,7 @@ SDT_PROBE_DECLARE(sdt, , , m__cljset); SDT_PROBE_DECLARE(sdt, , , m__free); SDT_PROBE_DECLARE(sdt, , , m__freem); +SDT_PROBE_DECLARE(sdt, , , m__freemp); #endif /* _KERNEL */ @@ -843,6 +844,7 @@ u_int m_fixhdr(struct mbuf *); struct mbuf *m_fragment(struct mbuf *, int, int); void m_freem(struct mbuf *); +void m_freemp(struct mbuf *); void m_free_raw(struct mbuf *); struct mbuf *m_get2(int, int, short, int); struct mbuf *m_get3(int, int, short, int);