summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-07-13 09:52:49 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-07-13 09:52:49 +0000
commit276447e9a855fed6a45a2dbbe3f7debc72e26993 (patch)
tree024eb21bfc7b705e5adeff8be718482ba0a9a846 /sys
parent13b625926df56cb470315c8d140ee15c1c50a0d1 (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.c52
-rw-r--r--sys/sys/mbuf.h18
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 *);