From owner-svn-src-all@FreeBSD.ORG Sun Mar 27 22:36:16 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C64EC106566B; Sun, 27 Mar 2011 22:36:16 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B42298FC0C; Sun, 27 Mar 2011 22:36:16 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2RMaGFC071392; Sun, 27 Mar 2011 22:36:16 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2RMaGdO071390; Sun, 27 Mar 2011 22:36:16 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201103272236.p2RMaGdO071390@svn.freebsd.org> From: Pyun YongHyeon Date: Sun, 27 Mar 2011 22:36:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r220070 - stable/8/sys/dev/dc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Mar 2011 22:36:17 -0000 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;