Date: Thu, 23 Feb 2012 08:22:44 +0000 (UTC) From: Pyun YongHyeon <yongari@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r232040 - head/sys/dev/sf Message-ID: <201202230822.q1N8Mik4091539@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: yongari Date: Thu Feb 23 08:22:44 2012 New Revision: 232040 URL: http://svn.freebsd.org/changeset/base/232040 Log: Add check for IFF_DRV_RUNNING flag after serving an interrupt and don't give RX path more priority than TX path. Also remove infinite loop in interrupt handler and limit number of iteration to 32. This change addresses system load fluctuations under high network load. Modified: head/sys/dev/sf/if_sf.c Modified: head/sys/dev/sf/if_sf.c ============================================================================== --- head/sys/dev/sf/if_sf.c Thu Feb 23 07:56:19 2012 (r232039) +++ head/sys/dev/sf/if_sf.c Thu Feb 23 08:22:44 2012 (r232040) @@ -1549,7 +1549,9 @@ sf_rxeof(struct sf_softc *sc) */ eidx = 0; prog = 0; - for (cons = sc->sf_cdata.sf_rxc_cons; ; SF_INC(cons, SF_RX_CLIST_CNT)) { + for (cons = sc->sf_cdata.sf_rxc_cons; + (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; + SF_INC(cons, SF_RX_CLIST_CNT)) { cur_cmp = &sc->sf_rdata.sf_rx_cring[cons]; status = le32toh(cur_cmp->sf_rx_status1); if (status == 0) @@ -1852,6 +1854,7 @@ sf_intr(void *arg) struct sf_softc *sc; struct ifnet *ifp; uint32_t status; + int cnt; sc = (struct sf_softc *)arg; SF_LOCK(sc); @@ -1870,13 +1873,13 @@ sf_intr(void *arg) if ((ifp->if_capenable & IFCAP_POLLING) != 0) goto done_locked; #endif - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - goto done_locked; /* Disable interrupts. */ csr_write_4(sc, SF_IMR, 0x00000000); - for (; (status & SF_INTRS) != 0;) { + for (cnt = 32; (status & SF_INTRS) != 0;) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; if ((status & SF_ISR_RXDQ1_DMADONE) != 0) sf_rxeof(sc); @@ -1911,15 +1914,19 @@ sf_intr(void *arg) #endif } } + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + sf_start_locked(ifp); + if (--cnt <= 0) + break; /* Reading the ISR register clears all interrrupts. */ status = csr_read_4(sc, SF_ISR); } - /* Re-enable interrupts. */ - csr_write_4(sc, SF_IMR, SF_INTRS); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + /* Re-enable interrupts. */ + csr_write_4(sc, SF_IMR, SF_INTRS); + } - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - sf_start_locked(ifp); done_locked: SF_UNLOCK(sc); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202230822.q1N8Mik4091539>