From owner-p4-projects@FreeBSD.ORG Sat Oct 20 22:03:12 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 106C216A41B; Sat, 20 Oct 2007 22:03: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 B81A916A418 for ; Sat, 20 Oct 2007 22:03: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 56CC613C45A for ; Sat, 20 Oct 2007 22:03: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 l9KM3BNF067425 for ; Sat, 20 Oct 2007 22:03:11 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l9KM3B3Y067408 for perforce@freebsd.org; Sat, 20 Oct 2007 22:03:11 GMT (envelope-from kmacy@freebsd.org) Date: Sat, 20 Oct 2007 22:03:11 GMT Message-Id: <200710202203.l9KM3B3Y067408@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 127849 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: Sat, 20 Oct 2007 22:03:12 -0000 http://perforce.freebsd.org/chv.cgi?CH=127849 Change 127849 by kmacy@kmacy_home:ethng on 2007/10/20 22:02:10 make mbuf ring a generic ring buffer for pointers Affected files ... .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#25 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_main.c#27 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#25 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_osdep.h#15 edit .. //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#34 edit Differences ... ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_adapter.h#25 (text+ko) ==== @@ -276,11 +276,11 @@ bus_dma_tag_t entry_tag; struct mbuf_head sendq; /* - * cleanq should really be an mbuf_ring to avoid extra + * cleanq should really be an buf_ring to avoid extra * mbuf touches */ struct mbuf_head cleanq; - struct mbuf_ring txq_mr; + struct buf_ring txq_mr; struct mbuf *immpkt; uint32_t txq_drops; uint32_t txq_skipped; ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_main.c#27 (text+ko) ==== @@ -221,7 +221,7 @@ "use a single queue-set per port"); #ifndef IFNET_MULTIQUEUE -int cxgb_txq_mbuf_ring_size = 0; +int cxgb_txq_buf_ring_size = 0; #endif enum { ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_multiq.c#25 (text+ko) ==== @@ -103,9 +103,9 @@ 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 = TX_ETH_Q_SIZE; -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, +int cxgb_txq_buf_ring_size = TX_ETH_Q_SIZE; +TUNABLE_INT("hw.cxgb.txq_mr_size", &cxgb_txq_buf_ring_size); +SYSCTL_UINT(_hw_cxgb, OID_AUTO, txq_mr_size, CTLFLAG_RDTUN, &cxgb_txq_buf_ring_size, 0, "size of per-queue mbuf ring"); @@ -117,7 +117,7 @@ cxgb_pcpu_enqueue_packet_(struct sge_qset *qs, struct mbuf *m) { struct sge_txq *txq; - struct mbuf_ring *mr; + struct buf_ring *mr; int prod, cons, mask; int err = 0; @@ -133,9 +133,9 @@ prod = mr->mr_prod; mask = mr->mr_size - 1; if (((prod + 1) & mask) != cons) { - mr->mr_ring[prod] = m; + mr->mr_ring[prod] = (caddr_t)m; + mb(); mr->mr_prod = (prod + 1) & mask; - mb(); } else { txq->txq_drops++; err = ENOBUFS; @@ -176,7 +176,7 @@ struct sge_qset *qs; int count, size, coalesced; struct adapter *sc; - struct mbuf_ring *mr; + struct buf_ring *mr; mr = &txq->txq_mr; coalesced = count = size = 0; @@ -193,7 +193,7 @@ } sc = qs->port->adapter; - m = mbuf_ring_dequeue(mr); + m = buf_ring_dequeue(mr); if (m == NULL) return (0); @@ -204,12 +204,12 @@ } count = 1; size = m->m_pkthdr.len; - for (m = mbuf_ring_peek(mr); m != NULL; m = mbuf_ring_peek(mr)) { + for (m = buf_ring_peek(mr); m != NULL; m = buf_ring_peek(mr)) { if (m->m_pkthdr.tso_segsz > 0 || size + m->m_pkthdr.len > TX_WR_SIZE_MAX || m->m_next != NULL) break; - mbuf_ring_dequeue(mr); + buf_ring_dequeue(mr); size += m->m_pkthdr.len; m_vec[count++] = m; @@ -360,7 +360,7 @@ while ((m = mbufq_dequeue(&txq->sendq)) != NULL) m_freem(m); - while ((m = mbuf_ring_dequeue(&txq->txq_mr)) != NULL) + while ((m = buf_ring_dequeue(&txq->txq_mr)) != NULL) m_freem(m); t3_free_tx_desc_all(txq); @@ -412,7 +412,7 @@ else { txq = &qs->txq[TXQ_ETH]; - if (!mbuf_ring_empty(&txq->txq_mr)) + if (!buf_ring_empty(&txq->txq_mr)) initerr = cxgb_pcpu_enqueue_packet_(qs, immpkt); else txq->immpkt = immpkt; @@ -442,11 +442,11 @@ } stopped = isset(&qs->txq_stopped, TXQ_ETH); - flush = ((!mbuf_ring_empty(&txq->txq_mr) && !stopped) || txq->immpkt); + flush = ((!buf_ring_empty(&txq->txq_mr) && !stopped) || txq->immpkt); max_desc = tx_flush ? TX_ETH_Q_SIZE : TX_START_MAX_DESC; err = flush ? cxgb_tx_common(qs->port->ifp, qs, max_desc) : ENOSPC; - if ((tx_flush && flush && err == 0) && !mbuf_ring_empty(&txq->txq_mr)) { + if ((tx_flush && flush && err == 0) && !buf_ring_empty(&txq->txq_mr)) { struct thread *td = curthread; if (++i > 1) { @@ -492,11 +492,11 @@ txq = &qs->txq[TXQ_ETH]; - if (((sc->tunq_coalesce == 0) || (mbuf_ring_count(&txq->txq_mr) > TX_WR_COUNT_MAX)) && mtx_trylock(&txq->lock)) { + if (((sc->tunq_coalesce == 0) || (buf_ring_count(&txq->txq_mr) > TX_WR_COUNT_MAX)) && mtx_trylock(&txq->lock)) { txq->flags |= TXQ_TRANSMITTING; err = cxgb_pcpu_start_(qs, immpkt, FALSE); txq->flags &= ~TXQ_TRANSMITTING; - resid = (mbuf_ring_count(&txq->txq_mr) > 64) || (desc_reclaimable(txq) > 64); + resid = (buf_ring_count(&txq->txq_mr) > 64) || (desc_reclaimable(txq) > 64); mtx_unlock(&txq->lock); } else if (immpkt) err = cxgb_pcpu_enqueue_packet_(qs, immpkt); @@ -586,7 +586,7 @@ if ((qs->port->ifp->if_drv_flags && IFF_DRV_RUNNING) == 0) { idleticks = hz; - if (!mbuf_ring_empty(&txq->txq_mr) || + if (!buf_ring_empty(&txq->txq_mr) || !mbufq_empty(&txq->sendq)) cxgb_pcpu_free(qs); goto done; @@ -610,7 +610,7 @@ mtx_unlock(&qs->rspq.lock); } - if ((!mbuf_ring_empty(&txq->txq_mr)) && err == 0) { + if ((!buf_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, ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_osdep.h#15 (text+ko) ==== @@ -161,8 +161,8 @@ #define L1_CACHE_BYTES 32 #endif -struct mbuf_ring { - struct mbuf **mr_ring; +struct buf_ring { + caddr_t *mr_ring; volatile uint32_t mr_cons; volatile uint32_t mr_prod; int mr_size; @@ -170,7 +170,7 @@ }; static __inline int -mbuf_ring_count(struct mbuf_ring *mr) +buf_ring_count(struct buf_ring *mr) { int size = mr->mr_size; int mask = size - 1; @@ -179,18 +179,23 @@ } static __inline int -mbuf_ring_empty(struct mbuf_ring *mr) +buf_ring_empty(struct buf_ring *mr) { return (mr->mr_cons == mr->mr_prod); } -static __inline struct mbuf * -mbuf_ring_dequeue(struct mbuf_ring *mr) +/* + * The producer and consumer are independently locked + * this relies on the consumer providing his own serialization + * + */ +static __inline void * +buf_ring_dequeue(struct buf_ring *mr) { int prod, cons, mask; - struct mbuf **ring, *m; + caddr_t *ring, m; - ring = mr->mr_ring; + ring = (caddr_t *)mr->mr_ring; mask = mr->mr_size - 1; cons = mr->mr_cons; prod = mr->mr_prod; @@ -200,17 +205,49 @@ mr->mr_cons = (cons + 1) & mask; mb(); } + return (m); +} + - return (m); +static __inline int +__buf_ring_enqueue(struct buf_ring *mr, void *m) +{ + + int prod, cons, mask, err; + + cons = mr->mr_cons; + prod = mr->mr_prod; + mask = mr->mr_size - 1; + if (((prod + 1) & mask) != cons) { + mr->mr_ring[prod] = m; + mb(); + mr->mr_prod = (prod + 1) & mask; + err = 0; + } else + err = ENOBUFS; + + return (err); +} + +static __inline int +buf_ring_enqueue(struct buf_ring *mr, void *m) +{ + int err; + + mtx_lock(&mr->mr_lock); + err = __buf_ring_enqueue(mr, m); + mtx_unlock(&mr->mr_lock); + + return (err); } -static __inline struct mbuf * -mbuf_ring_peek(struct mbuf_ring *mr) +static __inline void * +buf_ring_peek(struct buf_ring *mr) { int prod, cons, mask; - struct mbuf **ring, *m; + caddr_t *ring, m; - ring = mr->mr_ring; + ring = (caddr_t *)mr->mr_ring; mask = mr->mr_size - 1; cons = mr->mr_cons; prod = mr->mr_prod; ==== //depot/projects/ethng/src/sys/dev/cxgb/cxgb_sge.c#34 (text+ko) ==== @@ -74,7 +74,7 @@ #ifndef DISABLE_MBUF_IOVEC static int recycle_enable = 1; #endif -extern int cxgb_txq_mbuf_ring_size; +extern int cxgb_txq_buf_ring_size; int cxgb_cached_allocations; int cxgb_cached; int cxgb_ext_freed; @@ -2259,13 +2259,13 @@ int i, ret = 0; for (i = 0; i < SGE_TXQ_PER_SET; i++) { - if ((q->txq[i].txq_mr.mr_ring = malloc(cxgb_txq_mbuf_ring_size*sizeof(struct mbuf *), + if ((q->txq[i].txq_mr.mr_ring = malloc(cxgb_txq_buf_ring_size*sizeof(struct mbuf *), M_DEVBUF, M_WAITOK|M_ZERO)) == NULL) { device_printf(sc->dev, "failed to allocate mbuf ring\n"); goto err; } q->txq[i].txq_mr.mr_prod = q->txq[i].txq_mr.mr_cons = 0; - q->txq[i].txq_mr.mr_size = cxgb_txq_mbuf_ring_size; + q->txq[i].txq_mr.mr_size = cxgb_txq_buf_ring_size; mtx_init(&q->txq[i].txq_mr.mr_lock, "txq mbuf ring", NULL, MTX_DEF); }