DF-4064 / fix.diff
diff --git a/sys/dev/netif/fxp/if_fxp.c b/sys/dev/netif/fxp/if_fxp.c --- a/sys/dev/netif/fxp/if_fxp.c +++ b/sys/dev/netif/fxp/if_fxp.c @@ -1446,7 +1446,17 @@ fxp_tick(void *xsc) struct fxp_cb_tx *txp; struct mbuf *m; - lwkt_serialize_enter(sc->arpcom.ac_if.if_serializer); + /* + * Never block on the ifnet serializer from this (non-MPSAFE) + * callout: the callback runs on a softclock thread under the MP + * lock (kern_timeout.c), and every fxp_stop() caller invokes + * callout_stop(&sc->fxp_stat_timer) while already holding the + * serializer. DragonFly's callout_stop() synchronously waits for + * an in-progress callback ('costp', kern_timeout.c:920), so a + * callback parked in lwkt_serialize_enter ('slize', + * lwkt_serialize.c:234) deadlocks against the stopper (AB-BA), + * wedging both threads, the CPU's softclock and the MP lock. + * Retry on the next tick instead (emx_txgc_timer pattern). + */ + if (lwkt_serialize_try(sc->arpcom.ac_if.if_serializer) == 0) { + callout_reset(&sc->fxp_stat_timer, 1, fxp_tick, sc); + return; + } IFNET_STAT_INC(ifp, opackets, sp->tx_good); |