svn commit: r218820 - head/sys/dev/dc

Pyun YongHyeon yongari at FreeBSD.org
Fri Feb 18 20:38:06 UTC 2011


Author: yongari
Date: Fri Feb 18 20:38:05 2011
New Revision: 218820
URL: http://svn.freebsd.org/changeset/base/218820

Log:
  For controllers that have TX interrupt moderation capability,
  request TX completion interrupt for every 8-th frames. Previously
  dc(4) requested TX completion interrupt if number of queued TX
  descriptors is greater than 64. This caused a lot of TX completion
  interrupt under high TX load once driver queued more than 64 TX
  descriptors. It's quite normal to see more than 64 queued TX
  descriptors under high TX load.
  This change reduces the number of TX completion interrupts to be
  less than 17k under high TX load. Because this change does not
  generate TX completion interrupt for each frame, add reclaiming
  transmitted buffers in dc_tick not to generate false watchdog
  timeouts.
  While I'm here add check for queued descriptors in dc_txeof() since
  there is no more work to do when there is no pending descriptors.

Modified:
  head/sys/dev/dc/if_dc.c
  head/sys/dev/dc/if_dcreg.h

Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c	Fri Feb 18 20:37:09 2011	(r218819)
+++ head/sys/dev/dc/if_dc.c	Fri Feb 18 20:38:05 2011	(r218820)
@@ -2473,6 +2473,7 @@ dc_list_tx_init(struct dc_softc *sc)
 	}
 
 	cd->dc_tx_prod = cd->dc_tx_cons = cd->dc_tx_cnt = 0;
+	cd->dc_tx_pkts = 0;
 	bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap,
 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
 	return (0);
@@ -2841,6 +2842,9 @@ dc_txeof(struct dc_softc *sc)
 	int idx;
 	u_int32_t ctl, txstat;
 
+	if (sc->dc_cdata.dc_tx_cnt == 0)
+		return;
+
 	ifp = sc->dc_ifp;
 
 	/*
@@ -2952,6 +2956,13 @@ dc_tick(void *xsc)
 	ifp = sc->dc_ifp;
 	mii = device_get_softc(sc->dc_miibus);
 
+	/*
+	 * Reclaim transmitted frames for controllers that do
+	 * not generate TX completion interrupt for every frame.
+	 */
+	if (sc->dc_flags & DC_TX_USE_TX_INTR)
+		dc_txeof(sc);
+
 	if (sc->dc_flags & DC_REDUCED_MII_POLL) {
 		if (sc->dc_flags & DC_21143_NWAY) {
 			r = CSR_READ_4(sc, DC_10BTSTAT);
@@ -3322,8 +3333,11 @@ dc_encap(struct dc_softc *sc, struct mbu
 		    htole32(DC_TXCTL_FINT);
 	if (sc->dc_flags & DC_TX_INTR_ALWAYS)
 		sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT);
-	if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
+	if (sc->dc_flags & DC_TX_USE_TX_INTR &&
+	    ++sc->dc_cdata.dc_tx_pkts >= 8) {
+		sc->dc_cdata.dc_tx_pkts = 0;
 		sc->dc_ldata->dc_tx_list[cur].dc_ctl |= htole32(DC_TXCTL_FINT);
+	}
 	sc->dc_ldata->dc_tx_list[first].dc_status = htole32(DC_TXSTAT_OWN);
 
 	bus_dmamap_sync(sc->dc_mtag, sc->dc_cdata.dc_tx_map[idx],

Modified: head/sys/dev/dc/if_dcreg.h
==============================================================================
--- head/sys/dev/dc/if_dcreg.h	Fri Feb 18 20:37:09 2011	(r218819)
+++ head/sys/dev/dc/if_dcreg.h	Fri Feb 18 20:38:05 2011	(r218820)
@@ -495,6 +495,7 @@ struct dc_chain_data {
 	bus_dmamap_t		dc_tx_map[DC_TX_LIST_CNT];
 	u_int32_t		*dc_sbuf;
 	u_int8_t		dc_pad[DC_MIN_FRAMELEN];
+	int			dc_tx_pkts;
 	int			dc_tx_first;
 	int			dc_tx_prod;
 	int			dc_tx_cons;


More information about the svn-src-head mailing list