Module Name: src
Committed By: msaitoh
Date: Mon Aug 24 18:21:59 UTC 2020
Modified Files:
src/sys/dev/pci/ixgbe: ixgbe.c
Log Message:
Fix race in ixgbe_detach() to prevent panic on shutdown.
To generate a diff of this commit:
cvs rdiff -u -r1.240 -r1.241 src/sys/dev/pci/ixgbe/ixgbe.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.240 src/sys/dev/pci/ixgbe/ixgbe.c:1.241
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.240 Mon Aug 24 18:16:04 2020
+++ src/sys/dev/pci/ixgbe/ixgbe.c Mon Aug 24 18:21:59 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.240 2020/08/24 18:16:04 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.241 2020/08/24 18:21:59 msaitoh Exp $ */
/******************************************************************************
@@ -3558,13 +3558,6 @@ ixgbe_detach(device_t dev, int flags)
return (EBUSY);
}
- /*
- * Stop the interface. ixgbe_setup_low_power_mode() calls ixgbe_stop(),
- * so it's not required to call ixgbe_stop() directly.
- */
- IXGBE_CORE_LOCK(adapter);
- ixgbe_setup_low_power_mode(adapter);
- IXGBE_CORE_UNLOCK(adapter);
#if NVLAN > 0
/* Make sure VLANs are not using driver */
if (!VLAN_ATTACHED(&adapter->osdep.ec))
@@ -3577,6 +3570,25 @@ ixgbe_detach(device_t dev, int flags)
}
#endif
+ /*
+ * Stop the interface. ixgbe_setup_low_power_mode() calls ixgbe_stop(),
+ * so it's not required to call ixgbe_stop() directly.
+ */
+ IXGBE_CORE_LOCK(adapter);
+ ixgbe_setup_low_power_mode(adapter);
+ IXGBE_CORE_UNLOCK(adapter);
+
+ callout_halt(&adapter->timer, NULL);
+ if (adapter->feat_en & IXGBE_FEATURE_RECOVERY_MODE) {
+ callout_stop(&adapter->recovery_mode_timer);
+ callout_halt(&adapter->recovery_mode_timer, NULL);
+ }
+
+ workqueue_wait(adapter->admin_wq, &adapter->admin_wc);
+ atomic_store_relaxed(&adapter->admin_pending, 0);
+ workqueue_wait(adapter->timer_wq, &adapter->timer_wc);
+ atomic_store_relaxed(&adapter->timer_pending, 0);
+
pmf_device_deregister(dev);
ether_ifdetach(adapter->ifp);
@@ -3588,12 +3600,6 @@ ixgbe_detach(device_t dev, int flags)
ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext);
- callout_halt(&adapter->timer, NULL);
- if (adapter->feat_en & IXGBE_FEATURE_RECOVERY_MODE) {
- callout_stop(&adapter->recovery_mode_timer);
- callout_halt(&adapter->recovery_mode_timer, NULL);
- }
-
if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
netmap_detach(adapter->ifp);