Date: Mon, 2 Apr 2007 01:38:08 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 117153 for review Message-ID: <200704020138.l321c8cx080664@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=117153 Change 117153 by kmacy@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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704020138.l321c8cx080664>