--- a/sys/dev/netif/igb/if_igb.c +++ b/sys/dev/netif/igb/if_igb.c @@ -743,6 +743,7 @@ igb_detach(device_t dev) { struct igb_softc *sc = device_get_softc(dev); + int i; if (device_is_attached(dev)) { struct ifnet *ifp = &sc->arpcom.ac_if; @@ -762,6 +763,19 @@ ifnet_deserialize_all(ifp); + /* + * igb_timer() and igb_txgc_timer() self-rearm, and + * callout_stop() (see igb_stop()) does not interlock + * against a callback that is already in progress; a + * blocked igb_timer() resumes once the serializers are + * released above and would rearm into freed memory. + * Terminate both callout classes before the rings and + * softc go away. + */ + callout_terminate(&sc->timer); + for (i = 0; i < sc->tx_ring_cnt; ++i) + callout_terminate(&sc->tx_rings[i].tx_gc_timer); + ether_ifdetach(ifp); } else if (sc->mem_res != NULL) { igb_rel_hw_control(sc);