summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2020-10-14 06:40:22 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2020-10-14 06:40:22 +0000
commit0e87f767ff08224185d6ca93217941f21743b0cc (patch)
treeddb57cda53928c0dae558257f01a67a26ce8472b /sys
parent343207488e3a3ff5bd5e53fbfafabc547578119e (diff)
Add an interrupt barrier in bnxt_down() and check if the interface is
running before processing rx or tx events, to avoid crashes if an interrupt is received before we finish shutting down the completion ring. tested by Pavel Mateja ok dlg@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_bnxt.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/dev/pci/if_bnxt.c b/sys/dev/pci/if_bnxt.c
index 3bbff64ee14..e2126dbea23 100644
--- a/sys/dev/pci/if_bnxt.c
+++ b/sys/dev/pci/if_bnxt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnxt.c,v 1.26 2020/07/10 13:26:37 patrick Exp $ */
+/* $OpenBSD: if_bnxt.c,v 1.27 2020/10/14 06:40:21 jmatthew Exp $ */
/*-
* Broadcom NetXtreme-C/E network driver.
*
@@ -918,7 +918,7 @@ bnxt_down(struct bnxt_softc *sc)
CLR(ifp->if_flags, IFF_RUNNING);
- ifq_clr_oactive(&ifp->if_snd);
+ intr_barrier(sc->sc_ih);
ifq_barrier(&ifp->if_snd);
timeout_del(&sc->sc_rx_refill);
@@ -1952,6 +1952,7 @@ int
bnxt_rx(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr, struct mbuf_list *ml,
int *slots, int *agslots, struct cmpl_base *cmpl)
{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
struct mbuf *m, *am;
struct bnxt_slot *bs;
struct rx_pkt_cmpl *rx = (struct rx_pkt_cmpl *)cmpl;
@@ -1960,6 +1961,9 @@ bnxt_rx(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr, struct mbuf_list *ml,
uint32_t flags;
uint16_t errors;
+ if (!ISSET(ifp->if_flags, IFF_RUNNING))
+ return (0);
+
/* second part of the rx completion */
rxhi = (struct rx_pkt_cmpl_hi *)bnxt_cpr_next_cmpl(sc, cpr);
if (rxhi == NULL) {
@@ -2026,11 +2030,15 @@ bnxt_rx(struct bnxt_softc *sc, struct bnxt_cp_ring *cpr, struct mbuf_list *ml,
void
bnxt_txeof(struct bnxt_softc *sc, int *txfree, struct cmpl_base *cmpl)
{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
struct tx_cmpl *txcmpl = (struct tx_cmpl *)cmpl;
struct bnxt_slot *bs;
bus_dmamap_t map;
u_int idx, segs, last;
+ if (!ISSET(ifp->if_flags, IFF_RUNNING))
+ return;
+
idx = sc->sc_tx_ring_cons;
last = sc->sc_tx_cons;
do {