⬢ DragonFlyBSD Kernel Audit
DF-3991 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ale/if_ale.c
+++ b/sys/dev/netif/ale/if_ale.c
@@ -2260,7 +2260,19 @@
 	struct ifnet *ifp = &sc->arpcom.ac_if;
 	struct mii_data *mii;
 
-	lwkt_serialize_enter(ifp->if_serializer);
+	/*
+	 * DF-3715 family (DF-3760/3935/3991): ale_stop() tears this
+	 * callout down with the synchronous callout_stop() while holding
+	 * ifp->if_serializer; a callback dequeued and blocked in
+	 * lwkt_serialize_enter() then deadlocks the 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->ale_tick_ch, 1, ale_tick, sc);
+		return;
+	}
 
 	mii = device_get_softc(sc->ale_miibus);
 	mii_tick(mii);