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.
This commit is contained in:
yongari 2012-02-23 08:22:44 +00:00
parent d6295a5881
commit 48d91a32fa

View File

@ -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);
}