svn commit: r228326 - head/sys/dev/et

Pyun YongHyeon yongari at FreeBSD.org
Wed Dec 7 19:08:54 UTC 2011


Author: yongari
Date: Wed Dec  7 19:08:54 2011
New Revision: 228326
URL: http://svn.freebsd.org/changeset/base/228326

Log:
  Controller does not require TX start command for every frame.  So
  send a single TX command after setting up all TX frames.  This
  removes unnecessary register accesses and bus_dmamap_sync(9) calls.
  et(4) uses TX interrupt moderation so it's possible to have TX
  buffers that were already transmitted but waiting for TX completion
  interrupt.  If the number of available TX descriptor is less then
  1/3 of total TX descriptor, try reclaiming first to get enough free
  TX descriptors before setting up TX descriptors.
  After r228325, et_txeof() no longer tries to send frames after
  reclaiming TX buffers.  That change was made to give more chance
  to transmit frames in main interrupt handler since we can still
  send frames in interrupt handler with RX interrupt.  So right
  before exiting interrupt hander, after enabling interrupt, try to
  send more frames.  This gives slightly better performance numbers.
  
  While I'm here reduce number of spare TX descriptors from 8 to 4.
  Controller does not require reserved TX descriptors, it was just to
  reduce TX overhead.  After r228325, driver has much lower TX
  overhead so it does not make sense to reserve 8 TX descriptors.

Modified:
  head/sys/dev/et/if_et.c
  head/sys/dev/et/if_etvar.h

Modified: head/sys/dev/et/if_et.c
==============================================================================
--- head/sys/dev/et/if_et.c	Wed Dec  7 18:17:09 2011	(r228325)
+++ head/sys/dev/et/if_et.c	Wed Dec  7 19:08:54 2011	(r228326)
@@ -1097,7 +1097,11 @@ et_intr(void *xsc)
 	if (intrs & ET_INTR_TIMER)
 		CSR_WRITE_4(sc, ET_TIMER, sc->sc_timer);
 back:
-	et_enable_intrs(sc, ET_INTRS);
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		et_enable_intrs(sc, ET_INTRS);
+		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			et_start_locked(ifp);
+	}
 	ET_UNLOCK(sc);
 }
 
@@ -1240,7 +1244,9 @@ et_start_locked(struct ifnet *ifp)
 {
 	struct et_softc *sc;
 	struct mbuf *m_head = NULL;
+	struct et_txdesc_ring *tx_ring;
 	struct et_txbuf_data *tbd;
+	uint32_t tx_ready_pos;
 	int enq;
 
 	sc = ifp->if_softc;
@@ -1252,7 +1258,18 @@ et_start_locked(struct ifnet *ifp)
 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
 		return;
 
+	/*
+	 * Driver does not request TX completion interrupt for every
+	 * queued frames to prevent generating excessive interrupts.
+	 * This means driver may wait for TX completion interrupt even
+	 * though some frames were sucessfully transmitted.  Reclaiming
+	 * transmitted frames will ensure driver see all available
+	 * descriptors.
+	 */
 	tbd = &sc->sc_tx_data;
+	if (tbd->tbd_used > (ET_TX_NDESC * 2) / 3)
+		et_txeof(sc);
+
 	for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
 		if (tbd->tbd_used + ET_NSEG_SPARE >= ET_TX_NDESC) {
 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
@@ -1277,8 +1294,17 @@ et_start_locked(struct ifnet *ifp)
 		ETHER_BPF_MTAP(ifp, m_head);
 	}
 
-	if (enq > 0)
+	if (enq > 0) {
+		tx_ring = &sc->sc_tx_ring;
+		bus_dmamap_sync(tx_ring->tr_dtag, tx_ring->tr_dmap,
+		    BUS_DMASYNC_PREWRITE);
+		tx_ready_pos = tx_ring->tr_ready_index &
+		    ET_TX_READY_POS_INDEX_MASK;
+		if (tx_ring->tr_ready_wrap)
+			tx_ready_pos |= ET_TX_READY_POS_WRAP;
+		CSR_WRITE_4(sc, ET_TX_READY_POS, tx_ready_pos);
 		sc->watchdog_timer = 5;
+	}
 }
 
 static void
@@ -2036,7 +2062,7 @@ et_encap(struct et_softc *sc, struct mbu
 	struct mbuf *m;
 	bus_dma_segment_t segs[ET_NSEG_MAX];
 	bus_dmamap_t map;
-	uint32_t csum_flags, last_td_ctrl2, tx_ready_pos;
+	uint32_t csum_flags, last_td_ctrl2;
 	int error, i, idx, first_idx, last_idx, nsegs;
 
 	tx_ring = &sc->sc_tx_ring;
@@ -2121,12 +2147,6 @@ et_encap(struct et_softc *sc, struct mbu
 	tbd->tbd_used += nsegs;
 	MPASS(tbd->tbd_used <= ET_TX_NDESC);
 
-	bus_dmamap_sync(tx_ring->tr_dtag, tx_ring->tr_dmap,
-	    BUS_DMASYNC_PREWRITE);
-	tx_ready_pos = tx_ring->tr_ready_index & ET_TX_READY_POS_INDEX_MASK;
-	if (tx_ring->tr_ready_wrap)
-		tx_ready_pos |= ET_TX_READY_POS_WRAP;
-	CSR_WRITE_4(sc, ET_TX_READY_POS, tx_ready_pos);
 	return (0);
 }
 

Modified: head/sys/dev/et/if_etvar.h
==============================================================================
--- head/sys/dev/et/if_etvar.h	Wed Dec  7 18:17:09 2011	(r228325)
+++ head/sys/dev/et/if_etvar.h	Wed Dec  7 19:08:54 2011	(r228326)
@@ -41,7 +41,7 @@
 #define ET_RING_ALIGN		4096
 #define ET_STATUS_ALIGN		8
 #define ET_NSEG_MAX		32	/* XXX no limit actually */
-#define ET_NSEG_SPARE		8
+#define ET_NSEG_SPARE		4
 
 #define ET_TX_NDESC		512
 #define ET_RX_NDESC		512


More information about the svn-src-head mailing list