diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2015-12-03 12:45:57 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2015-12-03 12:45:57 +0000 |
commit | 5b9965b595424ee0a65cc77675a0b1882b1d31c6 (patch) | |
tree | 5cb852b67f4b68eb26ea1cd996580ef279539df7 /sys/dev | |
parent | e7e11e4251e7fbdf2f2df72c55ecef04d1c30a84 (diff) |
tell the stack myx_start is mpsafe.
as per the stack commit, the driver changes are:
1. setting ifp->if_xflags = IFXF_MPSAFE
2. only calling if_start() instead of its own start routine
3. clearing IFF_RUNNING before calling if_start_barrier() on its way down
4. only using IFQ_DEQUEUE (not ifq_deq_begin/commit/rollback)
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_myx.c | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/sys/dev/pci/if_myx.c b/sys/dev/pci/if_myx.c index fef3993aeb7..f1c98245fbb 100644 --- a/sys/dev/pci/if_myx.c +++ b/sys/dev/pci/if_myx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_myx.c,v 1.89 2015/12/01 12:37:12 dlg Exp $ */ +/* $OpenBSD: if_myx.c,v 1.90 2015/12/03 12:45:56 dlg Exp $ */ /* * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> @@ -511,6 +511,7 @@ myx_attachhook(void *arg) ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_xflags = IFXF_MPSAFE; ifp->if_ioctl = myx_ioctl; ifp->if_start = myx_start; ifp->if_watchdog = myx_watchdog; @@ -1360,8 +1361,9 @@ myx_down(struct myx_softc *sc) printf("%s: failed to reset the device\n", DEVNAME(sc)); } - CLR(ifp->if_flags, IFF_RUNNING); ifq_clr_oactive(&ifp->if_snd); + CLR(ifp->if_flags, IFF_RUNNING); + if_start_barrier(ifp); for (ring = 0; ring < 2; ring++) { struct myx_rx_ring *mrr = &sc->sc_rx_ring[ring]; @@ -1436,11 +1438,6 @@ myx_start(struct ifnet *ifp) u_int free, used; u_int8_t flags; - if (!ISSET(ifp->if_flags, IFF_RUNNING) || - ifq_is_oactive(&ifp->if_snd) || - IFQ_IS_EMPTY(&ifp->if_snd)) - return; - idx = sc->sc_tx_ring_prod; /* figure out space */ @@ -1588,11 +1585,10 @@ int myx_intr(void *arg) { struct myx_softc *sc = (struct myx_softc *)arg; - struct ifnet *ifp = &sc->sc_ac.ac_if; volatile struct myx_status *sts = sc->sc_sts; enum myx_state state; bus_dmamap_t map = sc->sc_sts_dma.mxm_map; - u_int32_t data, start; + u_int32_t data; u_int8_t valid = 0; state = sc->sc_state; @@ -1638,15 +1634,12 @@ myx_intr(void *arg) bus_space_write_raw_region_4(sc->sc_memt, sc->sc_memh, sc->sc_irqclaimoff + sizeof(data), &data, sizeof(data)); - start = ifq_is_oactive(&ifp->if_snd); - if (sts->ms_statusupdated) { if (state == MYX_S_DOWN && sc->sc_linkdown != sts->ms_linkdown) { sc->sc_state = MYX_S_OFF; membar_producer(); wakeup(sts); - start = 0; } else { data = sts->ms_linkstate; if (data != 0xffffffff) { @@ -1660,13 +1653,6 @@ myx_intr(void *arg) bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - if (start) { - KERNEL_LOCK(); - ifq_clr_oactive(&ifp->if_snd); - myx_start(ifp); - KERNEL_UNLOCK(); - } - return (1); } @@ -1715,6 +1701,10 @@ myx_txeof(struct myx_softc *sc, u_int32_t done_count) sc->sc_tx_ring_cons = idx; sc->sc_tx_cons = cons; + + ifq_clr_oactive(&ifp->if_snd); + if (!ifq_empty(&ifp->if_snd)) + if_start(ifp); } void |