Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Oct 2007 22:56:51 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 127398 for review
Message-ID:  <200710112256.l9BMupaQ029007@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=127398

Change 127398 by kmacy@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;
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710112256.l9BMupaQ029007>