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>