⬢ DragonFlyBSD Kernel Audit
DF-4025 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/re/if_re.c
+++ b/sys/dev/netif/re/if_re.c
@@ -1355,9 +1355,19 @@
 {
 	struct re_softc *sc = xsc;
 
-	lwkt_serialize_enter(sc->arpcom.ac_if.if_serializer);
-	re_tick_serialized(xsc);
-	lwkt_serialize_exit(sc->arpcom.ac_if.if_serializer);
+	/*
+	 * Do NOT block here.  re_stop() calls callout_stop() while
+	 * holding if_serializer; a callback parked in a blocking
+	 * lwkt_serialize_enter() deadlocks against it (AB-BA).
+	 * If the serializer is busy (e.g. someone is stopping the
+	 * adapter) simply retry on the next tick.
+	 */
+	if (lwkt_serialize_try(sc->arpcom.ac_if.if_serializer)) {
+		re_tick_serialized(xsc);
+		lwkt_serialize_exit(sc->arpcom.ac_if.if_serializer);
+	} else {
+		callout_reset(&sc->re_timer, 1, re_tick, sc);
+	}
 }
 
 static void