From 8e10fb3d0b5f966e1f5c421b1856bef891e9f1f9 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 23 Feb 2012 08:22:44 +0000 Subject: [PATCH] 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. --- sys/dev/sf/if_sf.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c index 41748863c31d..4f8002e0ddc2 100644 --- a/sys/dev/sf/if_sf.c +++ b/sys/dev/sf/if_sf.c @@ -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); }