> Date: Tue, 29 Dec 2015 07:59:12 +1000
> From: David Gwynne <[email protected]>
>
> this tweaks the bge tx code and marks it mpsafe.
>
> ok?
ok kettenis@
> Index: if_bge.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_bge.c,v
> retrieving revision 1.380
> diff -u -p -r1.380 if_bge.c
> --- if_bge.c 29 Nov 2015 20:19:35 -0000 1.380
> +++ if_bge.c 28 Dec 2015 12:24:47 -0000
> @@ -2994,6 +2994,7 @@ bge_attach(struct device *parent, struct
> ifp = &sc->arpcom.ac_if;
> ifp->if_softc = sc;
> ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
> + ifp->if_xflags = IFXF_MPSAFE;
> ifp->if_ioctl = bge_ioctl;
> ifp->if_start = bge_start;
> ifp->if_watchdog = bge_watchdog;
> @@ -3665,12 +3666,12 @@ bge_txeof(struct bge_softc *sc)
>
> txcnt = atomic_sub_int_nv(&sc->bge_txcnt, freed);
>
> - if (txcnt < BGE_TX_RING_CNT - 16)
> - ifq_clr_oactive(&ifp->if_snd);
> - if (txcnt == 0)
> - ifp->if_timer = 0;
> -
> sc->bge_tx_saved_considx = cons;
> +
> + if (ifq_is_oactive(&ifp->if_snd))
> + ifq_restart(&ifp->if_snd);
> + else if (txcnt == 0)
> + ifp->if_timer = 0;
> }
>
> int
> @@ -3733,12 +3734,6 @@ bge_intr(void *xsc)
>
> /* Check TX ring producer/consumer */
> bge_txeof(sc);
> -
> - if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
> - KERNEL_LOCK();
> - bge_start(ifp);
> - KERNEL_UNLOCK();
> - }
> }
>
> return (1);
> @@ -4099,12 +4094,12 @@ doit:
> if (i < dmamap->dm_nsegs)
> goto fail_unload;
>
> - bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
> - BUS_DMASYNC_PREWRITE);
> -
> if (frag == sc->bge_tx_saved_considx)
> goto fail_unload;
>
> + bus_dmamap_sync(sc->bge_dmatag, dmamap, 0, dmamap->dm_mapsize,
> + BUS_DMASYNC_PREWRITE);
> +
> sc->bge_rdata->bge_tx_ring[cur].bge_flags |= BGE_TXBDFLAG_END;
> sc->bge_cdata.bge_tx_chain[cur] = m;
> sc->bge_cdata.bge_tx_map[cur] = dmamap;
> @@ -4126,16 +4121,14 @@ fail_unload:
> void
> bge_start(struct ifnet *ifp)
> {
> - struct bge_softc *sc;
> + struct bge_softc *sc = ifp->if_softc;
> struct mbuf *m;
> int txinc;
>
> - sc = ifp->if_softc;
> -
> - if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
> - return;
> - if (!BGE_STS_BIT(sc, BGE_STS_LINK))
> + if (!BGE_STS_BIT(sc, BGE_STS_LINK)) {
> + IFQ_PURGE(&ifp->if_snd);
> return;
> + }
>
> txinc = 0;
> while (1) {
> @@ -4591,7 +4584,6 @@ bge_stop(struct bge_softc *sc, int softo
> timeout_del(&sc->bge_rxtimeout_jumbo);
>
> ifp->if_flags &= ~IFF_RUNNING;
> - ifq_clr_oactive(&ifp->if_snd);
> ifp->if_timer = 0;
>
> if (!softonly) {
> @@ -4653,6 +4645,9 @@ bge_stop(struct bge_softc *sc, int softo
> }
>
> intr_barrier(sc->bge_intrhand);
> + ifq_barrier(&ifp->if_snd);
> +
> + ifq_clr_oactive(&ifp->if_snd);
>
> /* Free the RX lists. */
> bge_free_rx_ring_std(sc);
>
>