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