Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Aug 2009 21:07:39 +0000 (UTC)
From:      Stanislav Sedov <stas@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r196370 - head/sys/dev/bge
Message-ID:  <200908182107.n7IL7d3V028466@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: stas
Date: Tue Aug 18 21:07:39 2009
New Revision: 196370
URL: http://svn.freebsd.org/changeset/base/196370

Log:
  - 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)
  MFC after:	1 week

Modified:
  head/sys/dev/bge/if_bge.c

Modified: head/sys/dev/bge/if_bge.c
==============================================================================
--- head/sys/dev/bge/if_bge.c	Tue Aug 18 20:39:35 2009	(r196369)
+++ head/sys/dev/bge/if_bge.c	Tue Aug 18 21:07:39 2009	(r196370)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908182107.n7IL7d3V028466>