PERFORCE change 117153 for review
Kip Macy
kmacy at FreeBSD.org
Mon Apr 2 01:38:10 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=117153
Change 117153 by kmacy at kmacy_vt-x:opentoe_init on 2007/04/02 01:37:22
define routine for freeing mbuf_iovec - neglect to handle sfbufs for the moment
add additional helper routines for mbuf iovec manipulation
Affected files ...
.. //depot/projects/opentoe/sys/kern/uipc_mbuf.c#2 edit
.. //depot/projects/opentoe/sys/sys/mbuf.h#4 edit
Differences ...
==== //depot/projects/opentoe/sys/kern/uipc_mbuf.c#2 (text+ko) ====
@@ -269,6 +269,90 @@
}
/*
+ * Non-directly-exported function to clean up after mbufs with M_EXT
+ * storage attached to them if the reference count hits 1.
+ */
+void
+mb_free_vec(struct mbuf *m)
+{
+ struct mbuf_iovec *iov;
+
+ KASSERT((m->m_flags & M_IOVEC) == M_IOVEC, ("%s: M_IOVEC not set", __func__));
+
+ iov = mtoiov(m);
+ KASSERT(iov->mi_count <= MAX_MBUF_IOV, ("%s: mi_count too large %d", __func__,
+ iov->mi_count));
+
+ for (i = iov->mi_first; i < iov->mi_count; i++) {
+ uma_zone_t zone;
+ int type;
+
+
+ refcnt = uma_find_refcnt(zone, iov->mi_bases[i]);
+ if (*refcnt != 1 && atomic_fetchadd_int(refcnt, -1) != 1)
+ continue;
+
+ type = (iov->mi_flags[i] & MBUF_IOV_TYPE_MASK);
+ switch (type) {
+ case EXT_CLUSTER:
+ zone = zone_clust;
+ break;
+ case EXT_JUMBOP:
+ zone = zone_jumbop;
+ break;
+ case EXT_JUMBO9:
+ zone = zone_jumbo9;
+ break;
+ case EXT_JUMBO16:
+ zone = zone_jumbo16;
+ break;
+ default:
+ zone = NULL;
+ break;
+ }
+
+ switch (type) {
+ case EXT_PACKET: /* The packet zone is special. */
+ if (*refcnt == 0)
+ *refcnt = 1;
+ uma_zfree(zone_pack, m);
+ return; /* Job done. */
+ case EXT_CLUSTER:
+ case EXT_JUMBOP:
+ case EXT_JUMBO9:
+ case EXT_JUMBO16:
+ uma_zfree(zone, iov->mi_bases[i]);
+ break;
+ case EXT_SFBUF:
+ *refcnt = 0;
+ uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *,
+ refcnt));
+ /* FALLTHROUGH */
+ case EXT_EXTREF:
+#ifdef notyet
+ KASSERT(m->m_ext.ext_free != NULL,
+ ("%s: ext_free not set", __func__));
+ (*(m->m_ext.ext_free))(m->m_ext.ext_buf,
+ m->m_ext.ext_args);
+#endif
+ panic("unsupported mbuf_iovec type: %d\n", type);
+ break;
+ default:
+ KASSERT(m->m_ext.ext_type == 0,
+ ("%s: unknown ext_type", __func__));
+
+
+ }
+ }
+ /*
+ * Free this mbuf back to the mbuf zone with all m_ext
+ * information purged.
+ */
+ m->m_flags &= ~M_IOVEC;
+ uma_zfree(zone_mbuf, m);
+}
+
+/*
* Attach the the cluster from *m to *n, set up m_ext in *n
* and bump the refcount of the cluster.
*/
==== //depot/projects/opentoe/sys/sys/mbuf.h#4 (text+ko) ====
@@ -66,6 +66,7 @@
*/
#define mtod(m, t) ((t)((m)->m_data))
#define dtom(x) ((struct mbuf *)((intptr_t)(x) & ~(MSIZE-1)))
+#define mtoiov(m) ((struct mbuf_iovec *)((m)->m_pktdat))
/*
* Argument structure passed to UMA routines during mbuf and packet
@@ -197,6 +198,7 @@
#define EXT_JUMBO9 4 /* jumbo cluster 9216 bytes */
#define EXT_JUMBO16 5 /* jumbo cluster 16184 bytes */
#define EXT_PACKET 6 /* mbuf+cluster from packet zone */
+#define EXT_MBUF 7 /* external mbuf from mbuf zone */
#define EXT_NET_DRV 100 /* custom ext_buf provided by net driver(s) */
#define EXT_MOD_TYPE 200 /* custom module's ext_buf type */
#define EXT_DISPOSABLE 300 /* can throw this buffer away w/page flipping */
@@ -281,6 +283,12 @@
*
*/
#define MAX_MBUF_IOV 12
+#define MBUF_IOV_TYPE_MASK ((1<<3)-1)
+#define mbuf_iovec_set_type(iov, i, type) \
+ (iov)->mi_flags[(i)] = (((iov)->mi_flags[(i)] & ~MBUF_IOV_TYPE_MASK) | type)
+
+#define mbuf_iovec_get_type(iov, i) ((iov)->mi_flags[(i)] & MBUF_IOV_TYPE_MASK)
+
struct mbuf_iovec {
uint16_t mi_first; /* first valid cluster */
uint16_t mi_count; /* number of valid clusters */
@@ -291,6 +299,60 @@
caddr_t mi_bases[MAX_MBUF_IOV]; /* pointers to clusters */
};
+static __inline int
+m_gettype(int size)
+{
+ int type;
+
+ switch (size) {
+ case MSIZE:
+ type = EXT_MBUF;
+ break;
+ case MCLBYTES:
+ type = EXT_CLUSTER;
+ break;
+#if MJUMPAGESIZE != MCLBYTES
+ case MJUMPAGESIZE:
+ type = EXT_JUMBOP;
+ break;
+#endif
+ case MJUM9BYTES:
+ type = EXT_JUMBO9;
+ break;
+ case MJUM16BYTES:
+ type = EXT_JUMBO16;
+ break;
+ default:
+ panic("%s: m_getjcl: invalid cluster type", __func__);
+ }
+
+ return (type);
+}
+
+static __inline void
+m_iovappend(struct mbuf *m, void *cl, int size, int len)
+{
+ struct mbuf_iovec *iov = mtoiov(m);
+ int idx = iov->mi_first + iov->mi_count;
+
+ KASSERT(idx <= MAX_MBUF_IOV, ("tried to append too many clusters to mbuf iovec"));
+
+ if ((m->m_flags & (M_EXT|M_IOVEC)) != M_IOVEC)
+ panic("invalid flags in %s", __func__);
+
+
+ if (iov->mi_count == 0) {
+ m->m_data = cl;
+ m->m_len = len;
+ }
+
+ iov->mi_flags[idx] = m_gettype(size);
+ iov->mi_bases[idx] = cl;
+ iov->mi_lens[idx] = len;
+ iov->mi_offsets[idx] = 0;
+ iov->mi_count++;
+}
+
/*
* Flags specifying how an allocation should be made.
*
@@ -361,6 +423,7 @@
static __inline void *m_cljget(struct mbuf *m, int how, int size);
static __inline void m_chtype(struct mbuf *m, short new_type);
void mb_free_ext(struct mbuf *);
+void mb_free_vec(struct mbuf *);
static __inline struct mbuf *
m_get(int how, short type)
@@ -415,6 +478,9 @@
uma_zone_t zone;
switch (size) {
+ case MSIZE:
+ zone = zone_mbuf;
+ break;
case MCLBYTES:
zone = zone_clust;
break;
@@ -472,6 +538,8 @@
if (m->m_flags & M_EXT)
mb_free_ext(m);
+ else if (m->m_flags & M_IOVEC)
+ mb_free_vec(m);
else
uma_zfree(zone_mbuf, m);
return (n);
@@ -517,32 +585,32 @@
}
static __inline void
-m_cljset(struct mbuf *m, void *cl, int size)
+m_cljset(struct mbuf *m, void *cl, int type)
{
uma_zone_t zone;
- int type;
+ int size;
- switch (size) {
- case MCLBYTES:
- type = EXT_CLUSTER;
+ switch (type) {
+ case EXT_CLUSTER:
+ size = MCLBYTES;
zone = zone_clust;
break;
#if MJUMPAGESIZE != MCLBYTES
- case MJUMPAGESIZE:
- type = EXT_JUMBOP;
+ case EXT_JUMBOP:
+ size = MJUMPAGESIZE;
zone = zone_jumbop;
break;
#endif
- case MJUM9BYTES:
- type = EXT_JUMBO9;
+ case EXT_JUMBO9:
+ size = MJUM9BYTES;
zone = zone_jumbo9;
break;
- case MJUM16BYTES:
- type = EXT_JUMBO16;
+ case EXT_JUMBO16:
+ size = MJUM16BYTES;
zone = zone_jumbo16;
break;
default:
- panic("unknown cluster size");
+ panic("unknown cluster type");
break;
}
More information about the p4-projects
mailing list