diff options
author | kmacy <kmacy@FreeBSD.org> | 2007-10-06 21:42:39 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2007-10-06 21:42:39 +0000 |
commit | caeef6111c8450d350a0926d31968121a5b5ae73 (patch) | |
tree | 418691345a5209afc71ef70182373d04f589cdde /sys/kern/uipc_mbuf.c | |
parent | c00108fd67397129aaed54bbec1d64b7b0cd4259 (diff) | |
download | FreeBSD-src-caeef6111c8450d350a0926d31968121a5b5ae73.zip FreeBSD-src-caeef6111c8450d350a0926d31968121a5b5ae73.tar.gz |
This patch adds an M_NOFREE flag which allows one to mark an mbuf as
not being independently freeable. This allows one to embed an mbuf in
the cluster itself. This confers the benefits of the packet zone on
all cluster sizes. Embedded mbufs currently suffer from the same
limitation that packet zone mbufs do in that one cannot disconnect
them and pass them around independently of the cluster. It would
likely be possible to eliminate this limitation in the future by
adding a second reference for the mbuf itself.
Approved by: re(gnn)
Diffstat (limited to 'sys/kern/uipc_mbuf.c')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 11 |
1 files changed, 11 insertions, 0 deletions
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. |