From owner-p4-projects@FreeBSD.ORG Mon Sep 24 20:35:12 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2137916A41B; Mon, 24 Sep 2007 20:35:12 +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 D1E9216A418 for ; Mon, 24 Sep 2007 20:35:11 +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 C670113C455 for ; Mon, 24 Sep 2007 20:35:11 +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 l8OKZBL0008730 for ; Mon, 24 Sep 2007 20:35:11 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l8OKZBus008718 for perforce@freebsd.org; Mon, 24 Sep 2007 20:35:11 GMT (envelope-from kmacy@freebsd.org) Date: Mon, 24 Sep 2007 20:35:11 GMT Message-Id: <200709242035.l8OKZBus008718@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 126786 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, 24 Sep 2007 20:35:12 -0000 http://perforce.freebsd.org/chv.cgi?CH=126786 Change 126786 by kmacy@kmacy_home:ethng on 2007/09/24 20:34:58 remove use of sendq list for queue management coalescing using the list doesn't help with performance but adds complexity Affected files ... .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#19 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#19 edit Differences ... ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#19 (text+ko) ==== @@ -281,6 +281,7 @@ */ struct mbuf_head cleanq; struct mbuf_ring txq_mr; + struct mbuf *immpkt; uint32_t txq_drops; uint32_t txq_skipped; uint32_t txq_coalesced; ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#19 (text+ko) ==== @@ -103,7 +103,7 @@ SYSCTL_UINT(_hw_cxgb, OID_AUTO, sleep_ticks, CTLFLAG_RDTUN, &sleep_ticks, 0, "ticks to sleep between checking pcpu queues"); -int cxgb_txq_mbuf_ring_size = 8192; +int cxgb_txq_mbuf_ring_size = 2048; TUNABLE_INT("hw.cxgb.txq_mr_size", &cxgb_txq_mbuf_ring_size); SYSCTL_UINT(_hw_cxgb, OID_AUTO, txq_mr_size, CTLFLAG_RDTUN, &cxgb_txq_mbuf_ring_size, 0, "size of per-queue mbuf ring"); @@ -118,7 +118,6 @@ { struct sge_txq *txq; struct mbuf_ring *mr; - struct mbuf_head *mbq; int prod, cons, mask; int err = 0; @@ -129,9 +128,6 @@ txq = &qs->txq[TXQ_ETH]; DPRINTF("enqueueing packet to cpuid=%d\n", qs->qs_cpuid); - - mbq = &txq->sendq; - mr = &txq->txq_mr; mtx_lock(&mr->mr_lock); cons = mr->mr_cons; @@ -179,23 +175,29 @@ struct mbuf *m; struct sge_qset *qs; int count, size, coalesced; - struct mbuf_head *mbq; + struct mbuf_ring *mr; - mbq = &txq->sendq; + mr = &txq->txq_mr; coalesced = count = size = 0; qs = txq_to_qset(txq, TXQ_ETH); if (qs->qs_flags & QS_EXITING) return (0); - for (m = mbufq_dequeue(mbq); m != NULL; m = mbufq_dequeue(mbq)) { + if (txq->immpkt != NULL) { + m_vec[0] = txq->immpkt; + txq->immpkt = NULL; + return (1); + } + + for (m = mbuf_ring_dequeue(mr); m != NULL; m = mbuf_ring_dequeue(mr)) { size += m->m_pkthdr.len; m_vec[count++] = m; if (count == TX_WR_COUNT_MAX || cxgb_pcpu_tx_coalesce == 0) break; - m = mbufq_peek(mbq); + m = mbuf_ring_peek(mr); /* * We can't coalesce TSO packets or past 11K */ @@ -337,44 +339,6 @@ return (cookie); } -static inline int -cxgb_pcpu_pkt_coalesce(struct sge_txq *txq, struct mbuf *imm) -{ - int prod, cons, mask, err; - struct mbuf_head *mbq; - struct mbuf_ring *mr; - struct mbuf **ring, *m; - - mbq = &txq->sendq; - mr = &txq->txq_mr; - ring = mr->mr_ring; - mask = mr->mr_size - 1; - err = 0; - /* - * Arbitrary threshold at which to apply backpressure - */ - if (mbufq_len(mbq) > cxgb_txq_mbuf_ring_size) { - if (imm) { - m_freem(imm); - txq->txq_drops++; - } - return (ENOBUFS); - } - - cons = mr->mr_cons; - prod = mr->mr_prod; - while (cons != prod) { - m = ring[cons]; - cons = (cons + 1) & mask; - mbufq_tail(mbq, m); - } - mr->mr_cons = cons; - if (imm) - mbufq_tail(mbq, imm); - - return (err); -} - static void cxgb_pcpu_free(struct sge_qset *qs) { @@ -383,13 +347,12 @@ while ((m = mbufq_dequeue(&txq->sendq)) != NULL) m_freem(m); - cxgb_pcpu_pkt_coalesce(txq, NULL); - while ((m = mbufq_dequeue(&txq->sendq)) != NULL) + while ((m = mbuf_ring_dequeue(&txq->txq_mr)) != NULL) m_freem(m); } static int -cxgb_pcpu_reclaim_tx(struct sge_txq *txq, struct mbuf_head *mbq) +cxgb_pcpu_reclaim_tx(struct sge_txq *txq) { int reclaimable; struct sge_qset *qs = txq_to_qset(txq, TXQ_ETH); @@ -414,7 +377,7 @@ } static int -cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush, struct mbuf_head *mbq) +cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush) { int i, err, initerr, flush, reclaimed, stopped; struct port_info *pi; @@ -433,7 +396,12 @@ initerr = ENXIO; else { txq = &qs->txq[TXQ_ETH]; - initerr = cxgb_pcpu_pkt_coalesce(txq, immpkt); + + if (!mbuf_ring_empty(&txq->txq_mr)) { + initerr = cxgb_pcpu_enqueue_packet_(qs, immpkt); + } else + txq->immpkt = immpkt; + immpkt = NULL; } if (initerr && initerr != ENOBUFS) { @@ -453,17 +421,17 @@ qs->qs_cpuid, curcpu, desc_reclaimable(txq), txq, txq->cidx, txq->pidx); } - reclaimed = cxgb_pcpu_reclaim_tx(txq, mbq); + reclaimed = cxgb_pcpu_reclaim_tx(txq); if (cxgb_debug) printf("reclaimed=%d\n", reclaimed); } stopped = isset(&qs->txq_stopped, TXQ_ETH); - flush = (!mbufq_empty(&txq->sendq) && !stopped); + flush = ((!mbuf_ring_empty(&txq->txq_mr) && !stopped) || txq->immpkt); max_desc = tx_flush ? 0xffffff : TX_START_MAX_DESC; err = flush ? cxgb_tx_common(qs->port->ifp, qs, max_desc) : ENOSPC; - - if ((tx_flush && flush && err == 0) && !mbufq_empty(&txq->sendq)) { + + if ((tx_flush && flush && err == 0) && !mbuf_ring_empty(&txq->txq_mr)) { #if 0 struct thread *td = curthread; thread_lock(td); @@ -490,8 +458,6 @@ struct port_info *pi; struct sge_qset *qs; struct sge_txq *txq = NULL /* gcc is dumb */; - struct mbuf_head mbq; - struct mbuf *m; pi = ifp->if_softc; qs = NULL; @@ -507,12 +473,11 @@ txq = &qs->txq[TXQ_ETH]; - mbufq_init(&mbq); if (mtx_trylock(&txq->lock)) { txq->flags |= TXQ_TRANSMITTING; - err = cxgb_pcpu_start_(qs, immpkt, FALSE, &mbq); + err = cxgb_pcpu_start_(qs, immpkt, FALSE); txq->flags &= ~TXQ_TRANSMITTING; - resid = (mbufq_len(&txq->sendq) > 128) || (desc_reclaimable(txq) > 128); + resid = (mbuf_ring_count(&txq->txq_mr) > 64) || (desc_reclaimable(txq) > 64); mtx_unlock(&txq->lock); } else if (immpkt) err = cxgb_pcpu_enqueue_packet_(qs, immpkt); @@ -520,21 +485,6 @@ if (resid && (txq->flags & TXQ_TRANSMITTING) == 0) wakeup(qs); - critical_enter(); - /* - * Are we on a cpu with a service thread? - */ - if (curcpu < SGE_QSETS) { - qs = &pi->adapter->sge.qs[curcpu]; - txq = &qs->txq[TXQ_ETH]; - mbufq_append(&txq->cleanq, &mbq); - critical_exit(); - } else { - critical_exit(); - while ((m = mbufq_dequeue(&mbq)) != NULL) - m_freem(m); - } - return ((err == ENOSPC) ? 0 : err); } @@ -545,9 +495,7 @@ struct sge_qset *qs; struct mbuf *m, *head, *tail, *lhead, *ltail; int calc_cookie, qidx, i; - struct mbuf_head mbq; - mbufq_init(&mbq); IFQ_LOCK(&ifp->if_snd); IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m); head = tail = m; @@ -584,7 +532,7 @@ * Assume one-to-one mapping of qset to CPU for now XXX */ - (void)cxgb_pcpu_start_(qs, NULL, TRUE, &mbq); + (void)cxgb_pcpu_start_(qs, NULL, TRUE); /* * XXX multiple packets */ @@ -599,8 +547,6 @@ struct thread *td; struct adapter *sc = qs->port->adapter; struct sge_txq *txq = &qs->txq[TXQ_ETH]; - struct mbuf_head mbq; - struct mbuf *m; int err = 0; @@ -616,18 +562,15 @@ printf("bound to %d running on %d\n", qs->qs_cpuid, curcpu); for (;;) { - mbufq_init(&mbq); - 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, &mbq); + err = cxgb_pcpu_start_(qs, NULL, TRUE); txq->flags &= ~TXQ_TRANSMITTING; mtx_unlock(&txq->lock); } else @@ -643,9 +586,7 @@ mtx_unlock(&qs->rspq.lock); } - if ((!mbufq_empty(&txq->sendq) || - (txq->txq_mr.mr_cons != txq->txq_mr.mr_prod)) && - err == 0) { + if ((!mbuf_ring_empty(&txq->txq_mr)) && err == 0) { if (cxgb_debug) printf("head=%p cons=%d prod=%d\n", txq->sendq.head, txq->txq_mr.mr_cons, @@ -653,13 +594,6 @@ continue; } done: - critical_enter(); - mbufq_append(&mbq, &txq->cleanq); - mbufq_init(&txq->cleanq); - critical_exit(); - while ((m = mbufq_dequeue(&mbq)) != NULL) - m_freem(m); - tsleep(qs, 1, "cxgbidle", sleep_ticks); }