summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_mbuf.c1
-rw-r--r--sys/kern/uipc_mbuf.c11
-rw-r--r--sys/sys/mbuf.h3
3 files changed, 14 insertions, 1 deletions
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index a5e1348..9015e24 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -347,6 +347,7 @@ mb_dtor_mbuf(void *mem, int size, void *arg)
if ((flags & MB_NOTAGS) == 0 && (m->m_flags & M_PKTHDR) != 0)
m_tag_delete_chain(m, NULL);
KASSERT((m->m_flags & M_EXT) == 0, ("%s: M_EXT set", __func__));
+ KASSERT((m->m_flags & M_NOFREE) == 0, ("%s: M_NOFREE set", __func__));
#ifdef INVARIANTS
trash_dtor(mem, size, arg);
#endif
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 2fdb407..3fefecc 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -211,9 +211,17 @@ m_extadd(struct mbuf *mb, caddr_t buf, u_int size,
void
mb_free_ext(struct mbuf *m)
{
+ int skipmbuf;
+
KASSERT((m->m_flags & M_EXT) == M_EXT, ("%s: M_EXT not set", __func__));
KASSERT(m->m_ext.ref_cnt != NULL, ("%s: ref_cnt not set", __func__));
+
+ /*
+ * check if the header is embedded in the cluster
+ */
+ skipmbuf = (m->m_flags & M_NOFREE);
+
/* Free attached storage if this mbuf is the only reference to it. */
if (*(m->m_ext.ref_cnt) == 1 ||
atomic_fetchadd_int(m->m_ext.ref_cnt, -1) == 1) {
@@ -254,6 +262,9 @@ mb_free_ext(struct mbuf *m)
("%s: unknown ext_type", __func__));
}
}
+ if (skipmbuf)
+ return;
+
/*
* Free this mbuf back to the mbuf zone with all m_ext
* information purged.
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index dc05c78..7ed3913 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -192,6 +192,7 @@ struct mbuf {
#define M_LASTFRAG 0x2000 /* packet is last fragment */
#define M_VLANTAG 0x10000 /* ether_vtag is valid */
#define M_PROMISC 0x20000 /* packet was not for us */
+#define M_NOFREE 0x40000 /* do not free mbuf - it is embedded in the cluster */
/*
* External buffer types: identify ext_buf type.
@@ -507,7 +508,7 @@ m_free(struct mbuf *m)
if (m->m_flags & M_EXT)
mb_free_ext(m);
- else
+ else if ((m->m_flags & M_NOFREE) == 0)
uma_zfree(zone_mbuf, m);
return (n);
}
OpenPOWER on IntegriCloud