Module Name:    src
Committed By:   msaitoh
Date:           Tue Sep  1 04:19:16 UTC 2020

Modified Files:
        src/sys/dev/pci/ixgbe: ixgbe.c ixgbe_osdep.h

Log Message:
 Fix a panic on shutdown on a machine which use the recovery mode timer.

 The recovery mode timer is first issued by the callout and it schedule
the workqueue. The workqueue then reschedule the callout. It's hard to
stop both of them without race only with callout_stop() and workqueue_wait.
To solve this problem. add new "detaching" flag and use it.

 The situation is almost the same as schedule_wqs_ok for the local_timer's
callout and workqueue, but the difference is that the local_timer isn't
required to run if the interface is not up. If it's not important to prevent
running timer while !IFF_UP, the flag can be integrated into one.


To generate a diff of this commit:
cvs rdiff -u -r1.253 -r1.254 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/pci/ixgbe/ixgbe_osdep.h

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.253 src/sys/dev/pci/ixgbe/ixgbe.c:1.254
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.253	Tue Sep  1 04:06:56 2020
+++ src/sys/dev/pci/ixgbe/ixgbe.c	Tue Sep  1 04:19:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.253 2020/09/01 04:06:56 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.254 2020/09/01 04:19:16 msaitoh Exp $ */
 
 /******************************************************************************
 
@@ -828,6 +828,7 @@ ixgbe_attach(device_t parent, device_t d
 	else
 		adapter->osdep.dmat = pa->pa_dmat;
 	adapter->osdep.attached = false;
+	adapter->osdep.detaching = false;
 
 	ent = ixgbe_lookup(pa);
 
@@ -3598,6 +3599,7 @@ ixgbe_detach(device_t dev, int flags)
 	}
 #endif
 
+	adapter->osdep.detaching = true;
 	/*
 	 * Stop the interface. ixgbe_setup_low_power_mode() calls
 	 * ixgbe_ifstop(), so it's not required to call ixgbe_ifstop()
@@ -4623,10 +4625,12 @@ ixgbe_recovery_mode_timer(void *arg)
 {
 	struct adapter *adapter = arg;
 
-	if (atomic_cas_uint(&adapter->recovery_mode_timer_pending, 0, 1) == 0)
-	{
-		workqueue_enqueue(adapter->recovery_mode_timer_wq,
-		    &adapter->recovery_mode_timer_wc, NULL);
+	if (__predict_false(adapter->osdep.detaching == false)) {
+		if (atomic_cas_uint(&adapter->recovery_mode_timer_pending,
+			0, 1) == 0) {
+			workqueue_enqueue(adapter->recovery_mode_timer_wq,
+			    &adapter->recovery_mode_timer_wc, NULL);
+		}
 	}
 }
 

Index: src/sys/dev/pci/ixgbe/ixgbe_osdep.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_osdep.h:1.27 src/sys/dev/pci/ixgbe/ixgbe_osdep.h:1.28
--- src/sys/dev/pci/ixgbe/ixgbe_osdep.h:1.27	Thu Jun 25 07:53:02 2020
+++ src/sys/dev/pci/ixgbe/ixgbe_osdep.h	Tue Sep  1 04:19:16 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_osdep.h,v 1.27 2020/06/25 07:53:02 msaitoh Exp $ */
+/* $NetBSD: ixgbe_osdep.h,v 1.28 2020/09/01 04:19:16 msaitoh Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -200,6 +200,7 @@ struct ixgbe_osdep
 	int		   nintrs;
 	void               *ihs[IXG_MAX_NINTR];
 	bool		   attached;
+	bool		   detaching;
 };
 
 /* These routines need struct ixgbe_hw declared */

Reply via email to