PERFORCE change 127398 for review
Kip Macy
kmacy at FreeBSD.org
Thu Oct 11 15:56:52 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=127398
Change 127398 by kmacy at kmacy_home:ethng on 2007/10/11 22:56:01
tighten up panic checks on free
always call collapse routine for marshalling info into the tx sw desc
try to defrag excessively long mbuf chain
move up freeing of mbuf tags to guarantee that they are always freed
Affected files ...
.. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#30 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/sys/mvec.h#9 edit
.. //depot/projects/ethng/src/sys/dev/cxgb/sys/uipc_mvec.c#12 edit
Differences ...
==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#30 (text+ko) ====
@@ -68,10 +68,7 @@
#include <dev/cxgb/sys/mvec.h>
#endif
-uint32_t collapse_free = 0;
-uint32_t mb_free_vec_free = 0;
int txq_fills = 0;
-int collapse_mbufs = 0;
static int bogus_imm = 0;
#ifndef DISABLE_MBUF_IOVEC
static int recycle_enable = 1;
@@ -1322,14 +1319,15 @@
if (m0->m_type == MT_DATA) {
DPRINTF("mbuf type=%d tags:%d head=%p", m0->m_type, !SLIST_EMPTY(&m0->m_pkthdr.tags),
SLIST_FIRST(&m0->m_pkthdr.tags));
- mi_collapse_mbuf(&txsd->mi, m0);
} else {
mv = mtomv(m0);
txsd->mi.mi_flags = m0->m_flags;
+ txsd->mi.mi_data = NULL;
txsd->mi.mi_base = (caddr_t)m0;
txsd->mi.mi_type = m0->m_type;
txsd->mi.mi_len = m0->m_pkthdr.len;
}
+ mi_collapse_mbuf(&txsd->mi, m0);
mi = &txsd->mi;
if (count > 1) {
==== //depot/projects/ethng/src/sys/dev/cxgb/sys/mvec.h#9 (text+ko) ====
@@ -158,7 +158,7 @@
return _m_collapse(m, maxbufs, mnew);
}
-void mb_free_ext_fast(struct mbuf_iovec *mi, int type);
+void mb_free_ext_fast(struct mbuf_iovec *mi, int type, int idx);
static __inline void
m_free_iovec(struct mbuf *m, int type)
@@ -171,7 +171,7 @@
mi = mv->mv_vec;
for (i = 0; i < mv->mv_count; i++, mi++) {
DPRINTF("freeing buf=%d of %d\n", i, mv->mv_count);
- mb_free_ext_fast(mi, mi->mi_type);
+ mb_free_ext_fast(mi, mi->mi_type, i);
}
switch (type) {
case EXT_IOVEC:
@@ -194,11 +194,17 @@
case EXT_IOVEC:
case EXT_CLIOVEC:
m = (struct mbuf *)mi->mi_base;
- DPRINTF("freeing iovec, type=%d\n", mi->mi_type);
m_free_iovec(m, mi->mi_type);
break;
+ case EXT_MBUF:
+ case EXT_CLUSTER:
+ case EXT_JUMBOP:
+ case EXT_JUMBO9:
+ case EXT_JUMBO16:
+ mb_free_ext_fast(mi, mi->mi_type, -1);
+ break;
default:
- mb_free_ext_fast(mi, mi->mi_type);
+ panic("unknown miov type: %d\n", mi->mi_type);
break;
}
}
==== //depot/projects/ethng/src/sys/dev/cxgb/sys/uipc_mvec.c#12 (text+ko) ====
@@ -122,8 +122,6 @@
struct mbuf *n = m->m_next;
prefetch(n);
- if (m->m_flags & M_PKTHDR && !SLIST_EMPTY(&m->m_pkthdr.tags))
- m_tag_delete_chain(m, NULL);
mi->mi_flags = m->m_flags;
mi->mi_len = m->m_len;
@@ -132,10 +130,19 @@
mi->mi_tso_segsz = m->m_pkthdr.tso_segsz;
mi->mi_rss_hash = m->m_pkthdr.rss_hash;
}
- if (m->m_flags & M_EXT) {
+ if (m->m_type != MT_DATA) {
+ mi->mi_data = NULL;
+ mi->mi_base = (caddr_t)m;
+ mi->mi_size = (m->m_type == EXT_CLIOVEC) ? MCLBYTES : MIOVBYTES;
+ mi->mi_type = m->m_type;
+ mi->mi_len = m->m_pkthdr.len;
+ } else if (m->m_flags & M_EXT) {
memcpy(&mi->mi_ext, &m->m_ext, sizeof(struct m_ext_));
mi->mi_data = m->m_data;
+ mi->mi_base = m->m_ext.ext_buf;
mi->mi_type = m->m_ext.ext_type;
+ mi->mi_size = m->m_ext.ext_size;
+ mi->mi_refcnt = m->m_ext.ref_cnt;
} else {
mi->mi_base = (caddr_t)m;
mi->mi_data = m->m_data;
@@ -158,10 +165,14 @@
struct mbuf *m0, *n = *m;
struct mbuf_iovec *mi;
struct mbuf *marray[TX_MAX_SEGS];
- int i, type, seg_count = 0;
+ int i, type, seg_count, defragged = 0;
struct mbuf_vec *mv;
-retry:
+ if (n->m_flags & M_PKTHDR && !SLIST_EMPTY(&n->m_pkthdr.tags))
+ m_tag_delete_chain(n, NULL);
+
+retry:
+ seg_count = 0;
if (n->m_next == NULL) {
busdma_map_mbuf_fast(n, segs);
*nsegs = 1;
@@ -174,9 +185,6 @@
if ((m0 = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
return (ENOMEM);
-
- if (!SLIST_EMPTY(&n->m_pkthdr.tags))
- m_tag_delete_chain(n, NULL);
data = m0->m_data;
SLIST_INIT(&n->m_pkthdr.tags);
@@ -185,6 +193,7 @@
m0->m_len = n->m_pkthdr.len;
m0->m_flags &= ~M_EXT;
m0->m_next = NULL;
+ m0->m_type = n->m_type;
n->m_flags &= ~M_PKTHDR;
while (n) {
memcpy(data, n->m_data, n->m_len);
@@ -215,6 +224,7 @@
}
if (__predict_false(seg_count == 1)) {
n = *m;
+ /* XXX */
goto retry;
}
if (seg_count == 0) {
@@ -224,6 +234,17 @@
} else if (seg_count >= TX_MAX_SEGS) {
if (cxgb_debug)
printf("mbuf chain too long: %d max allowed %d\n", seg_count, TX_MAX_SEGS);
+ if (!defragged) {
+ n = m_defrag(*m, M_DONTWAIT);
+ if (n == NULL) {
+ m_freem(*m);
+ *m = NULL;
+ return (ENOBUFS);
+ }
+ *m = n;
+ defragged = 1;
+ goto retry;
+ }
return (EFBIG);
}
@@ -285,6 +306,8 @@
mv->mv_count = count;
mv->mv_first = 0;
for (mp = m, i = 0, mi = mv->mv_vec; i < count; mp++, segs++, mi++, i++) {
+ if ((*mp)->m_flags & M_PKTHDR && !SLIST_EMPTY(&(*mp)->m_pkthdr.tags))
+ m_tag_delete_chain(*mp, NULL);
busdma_map_mbuf_fast(*mp, segs);
_mcl_collapse_mbuf(mi, *mp);
}
@@ -302,7 +325,7 @@
}
void
-mb_free_ext_fast(struct mbuf_iovec *mi, int type)
+mb_free_ext_fast(struct mbuf_iovec *mi, int type, int idx)
{
u_int cnt;
int dofree;
@@ -360,7 +383,7 @@
break;
default:
dump_mi(mi);
- panic("unknown mv type in m_free_vec type=%d", type);
+ panic("unknown mv type in m_free_vec type=%d idx=d", type, idx);
break;
}
}
More information about the p4-projects
mailing list