aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/uipc_mbuf.c
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2017-10-09 20:51:58 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2017-10-09 20:51:58 +0000
commit07e87a1d55ffc8cad3be04050b0a6898ccd849ed (patch)
treed7a33f518257b4d502c1241ef3d3139dbf9b8a12 /sys/kern/uipc_mbuf.c
parente8fd18f306915c411b08ab4664ec0aa3bc03d4d4 (diff)
downloadsrc-07e87a1d55ffc8cad3be04050b0a6898ccd849ed.tar.gz
src-07e87a1d55ffc8cad3be04050b0a6898ccd849ed.zip
Notes
Diffstat (limited to 'sys/kern/uipc_mbuf.c')
-rw-r--r--sys/kern/uipc_mbuf.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 4d4cb3888ee1..a8a0391eae5c 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -188,7 +188,17 @@ mb_dupcl(struct mbuf *n, struct mbuf *m)
KASSERT(m->m_flags & M_EXT, ("%s: M_EXT not set on %p", __func__, m));
KASSERT(!(n->m_flags & M_EXT), ("%s: M_EXT set on %p", __func__, n));
- n->m_ext = m->m_ext;
+ /*
+ * Cache access optimization. For most kinds of external
+ * storage we don't need full copy of m_ext, since the
+ * holder of the 'ext_count' is responsible to carry the
+ * free routine and its arguments. Exclusion is EXT_EXTREF,
+ * where 'ext_cnt' doesn't point into mbuf at all.
+ */
+ if (m->m_ext.ext_type == EXT_EXTREF)
+ bcopy(&m->m_ext, &n->m_ext, sizeof(struct m_ext));
+ else
+ bcopy(&m->m_ext, &n->m_ext, m_ext_copylen);
n->m_flags |= M_EXT;
n->m_flags |= m->m_flags & M_RDONLY;