From owner-p4-projects@FreeBSD.ORG Fri Oct 12 03:07:40 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6473C16A46B; Fri, 12 Oct 2007 03:07:40 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EBFB516A417 for ; Fri, 12 Oct 2007 03:07:39 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B5EF613C461 for ; Fri, 12 Oct 2007 03:07:39 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l9C37drV056984 for ; Fri, 12 Oct 2007 03:07:39 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l9C37dOv056981 for perforce@freebsd.org; Fri, 12 Oct 2007 03:07:39 GMT (envelope-from kmacy@freebsd.org) Date: Fri, 12 Oct 2007 03:07:39 GMT Message-Id: <200710120307.l9C37dOv056981@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to kmacy@freebsd.org using -f From: Kip Macy To: Perforce Change Reviews Cc: Subject: PERFORCE change 127403 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Oct 2007 03:07:40 -0000 http://perforce.freebsd.org/chv.cgi?CH=127403 Change 127403 by kmacy@kmacy_home:ethng on 2007/10/12 03:06:45 fix handling of case where packet header mbuf contained zero bytes of data - don't modify initial mbuf chain while iterating through it - when collapsing mbufs do it from the array and not the chain - when freeing mbufs do it from the chain and not the array skip special handling of mbuf chain with only buffer but multiple mbufs probably not common enough to special case and the way it was being handled could leak memory Affected files ... .. //depot/projects/ethng/src/sys/dev/cxgb/sys/uipc_mvec.c#15 edit Differences ... ==== //depot/projects/ethng/src/sys/dev/cxgb/sys/uipc_mvec.c#15 (text+ko) ==== @@ -125,7 +125,6 @@ mi->mi_flags = m->m_flags; mi->mi_len = m->m_len; - if (m->m_flags & M_PKTHDR) { mi->mi_ether_vtag = m->m_pkthdr.ether_vtag; @@ -141,6 +140,7 @@ mi->mi_size = (m->m_type == EXT_CLIOVEC) ? MCLBYTES : MIOVBYTES; mi->mi_type = m->m_type; mi->mi_len = m->m_pkthdr.len; + KASSERT(mi->mi_len, ("empty packet")); mi->mi_refcnt = NULL; } else if (m->m_flags & M_EXT) { memcpy(&mi->mi_ext, &m->m_ext, sizeof(struct m_ext_)); @@ -171,11 +171,12 @@ int busdma_map_sg_collapse(struct mbuf **m, bus_dma_segment_t *segs, int *nsegs) { - struct mbuf *m0, *n = *m; + struct mbuf *m0, *n = *m, *mhead; struct mbuf_iovec *mi; struct mbuf *marray[TX_MAX_SEGS]; int i, type, seg_count, defragged = 0, err = 0; struct mbuf_vec *mv; + uma_zone_t zone; if (n->m_flags & M_PKTHDR && !SLIST_EMPTY(&n->m_pkthdr.tags)) m_tag_delete_chain(n, NULL); @@ -221,20 +222,23 @@ /* * firmware doesn't like empty segments */ - if (__predict_false(n->m_len == 0)) { - n = m_free(n); - if (seg_count) - marray[seg_count - 1]->m_next = n; - continue; - } - seg_count++; + if (__predict_true(n->m_len != 0)) + seg_count++; + n = n->m_next; } +#if 0 + /* + * XXX needs more careful consideration + */ if (__predict_false(seg_count == 1)) { - n = *m; + n = marray[0]; + if (n != *m) + /* XXX */ goto retry; } +#endif if (seg_count == 0) { if (cxgb_debug) printf("empty segment chain\n"); @@ -257,43 +261,41 @@ goto err_out; } if (seg_count > MAX_CL_IOV) { - if ((m0 = uma_zalloc_arg(zone_jumbop, NULL, M_NOWAIT)) == NULL) { - err = ENOMEM; - goto err_out; - } + zone = zone_jumbop; type = EXT_JMPIOVEC; } else if (seg_count > MAX_MIOVEC_IOV) { - DPRINTF("seg count=%d ", seg_count); - if ((m0 = uma_zalloc_arg(zone_clust, NULL, M_NOWAIT)) == NULL) { - err = ENOMEM; - goto err_out; - } + zone = zone_clust; type = EXT_CLIOVEC; } else { - if ((m0 = uma_zalloc_arg(zone_miovec, NULL, M_NOWAIT)) == NULL) { - err = ENOMEM; - goto err_out; - } type = EXT_IOVEC; + zone = zone_miovec; } + if ((m0 = uma_zalloc_arg(zone, NULL, M_NOWAIT)) == NULL) { + err = ENOMEM; + goto err_out; + } - n = marray[0]; - memcpy(m0, n, sizeof(struct m_hdr) + sizeof(struct pkthdr)); + memcpy(m0, *m, sizeof(struct m_hdr) + sizeof(struct pkthdr)); m0->m_type = type; mv = mtomv(m0); mv->mv_count = seg_count; mv->mv_first = 0; - - for (mi = mv->mv_vec; n; mi++, segs++) { + for (i = 0, mi = mv->mv_vec; i < seg_count; mi++, segs++, i++) { + n = marray[i]; busdma_map_mbuf_fast(n, segs); - n = _mcl_collapse_mbuf(mi, n); + _mcl_collapse_mbuf(mi, n); } - for (i = 0; i < seg_count; i++) { - marray[i]->m_next = marray[i]->m_nextpkt = NULL; - if ((marray[i]->m_flags & (M_EXT|M_NOFREE)) == M_EXT) { - marray[i]->m_flags &= ~M_EXT; - m_free(marray[i]); + n = *m; + while (n) { + if (((n->m_flags & (M_EXT|M_NOFREE)) == M_EXT) && (n->m_len > 0)) + n->m_flags &= ~M_EXT; + else if (n->m_len > 0) { + n = n->m_next; + continue; } + mhead = n->m_next; + m_free(n); + n = mhead; } *nsegs = seg_count; *m = m0;