--- a/sys/dev/netif/age/if_age.c +++ b/sys/dev/netif/age/if_age.c @@ -2188,11 +2188,24 @@ age_rxintr(struct age_softc *sc, int rr_prod) static void age_tick(void *xsc) { struct age_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii = device_get_softc(sc->age_miibus); - lwkt_serialize_enter(ifp->if_serializer); + /* + * DF-3715 family: age_stop() tears this callout down with + * callout_stop() while holding ifp->if_serializer; a callback + * dequeued and blocked in lwkt_serialize_enter() then deadlocks + * the synchronous stopper (AB-BA, wchan 'costp'). Use a + * try-enter and bail (the next tick retries) so the callback + * can always complete and callout_stop() can always return. + */ + if (!lwkt_serialize_try(ifp->if_serializer)) { + callout_reset(&sc->age_tick_ch, 1, age_tick, sc); + return; + } mii_tick(mii); callout_reset(&sc->age_tick_ch, hz, age_tick, sc); lwkt_serialize_exit(ifp->if_serializer); }