Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci/ixgbe Fix a panic on shutdown on a machine which...



details:   https://anonhg.NetBSD.org/src/rev/97f1bbaf2c6c
branches:  trunk
changeset: 938072:97f1bbaf2c6c
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Tue Sep 01 04:19:16 2020 +0000

description:
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.

diffstat:

 sys/dev/pci/ixgbe/ixgbe.c       |  14 +++++++++-----
 sys/dev/pci/ixgbe/ixgbe_osdep.h |   3 ++-
 2 files changed, 11 insertions(+), 6 deletions(-)

diffs (59 lines):

diff -r 588db232ab55 -r 97f1bbaf2c6c sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Tue Sep 01 04:06:56 2020 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Tue Sep 01 04:19:16 2020 +0000
@@ -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 @@
        else
                adapter->osdep.dmat = pa->pa_dmat;
        adapter->osdep.attached = false;
+       adapter->osdep.detaching = false;
 
        ent = ixgbe_lookup(pa);
 
@@ -3598,6 +3599,7 @@
        }
 #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 @@
 {
        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);
+               }
        }
 }
 
diff -r 588db232ab55 -r 97f1bbaf2c6c sys/dev/pci/ixgbe/ixgbe_osdep.h
--- a/sys/dev/pci/ixgbe/ixgbe_osdep.h   Tue Sep 01 04:06:56 2020 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_osdep.h   Tue Sep 01 04:19:16 2020 +0000
@@ -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 @@
        int                nintrs;
        void               *ihs[IXG_MAX_NINTR];
        bool               attached;
+       bool               detaching;
 };
 
 /* These routines need struct ixgbe_hw declared */



Home | Main Index | Thread Index | Old Index