diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2011-04-14 06:27:53 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2011-04-14 06:27:53 +0000 |
commit | 7eca0974bc5e5d78503e19ff1a5c23de499b8bba (patch) | |
tree | 5eb22d746437f817be99a8607677674b389979c7 /sys/dev/pci | |
parent | 8e55f4167b62d99c9d314cce7c7dac05e68120c0 (diff) |
do not disable interrupts in the isr and then enable them again
when leaving. when you're handling an interrupt it is masked.
whacking the chip is work for no gain.
modify the interrupt handler so it only processes the rings once,
rather than looping over them until it runs out of work to do.
looping in the isr is bad for several reasons:
firstly, the chip does interrupt mitigation so you have a
decent/predictable amount of work to do in the isr. your first loop
will do that chunk of work (ie, it pulls off 50ish packets), and
then the successive looping aggressively pull one or two packets
off the rx ring. these extra loops work against the benefit that
interrupt mitigation provides.
bus space reads are slow. we should avoid doing them where possible
(but we should always do them when necessary).
doing the loop 5 times per isr works against the mclgeti semantics.
it knows a nic is busy and therefore needs more rx descriptors by
watching to see when the nic uses all of its descriptors between
interrupts. if we're aggressively pulling packets off by looping
in the isr then we're skewing this check.
ok henning@ krw@
testing by sthen@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_sis.c | 83 |
1 files changed, 34 insertions, 49 deletions
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c index 44def3b6165..6a97c8cb2ef 100644 --- a/sys/dev/pci/if_sis.c +++ b/sys/dev/pci/if_sis.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sis.c,v 1.103 2011/04/03 15:36:02 jasper Exp $ */ +/* $OpenBSD: if_sis.c,v 1.104 2011/04/14 06:27:52 dlg Exp $ */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. @@ -1476,58 +1476,43 @@ sis_tick(void *xsc) int sis_intr(void *arg) { - struct sis_softc *sc; - struct ifnet *ifp; + struct sis_softc *sc = arg; + struct ifnet *ifp = &sc->arpcom.ac_if; u_int32_t status; - int claimed = 0; - - sc = arg; - ifp = &sc->arpcom.ac_if; if (sc->sis_stopped) /* Most likely shared interrupt */ - return (claimed); - - /* Disable interrupts. */ - CSR_WRITE_4(sc, SIS_IER, 0); - - for (;;) { - /* Reading the ISR register clears all interrupts. */ - status = CSR_READ_4(sc, SIS_ISR); - - if ((status & SIS_INTRS) == 0) - break; - - claimed = 1; - - if (status & - (SIS_ISR_TX_DESC_OK | SIS_ISR_TX_ERR | - SIS_ISR_TX_OK | SIS_ISR_TX_IDLE)) - sis_txeof(sc); - - if (status & - (SIS_ISR_RX_DESC_OK | SIS_ISR_RX_OK | - SIS_ISR_RX_ERR | SIS_ISR_RX_IDLE)) - sis_rxeof(sc); - - if (status & (SIS_ISR_RX_IDLE)) { - /* consume what's there so that sis_rx_cons points - * to the first HW owned descriptor. */ - sis_rxeof(sc); - /* reprogram the RX listptr */ - CSR_WRITE_4(sc, SIS_RX_LISTPTR, - sc->sc_listmap->dm_segs[0].ds_addr + - offsetof(struct sis_list_data, - sis_rx_list[sc->sis_cdata.sis_rx_cons])); - } - - if (status & SIS_ISR_SYSERR) { - sis_reset(sc); - sis_init(sc); - } + return (0); + + /* Reading the ISR register clears all interrupts. */ + status = CSR_READ_4(sc, SIS_ISR); + if ((status & SIS_INTRS) == 0) + return (0); + + if (status & + (SIS_ISR_TX_DESC_OK | SIS_ISR_TX_ERR | + SIS_ISR_TX_OK | SIS_ISR_TX_IDLE)) + sis_txeof(sc); + + if (status & + (SIS_ISR_RX_DESC_OK | SIS_ISR_RX_OK | + SIS_ISR_RX_ERR | SIS_ISR_RX_IDLE)) + sis_rxeof(sc); + + if (status & (SIS_ISR_RX_IDLE)) { + /* consume what's there so that sis_rx_cons points + * to the first HW owned descriptor. */ + sis_rxeof(sc); + /* reprogram the RX listptr */ + CSR_WRITE_4(sc, SIS_RX_LISTPTR, + sc->sc_listmap->dm_segs[0].ds_addr + + offsetof(struct sis_list_data, + sis_rx_list[sc->sis_cdata.sis_rx_cons])); } - /* Re-enable interrupts. */ - CSR_WRITE_4(sc, SIS_IER, 1); + if (status & SIS_ISR_SYSERR) { + sis_reset(sc); + sis_init(sc); + } /* * XXX: Re-enable RX engine every time otherwise it occasionally @@ -1538,7 +1523,7 @@ sis_intr(void *arg) if (!IFQ_IS_EMPTY(&ifp->if_snd)) sis_start(ifp); - return (claimed); + return (1); } /* |