DF-4316 / fix.diff
--- a/sys/dev/netif/lge/if_lge.c +++ b/sys/dev/netif/lge/if_lge.c @@ -981,9 +981,21 @@ struct lge_softc *sc = xsc; struct ifnet *ifp = &sc->arpcom.ac_if; - lwkt_serialize_enter(ifp->if_serializer); - lge_tick_serialized(xsc); - lwkt_serialize_exit(ifp->if_serializer); + /* + * Never block on the serializer here: every lge_stop() caller + * (lge_detach, lge_init via ioctl/watchdog/rxeoc, lge_intr, + * lge_ioctl) holds ifp->if_serializer while calling + * callout_stop(&sc->lge_stat_timer), and callout_stop() sleeps + * until an in-progress callback returns. A callback parked in + * lwkt_serialize_enter would deadlock both threads forever. + */ + if (lwkt_serialize_try(ifp->if_serializer)) { + lge_tick_serialized(xsc); + lwkt_serialize_exit(ifp->if_serializer); + } else { + /* Retry on the next tick. */ + callout_reset(&sc->lge_stat_timer, 1, lge_tick, sc); + } } static void |