Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Mar 2011 22:36:16 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r220070 - stable/8/sys/dev/dc
Message-ID:  <201103272236.p2RMaGdO071390@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Sun Mar 27 22:36:16 2011
New Revision: 220070
URL: http://svn.freebsd.org/changeset/base/220070

Log:
  MFC r218830-218831:
  r218830:
    Send frames only when there is a valid link and driver is running
    as well as controller has enough free TX descriptors.
    Remove check for number of queued frames before attempting to
    transmit. I guess it was added to allow draining queued frames
    even if there is no link. I'm under the impression this type of
    check should be done in upper layer. No other drivers in tree do
    that.
  
  r218831:
    Rearrange interrupt handler a bit and remove forever loop.
    Previously dc(4) always checked whether there is pending interrupts
    and this consumed a lot of CPU cycles in interrupt handler. Limit
    the number of processing for TX/RX frames to 16. Also allow sending
    frames in the loop not to starve TX under high RX load.
    Reading DC_ISR register should be protected with driver lock,
    otherwise interrupt handler could be run(e.g. link state change)
    before the completion of dc_init_locked().
  
    While I'm here remove unneeded code.

Modified:
  stable/8/sys/dev/dc/if_dc.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/dc/if_dc.c
==============================================================================
--- stable/8/sys/dev/dc/if_dc.c	Sun Mar 27 22:32:14 2011	(r220069)
+++ stable/8/sys/dev/dc/if_dc.c	Sun Mar 27 22:36:16 2011	(r220070)
@@ -3135,16 +3135,19 @@ dc_intr(void *arg)
 	struct dc_softc *sc;
 	struct ifnet *ifp;
 	u_int32_t status;
+	int curpkts, n;
 
 	sc = arg;
 
 	if (sc->suspended)
 		return;
 
-	if ((CSR_READ_4(sc, DC_ISR) & DC_INTRS) == 0)
-		return;
-
 	DC_LOCK(sc);
+	status = CSR_READ_4(sc, DC_ISR);
+	if (status == 0xFFFFFFFF || (status & DC_INTRS) == 0) {
+		DC_UNLOCK(sc);
+		return;
+	}
 	ifp = sc->dc_ifp;
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING) {
@@ -3152,26 +3155,16 @@ dc_intr(void *arg)
 		return;
 	}
 #endif
-
-	/* Suppress unwanted interrupts */
-	if (!(ifp->if_flags & IFF_UP)) {
-		if (CSR_READ_4(sc, DC_ISR) & DC_INTRS)
-			dc_stop(sc);
-		DC_UNLOCK(sc);
-		return;
-	}
-
 	/* Disable interrupts. */
 	CSR_WRITE_4(sc, DC_IMR, 0x00000000);
 
-	while (((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) &&
-	    status != 0xFFFFFFFF &&
-	    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-
+	for (n = 16; n > 0; n--) {
+		if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+			break;
+		/* Ack interrupts. */
 		CSR_WRITE_4(sc, DC_ISR, status);
 
 		if (status & DC_ISR_RX_OK) {
-			int		curpkts;
 			curpkts = ifp->if_ipackets;
 			dc_rxeof(sc);
 			if (curpkts == ifp->if_ipackets) {
@@ -3196,7 +3189,6 @@ dc_intr(void *arg)
 
 		if ((status & DC_ISR_RX_WATDOGTIMEO)
 		    || (status & DC_ISR_RX_NOBUF)) {
-			int		curpkts;
 			curpkts = ifp->if_ipackets;
 			dc_rxeof(sc);
 			if (curpkts == ifp->if_ipackets) {
@@ -3205,17 +3197,23 @@ dc_intr(void *arg)
 			}
 		}
 
+		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+			dc_start_locked(ifp);
+
 		if (status & DC_ISR_BUS_ERR) {
 			dc_reset(sc);
 			dc_init_locked(sc);
+			DC_UNLOCK(sc);
+			return;
 		}
+		status = CSR_READ_4(sc, DC_ISR);
+		if (status == 0xFFFFFFFF || (status & DC_INTRS) == 0)
+			break;
 	}
 
 	/* Re-enable interrupts. */
-	CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
-
-	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		dc_start_locked(ifp);
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+		CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
 
 	DC_UNLOCK(sc);
 }
@@ -3375,10 +3373,8 @@ dc_start_locked(struct ifnet *ifp)
 
 	DC_LOCK_ASSERT(sc);
 
-	if (!sc->dc_link && ifp->if_snd.ifq_len < 10)
-		return;
-
-	if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
+	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+	    IFF_DRV_RUNNING || sc->dc_link == 0)
 		return;
 
 	idx = sc->dc_cdata.dc_tx_first = sc->dc_cdata.dc_tx_prod;



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