DF-3738 / fix.diff
--- a/sys/dev/netif/emx/if_emx.c +++ b/sys/dev/netif/emx/if_emx.c @@ -1911,7 +1911,27 @@ struct emx_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; - lwkt_serialize_enter(&sc->main_serialize); + if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) != + (IFF_RUNNING | IFF_UP)) + return; + + /* + * Never block on the serializer here: emx_stop() (and the LSC + * interrupt path) call callout_stop(&sc->timer) while HOLDING the + * serializer, and DragonFly's callout_stop() synchronously waits + * for an in-progress callback -- a blocking enter would deadlock + * the callout subsystem against the serializer (AB-BA). Use the + * same try-and-retry pattern as emx_txgc_timer(). + */ + if (!lwkt_serialize_try(&sc->main_serialize)) { + callout_reset(&sc->timer, 1, emx_timer, sc); + return; + } + if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) != + (IFF_RUNNING | IFF_UP)) { + lwkt_serialize_exit(&sc->main_serialize); + return; + } emx_update_link_status(sc); emx_update_stats(sc); |