I noticed the new dwge(4) locks up after a while running tcpbench. After scratching my head quite a lot I realised it wasn't restarting the send queue after processing tx completions, it was just clearing OACTIVE, Changing this to call ifq_restart() instead (as prescribed in ifq.h) things work much better. dwxe(4) also needs the same fix, but I haven't tested it.
ok? Index: if_dwge.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/if_dwge.c,v retrieving revision 1.1 diff -u -p -u -p -r1.1 if_dwge.c --- if_dwge.c 29 Sep 2019 13:04:03 -0000 1.1 +++ if_dwge.c 6 Oct 2019 13:12:37 -0000 @@ -812,12 +812,13 @@ dwge_tx_proc(struct dwge_softc *sc) struct ifnet *ifp = &sc->sc_ac.ac_if; struct dwge_desc *txd; struct dwge_buf *txb; - int idx; + int idx, txfree; bus_dmamap_sync(sc->sc_dmat, DWGE_DMA_MAP(sc->sc_txring), 0, DWGE_DMA_LEN(sc->sc_txring), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + txfree = 0; while (sc->sc_tx_cnt > 0) { idx = sc->sc_tx_cons; KASSERT(idx < DWGE_NTXDESC); @@ -836,8 +837,7 @@ dwge_tx_proc(struct dwge_softc *sc) txb->tb_m = NULL; } - ifq_clr_oactive(&ifp->if_snd); - + txfree++; sc->sc_tx_cnt--; if (sc->sc_tx_cons == (DWGE_NTXDESC - 1)) @@ -850,6 +850,11 @@ dwge_tx_proc(struct dwge_softc *sc) if (sc->sc_tx_cnt == 0) ifp->if_timer = 0; + + if (txfree) { + if (ifq_is_oactive(&ifp->if_snd)) + ifq_restart(&ifp->if_snd); + } } void Index: if_dwxe.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/if_dwxe.c,v retrieving revision 1.14 diff -u -p -u -p -r1.14 if_dwxe.c --- if_dwxe.c 29 Sep 2019 13:04:03 -0000 1.14 +++ if_dwxe.c 6 Oct 2019 13:12:38 -0000 @@ -870,12 +870,13 @@ dwxe_tx_proc(struct dwxe_softc *sc) struct ifnet *ifp = &sc->sc_ac.ac_if; struct dwxe_desc *txd; struct dwxe_buf *txb; - int idx; + int idx, txfree; bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_txring), 0, DWXE_DMA_LEN(sc->sc_txring), BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + txfree = 0; while (sc->sc_tx_cnt > 0) { idx = sc->sc_tx_cons; KASSERT(idx < DWXE_NTXDESC); @@ -894,8 +895,7 @@ dwxe_tx_proc(struct dwxe_softc *sc) txb->tb_m = NULL; } - ifq_clr_oactive(&ifp->if_snd); - + txfree++; sc->sc_tx_cnt--; if (sc->sc_tx_cons == (DWXE_NTXDESC - 1)) @@ -908,6 +908,11 @@ dwxe_tx_proc(struct dwxe_softc *sc) if (sc->sc_tx_cnt == 0) ifp->if_timer = 0; + + if (txfree) { + if (ifq_is_oactive(&ifp->if_snd)) + ifq_restart(&ifp->if_snd); + } } void