PERFORCE change 117121 for review
Kip Macy
kmacy at FreeBSD.org
Sun Apr 1 20:12:43 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=117121
Change 117121 by kmacy at kmacy_vt-x:opentoe_init on 2007/04/01 20:11:47
fix mb_ctor_clust to actually reference the correct zone for a cluster
eliminate duplicate calls to uma_find_refcnt
cleanup the INVARIANT checks in mb_dtor_clust
add m_cljset to attach a cluster to a deferred mbuf
add m_getzone to eliminate duplicated zone lookup code for clusters
add mbuf_iovec for using pktdat for cache-friendly scatter-gather of clusters
Affected files ...
.. //depot/projects/opentoe/sys/kern/kern_mbuf.c#3 edit
.. //depot/projects/opentoe/sys/sys/mbuf.h#3 edit
Differences ...
==== //depot/projects/opentoe/sys/kern/kern_mbuf.c#3 (text+ko) ====
@@ -423,7 +423,11 @@
default:
panic("unknown cluster size");
break;
- }
+ }
+
+ refcnt = uma_find_refcnt(zone, mem);
+ *refcnt = 1;
+
m = (struct mbuf *)arg;
if (m != NULL) {
m->m_ext.ext_buf = (caddr_t)mem;
@@ -433,12 +437,9 @@
m->m_ext.ext_args = NULL;
m->m_ext.ext_size = size;
m->m_ext.ext_type = type;
- m->m_ext.ref_cnt = uma_find_refcnt(zone, mem);
- *m->m_ext.ref_cnt = 1;
- } else {
- refcnt = uma_find_refcnt(zone, mem);
- *refcnt = 1;
+ m->m_ext.ref_cnt = refcnt;
}
+
return (0);
}
@@ -448,11 +449,13 @@
static void
mb_dtor_clust(void *mem, int size, void *arg)
{
+#ifdef INVARIANTS
+ uma_zone_t zone = m_getzone(size);
- KASSERT(*(uma_find_refcnt(zone_clust, mem)) <= 1,
+ KASSERT(*(uma_find_refcnt(zone, mem)) <= 1,
("%s: refcnt incorrect %u", __func__,
- *(uma_find_refcnt(zone_clust, mem))) );
-#ifdef INVARIANTS
+ *(uma_find_refcnt(zone, mem))) );
+
trash_dtor(mem, size, arg);
#endif
}
==== //depot/projects/opentoe/sys/sys/mbuf.h#3 (text+ko) ====
@@ -185,6 +185,8 @@
#define M_LASTFRAG 0x2000 /* packet is last fragment */
#define M_VLANTAG 0x10000 /* ether_vtag is valid */
#define M_PROMISC 0x20000 /* packet was not for us */
+#define M_IOVEC 0x40000 /* mbuf immediate data area is used to reference clusters */
+#define M_LRO 0x80000 /* large receive offload in use for packet */
/*
* External buffer types: identify ext_buf type.
@@ -275,6 +277,21 @@
};
/*
+ * m_pktdat == 200 bytes on 64-bit arches, need to stay below that
+ *
+ */
+#define MAX_MBUF_IOV 12
+struct mbuf_iovec {
+ uint16_t mi_first; /* first valid cluster */
+ uint16_t mi_count; /* number of valid clusters */
+ uint16_t mi_flags[MAX_MBUF_IOV]; /* per-cluster flags */
+ uint16_t mi_offsets[MAX_MBUF_IOV];/* data offsets of clusters */
+ uint16_t mi_lens[MAX_MBUF_IOV]; /* length of clusters */
+ uint32_t pad; /* 8-byte align mi_bases */
+ caddr_t mi_bases[MAX_MBUF_IOV]; /* pointers to clusters */
+};
+
+/*
* Flags specifying how an allocation should be made.
*
* The flag to use is as follows:
@@ -392,6 +409,33 @@
return ((struct mbuf *)(uma_zalloc_arg(zone_pack, &args, how)));
}
+static __inline uma_zone_t
+m_getzone(int size)
+{
+ uma_zone_t zone;
+
+ switch (size) {
+ case MCLBYTES:
+ zone = zone_clust;
+ break;
+#if MJUMPAGESIZE != MCLBYTES
+ case MJUMPAGESIZE:
+ zone = zone_jumbop;
+ break;
+#endif
+ case MJUM9BYTES:
+ zone = zone_jumbo9;
+ break;
+ case MJUM16BYTES:
+ zone = zone_jumbo16;
+ break;
+ default:
+ panic("%s: m_getjcl: invalid cluster type", __func__);
+ }
+
+ return (zone);
+}
+
/*
* m_getjcl() returns an mbuf with a cluster of the specified size attached.
* For size it takes MCLBYTES, MJUMPAGESIZE, MJUM9BYTES, MJUM16BYTES.
@@ -412,24 +456,7 @@
if (m == NULL)
return (NULL);
- switch (size) {
- case MCLBYTES:
- zone = zone_clust;
- break;
-#if MJUMPAGESIZE != MCLBYTES
- case MJUMPAGESIZE:
- zone = zone_jumbop;
- break;
-#endif
- case MJUM9BYTES:
- zone = zone_jumbo9;
- break;
- case MJUM16BYTES:
- zone = zone_jumbo16;
- break;
- default:
- panic("%s: m_getjcl: invalid cluster type", __func__);
- }
+ zone = m_getzone(size);
n = uma_zalloc_arg(zone, m, how);
if (n == NULL) {
uma_zfree(zone_mbuf, m);
@@ -468,6 +495,7 @@
}
}
+
/*
* m_cljget() is different from m_clget() as it can allocate clusters without
* attaching them to an mbuf. In that case the return value is the pointer
@@ -478,35 +506,55 @@
static __inline void *
m_cljget(struct mbuf *m, int how, int size)
{
- uma_zone_t zone;
-
+ uma_zone_t zone = m_getzone(size);
+
if (m && m->m_flags & M_EXT)
printf("%s: %p mbuf already has cluster\n", __func__, m);
if (m != NULL)
m->m_ext.ext_buf = NULL;
+ return (uma_zalloc_arg(zone, m, how));
+}
+
+static __inline void
+m_cljset(struct mbuf *m, void *cl, int size)
+{
+ uma_zone_t zone;
+ int type;
+
switch (size) {
case MCLBYTES:
+ type = EXT_CLUSTER;
zone = zone_clust;
break;
#if MJUMPAGESIZE != MCLBYTES
case MJUMPAGESIZE:
+ type = EXT_JUMBOP;
zone = zone_jumbop;
break;
#endif
case MJUM9BYTES:
+ type = EXT_JUMBO9;
zone = zone_jumbo9;
break;
case MJUM16BYTES:
+ type = EXT_JUMBO16;
zone = zone_jumbo16;
break;
default:
- panic("%s: m_getjcl: invalid cluster type", __func__);
+ panic("unknown cluster size");
+ break;
}
- return (uma_zalloc_arg(zone, m, how));
+ m->m_data = m->m_ext.ext_buf = cl;
+ m->m_ext.ext_free = m->m_ext.ext_args = NULL;
+ m->m_ext.ext_size = size;
+ m->m_ext.ext_type = type;
+ m->m_ext.ref_cnt = uma_find_refcnt(zone, cl);
+ m->m_flags |= M_EXT;
+
}
-
+
static __inline void
m_chtype(struct mbuf *m, short new_type)
{
More information about the p4-projects
mailing list