⬢ DragonFlyBSD Kernel Audit
DF-4051 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/nfe/if_nfe.c
+++ b/sys/dev/netif/nfe/if_nfe.c
@@ -2182,9 +2182,20 @@ static void
 nfe_tick(void *arg)
 {
 	struct nfe_softc *sc = arg;
 	struct ifnet *ifp = &sc->arpcom.ac_if;
 	struct mii_data *mii = device_get_softc(sc->sc_miibus);
 
-	lwkt_serialize_enter(ifp->if_serializer);
+	/*
+	 * Never block on the serializer from the callout handler:
+	 * nfe_stop() issues a synchronous callout_stop() while HOLDING
+	 * the serializer (if_nfe.c:1593), so a tick parked inside
+	 * lwkt_serialize_enter deadlocks against it (AB-BA, DF-4051;
+	 * callout_stop sleeps on "costp", kern_timeout.c:920).  Retry
+	 * on the next tick instead.
+	 */
+	if (lwkt_serialize_try(ifp->if_serializer) == 0) {
+		callout_reset(&sc->sc_tick_ch, 1, nfe_tick, sc);
+		return;
+	}
 
 	mii_tick(mii);
 	callout_reset(&sc->sc_tick_ch, hz, nfe_tick, sc);
 
 	lwkt_serialize_exit(ifp->if_serializer);