Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

e1000e: Revert "e1000e: Make watchdog use delayed work"

This reverts commit 59653e6497d16f7ac1d9db088f3959f57ee8c3db.

This is due to this commit causing driver crashes and connections to
reset unexpectedly.

Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>

+27 -32
+2 -3
drivers/net/ethernet/intel/e1000e/e1000.h
··· 185 185 186 186 /* board specific private data structure */ 187 187 struct e1000_adapter { 188 + struct timer_list watchdog_timer; 188 189 struct timer_list phy_info_timer; 189 190 struct timer_list blink_timer; 190 191 191 192 struct work_struct reset_task; 192 - struct delayed_work watchdog_task; 193 - 194 - struct workqueue_struct *e1000_workqueue; 193 + struct work_struct watchdog_task; 195 194 196 195 const struct e1000_info *ei; 197 196
+25 -29
drivers/net/ethernet/intel/e1000e/netdev.c
··· 1780 1780 } 1781 1781 /* guard against interrupt when we're going down */ 1782 1782 if (!test_bit(__E1000_DOWN, &adapter->state)) 1783 - mod_delayed_work(adapter->e1000_workqueue, 1784 - &adapter->watchdog_task, HZ); 1783 + mod_timer(&adapter->watchdog_timer, jiffies + 1); 1785 1784 } 1786 1785 1787 1786 /* Reset on uncorrectable ECC error */ ··· 1860 1861 } 1861 1862 /* guard against interrupt when we're going down */ 1862 1863 if (!test_bit(__E1000_DOWN, &adapter->state)) 1863 - mod_delayed_work(adapter->e1000_workqueue, 1864 - &adapter->watchdog_task, HZ); 1864 + mod_timer(&adapter->watchdog_timer, jiffies + 1); 1865 1865 } 1866 1866 1867 1867 /* Reset on uncorrectable ECC error */ ··· 1905 1907 hw->mac.get_link_status = true; 1906 1908 /* guard against interrupt when we're going down */ 1907 1909 if (!test_bit(__E1000_DOWN, &adapter->state)) 1908 - mod_delayed_work(adapter->e1000_workqueue, 1909 - &adapter->watchdog_task, HZ); 1910 + mod_timer(&adapter->watchdog_timer, jiffies + 1); 1910 1911 } 1911 1912 1912 1913 if (!test_bit(__E1000_DOWN, &adapter->state)) ··· 4281 4284 4282 4285 napi_synchronize(&adapter->napi); 4283 4286 4287 + del_timer_sync(&adapter->watchdog_timer); 4284 4288 del_timer_sync(&adapter->phy_info_timer); 4285 4289 4286 4290 spin_lock(&adapter->stats64_lock); ··· 5153 5155 } 5154 5156 } 5155 5157 5158 + /** 5159 + * e1000_watchdog - Timer Call-back 5160 + * @data: pointer to adapter cast into an unsigned long 5161 + **/ 5162 + static void e1000_watchdog(struct timer_list *t) 5163 + { 5164 + struct e1000_adapter *adapter = from_timer(adapter, t, watchdog_timer); 5165 + 5166 + /* Do the rest outside of interrupt context */ 5167 + schedule_work(&adapter->watchdog_task); 5168 + 5169 + /* TODO: make this use queue_delayed_work() */ 5170 + } 5171 + 5156 5172 static void e1000_watchdog_task(struct work_struct *work) 5157 5173 { 5158 5174 struct e1000_adapter *adapter = container_of(work, 5159 5175 struct e1000_adapter, 5160 - watchdog_task.work); 5176 + watchdog_task); 5161 5177 struct net_device *netdev = adapter->netdev; 5162 5178 struct e1000_mac_info *mac = &adapter->hw.mac; 5163 5179 struct e1000_phy_info *phy = &adapter->hw.phy; ··· 5419 5407 5420 5408 /* Reset the timer */ 5421 5409 if (!test_bit(__E1000_DOWN, &adapter->state)) 5422 - queue_delayed_work(adapter->e1000_workqueue, 5423 - &adapter->watchdog_task, 5424 - round_jiffies(2 * HZ)); 5410 + mod_timer(&adapter->watchdog_timer, 5411 + round_jiffies(jiffies + 2 * HZ)); 5425 5412 } 5426 5413 5427 5414 #define E1000_TX_FLAGS_CSUM 0x00000001 ··· 7460 7449 goto err_eeprom; 7461 7450 } 7462 7451 7463 - adapter->e1000_workqueue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, 7464 - e1000e_driver_name); 7465 - 7466 - if (!adapter->e1000_workqueue) { 7467 - err = -ENOMEM; 7468 - goto err_workqueue; 7469 - } 7470 - 7471 - INIT_DELAYED_WORK(&adapter->watchdog_task, e1000_watchdog_task); 7472 - queue_delayed_work(adapter->e1000_workqueue, &adapter->watchdog_task, 7473 - 0); 7474 - 7452 + timer_setup(&adapter->watchdog_timer, e1000_watchdog, 0); 7475 7453 timer_setup(&adapter->phy_info_timer, e1000_update_phy_info, 0); 7476 7454 7477 7455 INIT_WORK(&adapter->reset_task, e1000_reset_task); 7456 + INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); 7478 7457 INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); 7479 7458 INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); 7480 7459 INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang); ··· 7558 7557 return 0; 7559 7558 7560 7559 err_register: 7561 - flush_workqueue(adapter->e1000_workqueue); 7562 - destroy_workqueue(adapter->e1000_workqueue); 7563 - err_workqueue: 7564 7560 if (!(adapter->flags & FLAG_HAS_AMT)) 7565 7561 e1000e_release_hw_control(adapter); 7566 7562 err_eeprom: ··· 7602 7604 * from being rescheduled. 7603 7605 */ 7604 7606 set_bit(__E1000_DOWN, &adapter->state); 7607 + del_timer_sync(&adapter->watchdog_timer); 7605 7608 del_timer_sync(&adapter->phy_info_timer); 7606 7609 7607 7610 cancel_work_sync(&adapter->reset_task); 7611 + cancel_work_sync(&adapter->watchdog_task); 7608 7612 cancel_work_sync(&adapter->downshift_task); 7609 7613 cancel_work_sync(&adapter->update_phy_task); 7610 7614 cancel_work_sync(&adapter->print_hang_task); 7611 - 7612 - cancel_delayed_work(&adapter->watchdog_task); 7613 - flush_workqueue(adapter->e1000_workqueue); 7614 - destroy_workqueue(adapter->e1000_workqueue); 7615 7615 7616 7616 if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) { 7617 7617 cancel_work_sync(&adapter->tx_hwtstamp_work);