summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormsaitoh <msaitoh@NetBSD.org>2019-03-27 03:29:50 +0000
committermsaitoh <msaitoh@NetBSD.org>2019-03-27 03:29:50 +0000
commita6d2fdfa0f893c6ff00f94d773fd2d427d209020 (patch)
tree738dcbe68fd7d189a67fca998dccf130111ae1e5 /sys/dev
parent5810085705388eccf4331a2ceb7019aeefdb894a (diff)
Apply OpenBSD rev. 1.94:
> ido 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 deraadt@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_bnx.c69
1 files changed, 25 insertions, 44 deletions
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index 29bb58a13fe..28173e762fa 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -1,5 +1,5 @@
-/* $NetBSD: if_bnx.c,v 1.69 2019/03/27 03:10:39 msaitoh Exp $ */
-/* $OpenBSD: if_bnx.c,v 1.85 2009/11/09 14:32:41 dlg Exp $ */
+/* $NetBSD: if_bnx.c,v 1.70 2019/03/27 03:29:50 msaitoh Exp $ */
+/* $OpenBSD: if_bnx.c,v 1.94 2011/04/18 04:27:31 dlg Exp $ */
/*-
* Copyright (c) 2006-2010 Broadcom Corporation
@@ -35,7 +35,7 @@
#if 0
__FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
#endif
-__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.69 2019/03/27 03:10:39 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.70 2019/03/27 03:29:50 msaitoh Exp $");
/*
* The following controllers are supported by this driver:
@@ -5264,14 +5264,12 @@ bnx_watchdog(struct ifnet *ifp)
int
bnx_intr(void *xsc)
{
- struct bnx_softc *sc;
- struct ifnet *ifp;
+ struct bnx_softc *sc = xsc;
+ struct ifnet *ifp = &sc->bnx_ec.ec_if;
uint32_t status_attn_bits;
+ uint16_t status_idx;
const struct status_block *sblk;
-
- sc = xsc;
-
- ifp = &sc->bnx_ec.ec_if;
+ int rv = 0;
if (!device_is_active(sc->bnx_dev) ||
(ifp->if_flags & IFF_RUNNING) == 0)
@@ -5282,25 +5280,23 @@ bnx_intr(void *xsc)
bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0,
sc->status_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ sblk = sc->status_block;
/*
* If the hardware status block index
* matches the last value read by the
* driver and we haven't asserted our
* interrupt then there's nothing to do.
*/
- if ((sc->status_block->status_idx == sc->last_status_idx) &&
- (REG_RD(sc, BNX_PCICFG_MISC_STATUS) &
- BNX_PCICFG_MISC_STATUS_INTA_VALUE))
- return 0;
+ status_idx = sblk->status_idx;
+ if ((status_idx != sc->last_status_idx) ||
+ !ISSET(REG_RD(sc, BNX_PCICFG_MISC_STATUS),
+ BNX_PCICFG_MISC_STATUS_INTA_VALUE)) {
+ rv = 1;
- /* Ack the interrupt and stop others from occurring. */
- REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
- BNX_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
- BNX_PCICFG_INT_ACK_CMD_MASK_INT);
+ /* Ack the interrupt */
+ REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
+ BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | status_idx);
- /* Keep processing data as long as there is work to do. */
- for (;;) {
- sblk = sc->status_block;
status_attn_bits = sblk->status_attn_bits;
DBRUNIF(DB_RANDOMTRUE(bnx_debug_unexpected_attention),
@@ -5325,10 +5321,10 @@ bnx_intr(void *xsc)
DBRUN(BNX_FATAL,
if (bnx_debug_unexpected_attention == 0)
- bnx_breakpoint(sc));
+ bnx_breakpoint(sc));
bnx_init(ifp);
- return 1;
+ goto out;
}
/* Check for any completed RX frames. */
@@ -5343,35 +5339,20 @@ bnx_intr(void *xsc)
* Save the status block index value for use during the
* next interrupt.
*/
- sc->last_status_idx = sblk->status_idx;
+ sc->last_status_idx = status_idx;
- /* Prevent speculative reads from getting ahead of the
- * status block.
- */
- bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
- BUS_SPACE_BARRIER_READ);
-
- /* If there's no work left then exit the isr. */
- if ((sblk->status_rx_quick_consumer_index0 ==
- sc->hw_rx_cons) &&
- (sblk->status_tx_quick_consumer_index0 == sc->hw_tx_cons))
- break;
+ /* Start moving packets again */
+ if (ifp->if_flags & IFF_RUNNING &&
+ !IFQ_IS_EMPTY(&ifp->if_snd))
+ if_schedule_deferred_start(ifp);
}
+out:
bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0,
sc->status_map->dm_mapsize, BUS_DMASYNC_PREREAD);
- /* Re-enable interrupts. */
- REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
- BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx |
- BNX_PCICFG_INT_ACK_CMD_MASK_INT);
- REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
- BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
-
- /* Handle any frames that arrived while handling the interrupt. */
- if_schedule_deferred_start(ifp);
- return 1;
+ return rv;
}
/****************************************************************************/