diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-13 09:52:49 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-13 09:52:49 +0000 |
commit | 276447e9a855fed6a45a2dbbe3f7debc72e26993 (patch) | |
tree | 024eb21bfc7b705e5adeff8be718482ba0a9a846 /sys | |
parent | 13b625926df56cb470315c8d140ee15c1c50a0d1 (diff) |
treat external storage allocated by the mbuf layer the same as
external storage attached to an mbuf anywhere else. this means it
uses MEXTADD to wire it up to the mbuf, and it relies on the ext_free
and ext_arg bits in the header to call the right free function
against the right pool.
M_CLUSTER gets renamed to M_EXTWR. the type field in MEXTADD gets
reused as a flags field so anything attaching storage to an mbuf
can say if it is writable or not.
ok claudio@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/uipc_mbuf.c | 52 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 18 |
2 files changed, 36 insertions, 34 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index a2dcf8af65a..c985968e29e 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.190 2014/07/09 13:05:45 dlg Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.191 2014/07/13 09:52:48 dlg Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -112,7 +112,7 @@ u_int mclsizes[] = { static char mclnames[MCLPOOLS][8]; struct pool mclpools[MCLPOOLS]; -int m_clpool(u_int); +struct pool *m_clpool(u_int); int max_linkhdr; /* largest link-level header */ int max_protohdr; /* largest protocol header */ @@ -278,29 +278,32 @@ m_getclr(int nowait, int type) return (m); } -int +struct pool * m_clpool(u_int pktlen) { + struct pool *pp; int pi; - for (pi = 0; pi < MCLPOOLS; pi++) { - if (pktlen <= mclsizes[pi]) - return (pi); + for (pi = 0; pi < nitems(mclpools); pi++) { + pp = &mclpools[pi]; + if (pktlen <= pp->pr_size) + return (pp); } - return (-1); + return (NULL); } struct mbuf * m_clget(struct mbuf *m, int how, struct ifnet *ifp, u_int pktlen) { struct mbuf *m0 = NULL; - int pi; + struct pool *pp; + caddr_t buf; int s; - pi = m_clpool(pktlen); + pp = m_clpool(pktlen); #ifdef DIAGNOSTIC - if (pi == -1) + if (pp == NULL) panic("m_clget: request for %u byte cluster", pktlen); #endif @@ -313,9 +316,8 @@ m_clget(struct mbuf *m, int how, struct ifnet *ifp, u_int pktlen) } m = m0; } - m->m_ext.ext_buf = pool_get(&mclpools[pi], - how == M_WAIT ? PR_WAITOK : PR_NOWAIT); - if (!m->m_ext.ext_buf) { + buf = pool_get(pp, how == M_WAIT ? PR_WAITOK : PR_NOWAIT); + if (buf == NULL) { if (m0) m_freem(m0); splx(s); @@ -323,15 +325,17 @@ m_clget(struct mbuf *m, int how, struct ifnet *ifp, u_int pktlen) } splx(s); - m->m_data = m->m_ext.ext_buf; - m->m_flags |= M_EXT|M_CLUSTER; - m->m_ext.ext_size = mclpools[pi].pr_size; - m->m_ext.ext_free = NULL; - m->m_ext.ext_arg = &mclpools[pi]; - MCLINITREFERENCE(m); + MEXTADD(m, buf, pp->pr_size, M_EXTWR, m_extfree_pool, pp); return (m); } +void +m_extfree_pool(caddr_t buf, u_int size, void *pp) +{ + splassert(IPL_NET); + pool_put(pp, buf); +} + struct mbuf * m_free_unlocked(struct mbuf *m) { @@ -375,15 +379,13 @@ m_extfree(struct mbuf *m) m->m_ext.ext_prevref; m->m_ext.ext_prevref->m_ext.ext_nextref = m->m_ext.ext_nextref; - } else if (m->m_flags & M_CLUSTER) { - pool_put(m->m_ext.ext_arg, m->m_ext.ext_buf); } else if (m->m_ext.ext_free) (*(m->m_ext.ext_free))(m->m_ext.ext_buf, m->m_ext.ext_size, m->m_ext.ext_arg); else panic("unknown type of extension buffer"); m->m_ext.ext_size = 0; - m->m_flags &= ~(M_EXT|M_CLUSTER); + m->m_flags &= ~(M_EXT|M_EXTWR); } void @@ -449,7 +451,7 @@ m_defrag(struct mbuf *m, int how) if (m0->m_flags & M_EXT) { memcpy(&m->m_ext, &m0->m_ext, sizeof(struct mbuf_ext)); MCLINITREFERENCE(m); - m->m_flags |= M_EXT|M_CLUSTER; + m->m_flags |= m0->m_flags & (M_EXT|M_EXTWR); m->m_data = m->m_ext.ext_buf; } else { m->m_data = m->m_pktdat; @@ -457,7 +459,7 @@ m_defrag(struct mbuf *m, int how) } m->m_pkthdr.len = m->m_len = m0->m_len; - m0->m_flags &= ~(M_EXT|M_CLUSTER); /* cluster is gone */ + m0->m_flags &= ~(M_EXT|M_EXTWR); /* cluster is gone */ m_free(m0); return (0); @@ -1186,7 +1188,7 @@ m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int wait) KASSERT(from->m_flags & M_PKTHDR); - to->m_flags = (to->m_flags & (M_EXT | M_CLUSTER)); + to->m_flags = (to->m_flags & (M_EXT | M_EXTWR)); to->m_flags |= (from->m_flags & M_COPYFLAGS); to->m_pkthdr = from->m_pkthdr; diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index cff349331fa..bedfdfe38a4 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.h,v 1.179 2014/07/09 13:05:45 dlg Exp $ */ +/* $OpenBSD: mbuf.h,v 1.180 2014/07/13 09:52:48 dlg Exp $ */ /* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */ /* @@ -167,7 +167,7 @@ struct mbuf { #define M_EXT 0x0001 /* has associated external storage */ #define M_PKTHDR 0x0002 /* start of record */ #define M_EOR 0x0004 /* end of record */ -#define M_CLUSTER 0x0008 /* external storage is a cluster */ +#define M_EXTWR 0x0008 /* external storage is writable */ #define M_PROTO1 0x0010 /* protocol-specific */ /* mbuf pkthdr flags, also in m_flags */ @@ -185,7 +185,7 @@ struct mbuf { #ifdef _KERNEL #define M_BITS \ - ("\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_CLUSTER\5M_PROTO1\6M_VLANTAG\7M_LOOP" \ + ("\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_EXTWR\5M_PROTO1\6M_VLANTAG\7M_LOOP" \ "\10M_FILDROP\11M_BCAST\12M_MCAST\13M_CONF\14M_AUTH\15M_TUNNEL" \ "\16M_ZEROIZE\17M_COMP\20M_LINK0") #endif @@ -267,7 +267,7 @@ struct mbuf { #define MCLADDREFERENCE(o, n) do { \ int ms = splnet(); \ - (n)->m_flags |= ((o)->m_flags & (M_EXT|M_CLUSTER)); \ + (n)->m_flags |= ((o)->m_flags & (M_EXT|M_EXTWR)); \ (n)->m_ext.ext_nextref = (o)->m_ext.ext_nextref; \ (n)->m_ext.ext_prevref = (o); \ (o)->m_ext.ext_nextref = (n); \ @@ -292,10 +292,9 @@ struct mbuf { * MCLGET allocates and adds an mbuf cluster to a normal mbuf; * the flag M_EXT is set upon success. */ -#define MEXTADD(m, buf, size, type, free, arg) do { \ +#define MEXTADD(m, buf, size, mflags, free, arg) do { \ (m)->m_data = (m)->m_ext.ext_buf = (caddr_t)(buf); \ - (m)->m_flags |= M_EXT; \ - (m)->m_flags &= ~M_CLUSTER; \ + (m)->m_flags |= M_EXT | (mflags & M_EXTWR); \ (m)->m_ext.ext_size = (size); \ (m)->m_ext.ext_free = (free); \ (m)->m_ext.ext_arg = (arg); \ @@ -327,7 +326,7 @@ struct mbuf { * from must have M_PKTHDR set, and to must be empty. */ #define M_MOVE_PKTHDR(to, from) do { \ - (to)->m_flags = ((to)->m_flags & (M_EXT | M_CLUSTER)); \ + (to)->m_flags = ((to)->m_flags & (M_EXT | M_EXTWR)); \ (to)->m_flags |= (from)->m_flags & M_COPYFLAGS; \ M_MOVE_HDR((to), (from)); \ if (((to)->m_flags & M_EXT) == 0) \ @@ -354,7 +353,7 @@ struct mbuf { */ #define M_READONLY(m) \ (((m)->m_flags & M_EXT) != 0 && \ - (((m)->m_flags & M_CLUSTER) == 0 || MCLISREFERENCED(m))) + (((m)->m_flags & M_EXTWR) == 0 || MCLISREFERENCED(m))) /* * Compute the amount of space available @@ -428,6 +427,7 @@ struct mbuf *m_getptr(struct mbuf *, int, int *); int m_leadingspace(struct mbuf *); int m_trailingspace(struct mbuf *); struct mbuf *m_clget(struct mbuf *, int, struct ifnet *, u_int); +void m_extfree_pool(caddr_t, u_int, void *); void m_adj(struct mbuf *, int); int m_copyback(struct mbuf *, int, int, const void *, int); void m_freem(struct mbuf *); |