From 1daebacca0d4fcd672c37d2ae97abdc9c2e1e906 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 18 Aug 2009 21:13:00 +0000 Subject: [PATCH] - MFC r196370. Do not try to reevaluate current RX production index on each loop iteration as it can be updated by the card while we process the RX ring forcing us to process RX descriptors for which DMA synchronisation operation has not been performed. This fixes the bug when bge(4) drops packets under high load. Discussed with: yongari, marius Approved by: re (kib) --- sys/dev/bge/if_bge.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 4528762a02d..db65ec2caad 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3055,12 +3055,14 @@ bge_rxeof(struct bge_softc *sc) { struct ifnet *ifp; int rx_npkts = 0, stdcnt = 0, jumbocnt = 0; + uint16_t rx_prod, rx_cons; BGE_LOCK_ASSERT(sc); + rx_cons = sc->bge_rx_saved_considx; + rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx; /* Nothing to do. */ - if (sc->bge_rx_saved_considx == - sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) + if (rx_cons == rx_prod) return (rx_npkts); ifp = sc->bge_ifp; @@ -3073,8 +3075,7 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTREAD); - while (sc->bge_rx_saved_considx != - sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) { + while (rx_cons != rx_prod) { struct bge_rx_bd *cur_rx; uint32_t rxidx; struct mbuf *m = NULL; @@ -3089,11 +3090,10 @@ bge_rxeof(struct bge_softc *sc) } #endif - cur_rx = - &sc->bge_ldata.bge_rx_return_ring[sc->bge_rx_saved_considx]; + cur_rx = &sc->bge_ldata.bge_rx_return_ring[rx_cons]; rxidx = cur_rx->bge_idx; - BGE_INC(sc->bge_rx_saved_considx, sc->bge_return_ring_cnt); + BGE_INC(rx_cons, sc->bge_return_ring_cnt); if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING && cur_rx->bge_flags & BGE_RXBDFLAG_VLAN_TAG) { @@ -3207,6 +3207,7 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE); + sc->bge_rx_saved_considx = rx_cons; bge_writembx(sc, BGE_MBX_RX_CONS0_LO, sc->bge_rx_saved_considx); if (stdcnt) bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std);