diff --git a/kmod/igb_main.c b/kmod/igb_main.c index 2ff170e..79b7c38 100644 --- a/kmod/igb_main.c +++ b/kmod/igb_main.c @@ -1878,6 +1878,15 @@ void igb_down(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 tctl, rctl; int i; + + /* deleting timer and work queue sync + of igb_watchdog task at the begining + to avoid race condition between igb_down + and watchdog - performing required actions + before altering the adapter state and registers + */ + del_timer_sync(&adapter->watchdog_timer); + cancel_work_sync(&adapter->watchdog_task); /* signal that we're down so the interrupt handler does not * reschedule our watchdog timer @@ -1906,8 +1915,7 @@ void igb_down(struct igb_adapter *adapter) igb_irq_disable(adapter); adapter->flags &= ~IGB_FLAG_NEED_LINK_UPDATE; - - del_timer_sync(&adapter->watchdog_timer); + if (adapter->flags & IGB_FLAG_DETECT_BAD_DMA) del_timer_sync(&adapter->dma_err_timer); del_timer_sync(&adapter->phy_info_timer);