⬢ DragonFlyBSD Kernel Audit
DF-3760 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/alc/if_alc.c
+++ b/sys/dev/netif/alc/if_alc.c
@@ -3411,7 +3411,20 @@
 	struct ifnet *ifp = &sc->arpcom.ac_if;
 	struct mii_data *mii;
 
-	lwkt_serialize_enter(ifp->if_serializer);
+	/*
+	 * alc_stop() stops alc_tick_ch with callout_stop() while
+	 * holding ifp->if_serializer.  callout_stop() on this kernel
+	 * synchronously waits (ssleep "costp", kern_timeout.c:923) for
+	 * an in-progress callback, so a blocking serializer acquire
+	 * here can deadlock (AB-BA) against alc_stop()'s caller
+	 * (ifconfig down, alc_init reinit, alc_detach, alc_suspend).
+	 * Try-enter instead and retry on the next tick; when alc_stop()
+	 * completes, its STOP unloads the racing re-arm.
+	 */
+	if (!lwkt_serialize_try(ifp->if_serializer)) {
+		callout_reset(&sc->alc_tick_ch, 1, alc_tick, sc);
+		return;
+	}
 
 	mii = device_get_softc(sc->alc_miibus);
 	mii_tick(mii);