Module Name: src Committed By: matt Date: Tue Dec 25 21:17:41 UTC 2012
Modified Files: src/sys/arch/arm/broadcom: bcm53xx_eth.c Log Message: Change the way rx are consumed. Only consume a 1/4 of the receive buffers before refilling with new buffers. Don't stop until there are no packets left to receive. To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/sys/arch/arm/broadcom/bcm53xx_eth.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/broadcom/bcm53xx_eth.c diff -u src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.19 src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.20 --- src/sys/arch/arm/broadcom/bcm53xx_eth.c:1.19 Wed Dec 19 02:44:39 2012 +++ src/sys/arch/arm/broadcom/bcm53xx_eth.c Tue Dec 25 21:17:40 2012 @@ -35,7 +35,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth.c,v 1.19 2012/12/19 02:44:39 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: bcm53xx_eth.c,v 1.20 2012/12/25 21:17:40 matt Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -1009,29 +1009,27 @@ bcmeth_rx_input( #endif } -static void +static bool bcmeth_rxq_consume( struct bcmeth_softc *sc, - struct bcmeth_rxqueue *rxq) + struct bcmeth_rxqueue *rxq, + size_t atmost) { struct ifnet * const ifp = &sc->sc_if; struct gmac_rxdb *consumer = rxq->rxq_consumer; size_t rxconsumed = 0; + bool didconsume = false; - for (;;) { + while (atmost-- > 0) { if (consumer == rxq->rxq_producer) { - rxq->rxq_consumer = consumer; - rxq->rxq_inuse -= rxconsumed; KASSERT(rxq->rxq_inuse == 0); - return; + break; } uint32_t rcvsts0 = bcmeth_read_4(sc, rxq->rxq_reg_rcvsts0); uint32_t currdscr = __SHIFTOUT(rcvsts0, RCV_CURRDSCR); if (consumer == rxq->rxq_first + currdscr) { - rxq->rxq_consumer = consumer; - rxq->rxq_inuse -= rxconsumed; - return; + break; } bcmeth_rxq_desc_postsync(sc, rxq, consumer, 1); @@ -1039,6 +1037,7 @@ bcmeth_rxq_consume( * We own this packet again. Copy the rxsts word from it. */ rxconsumed++; + didconsume = true; uint32_t rxsts; KASSERT(rxq->rxq_mhead != NULL); bus_dmamap_t map = M_GETCTX(rxq->rxq_mhead, bus_dmamap_t); @@ -1152,6 +1151,17 @@ bcmeth_rxq_consume( consumer = rxq->rxq_first; } } + + /* + * Update queue info. + */ + rxq->rxq_consumer = consumer; + rxq->rxq_inuse -= rxconsumed; + + /* + * Did we consume anything? + */ + return didconsume; } static void @@ -1896,7 +1906,14 @@ bcmeth_soft_intr(void *arg) /* * Let's consume */ - bcmeth_rxq_consume(sc, &sc->sc_rxq); + while (bcmeth_rxq_consume(sc, &sc->sc_rxq, + sc->sc_rxq.rxq_threshold / 4)) { + /* + * We've consumed a quarter of the ring and still have + * more to do. Refill the ring. + */ + bcmeth_rxq_produce(sc, &sc->sc_rxq); + } intmask |= RCVINT; } @@ -1949,7 +1966,14 @@ bcmeth_worker(struct work *wk, void *arg /* * Let's consume */ - bcmeth_rxq_consume(sc, &sc->sc_rxq); + while (bcmeth_rxq_consume(sc, &sc->sc_rxq, + sc->sc_rxq.rxq_threshold / 4)) { + /* + * We've consumed a quarter of the ring and still have + * more to do. Refill the ring. + */ + bcmeth_rxq_produce(sc, &sc->sc_rxq); + } intmask |= RCVINT; }