⬢ DragonFlyBSD Kernel Audit
DF-4275 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/tx/if_tx.c
+++ b/sys/dev/netif/tx/if_tx.c
@@ -197,7 +197,7 @@ epic_attach(device_t dev)
 	sc = device_get_softc(dev);
 
 	/* Preinitialize softc structure */
 	sc->dev = dev;
-	callout_init(&sc->tx_stat_timer);
+	/* deferred: lock-aided init after ether_ifattach() (see below) */
@@ -266,7 +266,11 @@ epic_attach(device_t dev)
 	/* Attach to OS's managers */
 	ether_ifattach(ifp, sc->sc_macaddr, NULL);
 	ifp->if_hdrlen = sizeof(struct ether_vlan_header);
 
+	/* Lock-aided callout: the callback runs under if_serializer and must
+	 * not take it itself, so callout_stop() (epic_stop) can no longer
+	 * deadlock against a parked callback (DF-3715 family). */
+	callout_init_lk(&sc->tx_stat_timer, ifp->if_serializer);
+
 	ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->irq));
@@ -799,13 +803,8 @@ epic_stats_update(void *xsc)
 	struct mii_data * mii;
 
-	lwkt_serialize_enter(ifp->if_serializer);
-
+	/* serializer held via callout_init_lk(); do not enter it here */
 	mii = device_get_softc(sc->miibus);
 	mii_tick(mii);
 
 	callout_reset(&sc->tx_stat_timer, hz, epic_stats_update, sc);
-
-	lwkt_serialize_exit(ifp->if_serializer);
 }