DF-3715 / fix.diff
--- a/sys/dev/netif/em/if_em.c 2026-09-15 21:39:34.188447660 +0000 +++ b/sys/dev/netif/em/if_em.c 2026-09-15 21:40:02.404089946 +0000 @@ -2030,9 +2030,17 @@ struct adapter *adapter = xsc; struct ifnet *ifp = &adapter->arpcom.ac_if; - lwkt_serialize_enter(ifp->if_serializer); - em_82547_move_tail_serialized(adapter); - lwkt_serialize_exit(ifp->if_serializer); + /* + * Non-blocking, see em_timer(): em_stop() calls + * callout_stop(&adapter->tx_fifo_timer) under the serializer. + */ + if (lwkt_serialize_try(ifp->if_serializer)) { + em_82547_move_tail_serialized(adapter); + lwkt_serialize_exit(ifp->if_serializer); + } else { + callout_reset(&adapter->tx_fifo_timer, 1, + em_82547_move_tail, adapter); + } } static int @@ -2219,23 +2227,33 @@ struct adapter *adapter = xsc; struct ifnet *ifp = &adapter->arpcom.ac_if; - lwkt_serialize_enter(ifp->if_serializer); - - em_update_link_status(adapter); - em_update_stats(adapter); + /* + * Never block on the serializer here. em_stop() tears this + * callout down with callout_stop() while holding the same + * serializer, and callout_stop() synchronously waits for an + * in-progress callback (kern_timeout.c "costp" wait). A + * callback blocked in lwkt_serialize_enter() therefore + * deadlocks the softclock thread against the serializer + * holder (AB-BA). Use try-enter and retry on the next tick, + * like em_txgc_timer(). + */ + if (lwkt_serialize_try(ifp->if_serializer)) { + em_update_link_status(adapter); + em_update_stats(adapter); + + /* Reset LAA into RAR[0] on 82571 */ + if (e1000_get_laa_state_82571(&adapter->hw) == TRUE) + e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); - /* Reset LAA into RAR[0] on 82571 */ - if (e1000_get_laa_state_82571(&adapter->hw) == TRUE) - e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); + if (em_display_debug_stats && (ifp->if_flags & IFF_RUNNING)) + em_print_hw_stats(adapter); - if (em_display_debug_stats && (ifp->if_flags & IFF_RUNNING)) - em_print_hw_stats(adapter); - - em_smartspeed(adapter); + em_smartspeed(adapter); + lwkt_serialize_exit(ifp->if_serializer); + } callout_reset(&adapter->timer, hz, em_timer, adapter); - lwkt_serialize_exit(ifp->if_serializer); } static void |