DF-3776 / fix.diff
--- a/sys/dev/netif/jme/if_jme.c +++ b/sys/dev/netif/jme/if_jme.c @@ -2568,7 +2568,23 @@ struct jme_softc *sc = xsc; struct mii_data *mii = device_get_softc(sc->jme_miibus); - lwkt_serialize_enter(&sc->jme_serialize); + /* + * jme_stop() stops jme_tick_ch with callout_stop() while holding + * ALL driver serializers (ASSERT_IFNET_SERIALIZED_ALL, if_jme.c, + * entered via ifnet_serialize_all). callout_stop() on this + * kernel synchronously waits (ssleep "costp", + * sys/kern/kern_timeout.c:920) for an in-progress callback, so a + * blocking serializer acquire here can deadlock (AB-BA) against + * jme_stop()'s caller (ifconfig down/MTU/media, jme_init reinit, + * watchdog, jme_detach, jme_suspend). Try-enter instead and + * retry on the next tick; the STOP issued by callout_stop() + * unloads the racing re-arm. + */ + if (!lwkt_serialize_try(&sc->jme_serialize)) { + callout_reset_bycpu(&sc->jme_tick_ch, 1, jme_tick, sc, + JME_TICK_CPUID); + return; + } KKASSERT(mycpuid == JME_TICK_CPUID); |