From owner-p4-projects@FreeBSD.ORG Mon Aug 20 22:02:13 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 45FA016A469; Mon, 20 Aug 2007 22:02:13 +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 E737616A420 for ; Mon, 20 Aug 2007 22:02:12 +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 D68CD13C48D for ; Mon, 20 Aug 2007 22:02:12 +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 l7KM2CNP002692 for ; Mon, 20 Aug 2007 22:02:12 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7KM2Crd002688 for perforce@freebsd.org; Mon, 20 Aug 2007 22:02:12 GMT (envelope-from kmacy@freebsd.org) Date: Mon, 20 Aug 2007 22:02:12 GMT Message-Id: <200708202202.l7KM2Crd002688@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 125462 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: Mon, 20 Aug 2007 22:02:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=125462 Change 125462 by kmacy@kmacy_home:ethng on 2007/08/20 22:02:11 - track number of descriptors skipped and number of mbufs freed - bump txq_drops when coalesce fails due to queue overflow - only print debug statement on 10th iteration in reclaim - fix leak caused by acting as if more were reclaimed per iteration than were in fact - TX_START_MAX_DESC appears to be optimally set to 2^5 - don't call bus_dmamap_destroy when freeing corresponding mbuf Affected files ... .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#10 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#11 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_osdep.h#4 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#13 edit Differences ... ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#10 (text+ko) ==== @@ -272,6 +272,8 @@ struct mbuf_head sendq; struct mbuf_ring txq_mr; uint32_t txq_drops; + uint32_t txq_skipped; + unsigned long txq_frees; struct mtx lock; #define TXQ_NAME_LEN 32 char lockbuf[TXQ_NAME_LEN]; ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#11 (text+ko) ==== @@ -349,8 +349,10 @@ * Arbitrary threshold at which to apply backpressure */ if (mbufq_len(mbq) > cxgb_txq_mbuf_ring_size) { - if (imm) + if (imm) { m_freem_vec(imm); + txq->txq_drops++; + } *complete = 1; return (ENOBUFS); } @@ -388,72 +390,72 @@ static int cxgb_pcpu_reclaim_tx(struct sge_txq *txq) { - int reclaimable, reclaimed, i, j, n; + int reclaimable, reclaimed, freed, i, j, n; struct mbuf *m_vec[TX_CLEAN_MAX_DESC]; struct sge_qset *qs = txq_to_qset(txq, TXQ_ETH); KASSERT(qs->qs_cpuid == curcpu, ("cpu qset mismatch cpuid=%d curcpu=%d", qs->qs_cpuid, curcpu)); - reclaimed = j = 0; - reclaimable = desc_reclaimable(txq); + freed = reclaimed = j = 0; + reclaimable = min(desc_reclaimable(txq), TX_CLEAN_MAX_DESC); while (reclaimable > 0) { - n = t3_free_tx_desc(txq, min(reclaimable, TX_CLEAN_MAX_DESC), m_vec); + n = t3_free_tx_desc(txq, reclaimable, m_vec); - reclaimed += min(reclaimable, TX_CLEAN_MAX_DESC); + reclaimed += reclaimable; - if (j > 5 || cxgb_debug) + if (j > 10 || cxgb_debug) printf("n=%d reclaimable=%d txq->processed=%d txq->cleaned=%d txq->in_use=%d\n", n, reclaimable, txq->processed, txq->cleaned, txq->in_use); - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) m_freem_vec(m_vec[i]); + freed += n; j++; txq->cleaned += reclaimable; txq->in_use -= reclaimable; if (isset(&qs->txq_stopped, TXQ_ETH)) clrbit(&qs->txq_stopped, TXQ_ETH); - reclaimable = desc_reclaimable(txq); + reclaimable = min(desc_reclaimable(txq), TX_CLEAN_MAX_DESC); } + txq->txq_frees += freed; return (reclaimed); } static int cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush) { - int i, err, flush, complete, reclaimed, stopped; + int i, err, initerr, flush, complete, reclaimed, stopped; struct port_info *pi; struct sge_txq *txq; adapter_t *sc; uint32_t max_desc; pi = qs->port; - err = 0; + initerr = err = i = reclaimed = 0; sc = pi->adapter; - i = reclaimed = 0; retry: if (!pi->link_config.link_ok) - err = ENXIO; + initerr = ENXIO; else if (qs->qs_flags & QS_EXITING) - err = ENXIO; + initerr = ENXIO; else { txq = &qs->txq[TXQ_ETH]; - cxgb_pcpu_pkt_coalesce(txq, immpkt, &complete); + initerr = cxgb_pcpu_pkt_coalesce(txq, immpkt, &complete); immpkt = NULL; } - if (err) { + if (initerr && initerr != ENOBUFS) { if (cxgb_debug) printf("cxgb link down\n"); if (immpkt) m_freem_vec(immpkt); - return (err); + return (initerr); } - - if (desc_reclaimable(txq) > 0) { + if ((tx_flush && (desc_reclaimable(txq) > 0)) || (desc_reclaimable(txq) > (TX_ETH_Q_SIZE>>1))) { int reclaimed = 0; if (cxgb_debug) { @@ -488,6 +490,8 @@ goto retry; } + err = (initerr != 0) ? initerr : err; + return (err); } @@ -495,15 +499,14 @@ cxgb_pcpu_start(struct ifnet *ifp, struct mbuf *immpkt) { uint32_t cookie; - int err, qidx, locked; + int err, qidx, locked, resid; struct port_info *pi; struct sge_qset *qs; struct sge_txq *txq = NULL /* gcc is dumb */; - pi = ifp->if_softc; qs = NULL; - err = cookie = locked = 0; + resid = err = cookie = locked = 0; if (immpkt && (immpkt->m_pkthdr.rss_hash != 0)) { cookie = immpkt->m_pkthdr.rss_hash; @@ -516,11 +519,17 @@ txq = &qs->txq[TXQ_ETH]; if (mtx_trylock(&txq->lock)) { + txq->flags |= TXQ_TRANSMITTING; err = cxgb_pcpu_start_(qs, immpkt, FALSE); + txq->flags &= ~TXQ_TRANSMITTING; + resid = (mbufq_len(&txq->sendq) > 128) || (desc_reclaimable(txq) > 128); mtx_unlock(&txq->lock); } else if (immpkt) err = cxgb_pcpu_enqueue_packet_(qs, immpkt); + if (resid && (txq->flags & TXQ_TRANSMITTING) == 0) + wakeup(qs); + return ((err == ENOSPC) ? 0 : err); } @@ -599,9 +608,14 @@ for (;;) { if (qs->qs_flags & QS_EXITING) break; - + + if ((qs->port->ifp->if_drv_flags && IFF_DRV_RUNNING) == 0) + goto done; + if (mtx_trylock(&txq->lock)) { + txq->flags |= TXQ_TRANSMITTING; err = cxgb_pcpu_start_(qs, NULL, TRUE); + txq->flags &= ~TXQ_TRANSMITTING; mtx_unlock(&txq->lock); } else err = EINPROGRESS; @@ -625,6 +639,7 @@ txq->txq_mr.mr_prod); continue; } + done: tsleep(qs, 1, "cxgbidle", sleep_ticks); } ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_osdep.h#4 (text+ko) ==== @@ -117,12 +117,9 @@ #define TX_START_MIN_DESC (TX_MAX_DESC << 2) -#ifdef IFNET_MULTIQUEUE -#define TX_START_MAX_DESC (TX_MAX_DESC << 4) -#else + #define TX_START_MAX_DESC (TX_MAX_DESC << 3) /* maximum number of descriptors * call to start used per */ -#endif #define TX_CLEAN_MAX_DESC (TX_MAX_DESC << 4) /* maximum tx descriptors * to clean per iteration */ ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#13 (text+ko) ==== @@ -1691,7 +1691,6 @@ if (d->m) { if (d->flags & TX_SW_DESC_MAPPED) { bus_dmamap_unload(q->entry_tag, d->map); - bus_dmamap_destroy(q->entry_tag, d->map); d->flags &= ~TX_SW_DESC_MAPPED; } if (m_get_priority(d->m) == cidx) { @@ -1701,7 +1700,9 @@ } else { printf("pri=%d cidx=%d\n", (int)m_get_priority(d->m), cidx); } - } + } else + q->txq_skipped++; + ++d; if (++cidx == q->size) { cidx = 0; @@ -2830,6 +2831,12 @@ SYSCTL_ADD_UINT(ctx, qspoidlist, OID_AUTO, "in_use", CTLFLAG_RD, &txq->in_use, 0, "#tunneled packet slots in use"); + SYSCTL_ADD_ULONG(ctx, qspoidlist, OID_AUTO, "frees", + CTLFLAG_RD, &txq->txq_frees, + "#tunneled packets freed"); + SYSCTL_ADD_UINT(ctx, qspoidlist, OID_AUTO, "skipped", + CTLFLAG_RD, &txq->txq_skipped, + 0, "#tunneled packet descriptors skipped"); SYSCTL_ADD_UINT(ctx, qspoidlist, OID_AUTO, "stopped_flags", CTLFLAG_RD, &qs->txq_stopped, 0, "tx queues stopped");