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 Don't write EIMC directly. It is required ...



details:   https://anonhg.NetBSD.org/src/rev/3484619f2fa0
branches:  trunk
changeset: 321655:3484619f2fa0
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Fri Mar 30 03:58:20 2018 +0000

description:
Don't write EIMC directly. It is required to manage with struct ix_queue status.

XXX pullup-8

diffstat:

 sys/dev/pci/ixgbe/ix_txrx.c      |   6 +-
 sys/dev/pci/ixgbe/ixgbe.c        |  69 ++++++++++++++++++++++++++++++---------
 sys/dev/pci/ixgbe/ixgbe.h        |  11 ++++-
 sys/dev/pci/ixgbe/ixgbe_api.h    |   4 +-
 sys/dev/pci/ixgbe/ixgbe_common.c |  24 ++++++++++++-
 sys/dev/pci/ixgbe/ixv.c          |  16 ++++----
 6 files changed, 96 insertions(+), 34 deletions(-)

diffs (299 lines):

diff -r decfe5ec1057 -r 3484619f2fa0 sys/dev/pci/ixgbe/ix_txrx.c
--- a/sys/dev/pci/ixgbe/ix_txrx.c       Fri Mar 30 03:56:38 2018 +0000
+++ b/sys/dev/pci/ixgbe/ix_txrx.c       Fri Mar 30 03:58:20 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.36 2018/03/15 06:48:51 msaitoh Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.37 2018/03/30 03:58:20 knakahara Exp $ */
 
 /******************************************************************************
 
@@ -2298,8 +2298,8 @@
                que->txr = &adapter->tx_rings[i];
                que->rxr = &adapter->rx_rings[i];
 
-               mutex_init(&que->im_mtx, MUTEX_DEFAULT, IPL_NET);
-               que->im_nest = 0;
+               mutex_init(&que->dc_mtx, MUTEX_DEFAULT, IPL_NET);
+               que->disabled_count = 0;
        }
 
        return (0);
diff -r decfe5ec1057 -r 3484619f2fa0 sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Fri Mar 30 03:56:38 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Fri Mar 30 03:58:20 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.138 2018/03/30 03:56:38 knakahara Exp $ */
+/* $NetBSD: ixgbe.c,v 1.139 2018/03/30 03:58:20 knakahara Exp $ */
 
 /******************************************************************************
 
@@ -2410,8 +2410,8 @@
        u64             queue = (u64)(1ULL << vector);
        u32             mask;
 
-       mutex_enter(&que->im_mtx);
-       if (que->im_nest > 0 && --que->im_nest > 0)
+       mutex_enter(&que->dc_mtx);
+       if (que->disabled_count > 0 && --que->disabled_count > 0)
                goto out;
 
        if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -2426,23 +2426,28 @@
                        IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
        }
 out:
-       mutex_exit(&que->im_mtx);
+       mutex_exit(&que->dc_mtx);
 } /* ixgbe_enable_queue */
 
 /************************************************************************
- * ixgbe_disable_queue
+ * ixgbe_disable_queue_internal
  ************************************************************************/
 static inline void
-ixgbe_disable_queue(struct adapter *adapter, u32 vector)
+ixgbe_disable_queue_internal(struct adapter *adapter, u32 vector, bool nestok)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        struct ix_queue *que = &adapter->queues[vector];
        u64             queue = (u64)(1ULL << vector);
        u32             mask;
 
-       mutex_enter(&que->im_mtx);
-       if (que->im_nest++ > 0)
-               goto  out;
+       mutex_enter(&que->dc_mtx);
+
+       if (que->disabled_count > 0) {
+               if (nestok)
+                       que->disabled_count++;
+               goto out;
+       }
+       que->disabled_count++;
 
        if (hw->mac.type == ixgbe_mac_82598EB) {
                mask = (IXGBE_EIMS_RTX_QUEUE & queue);
@@ -2456,7 +2461,17 @@
                        IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
        }
 out:
-       mutex_exit(&que->im_mtx);
+       mutex_exit(&que->dc_mtx);
+} /* ixgbe_disable_queue_internal */
+
+/************************************************************************
+ * ixgbe_disable_queue
+ ************************************************************************/
+static inline void
+ixgbe_disable_queue(struct adapter *adapter, u32 vector)
+{
+
+       ixgbe_disable_queue_internal(adapter, vector, true);
 } /* ixgbe_disable_queue */
 
 /************************************************************************
@@ -3511,7 +3526,7 @@
        ixgbe_free_receive_structures(adapter);
        for (int i = 0; i < adapter->num_queues; i++) {
                struct ix_queue * que = &adapter->queues[i];
-               mutex_destroy(&que->im_mtx);
+               mutex_destroy(&que->dc_mtx);
        }
        free(adapter->queues, M_DEVBUF);
        free(adapter->mta, M_DEVBUF);
@@ -4295,11 +4310,11 @@
        else if (queues != 0) { /* Force an IRQ on queues with work */
                que = adapter->queues;
                for (i = 0; i < adapter->num_queues; i++, que++) {
-                       mutex_enter(&que->im_mtx);
-                       if (que->im_nest == 0)
+                       mutex_enter(&que->dc_mtx);
+                       if (que->disabled_count == 0)
                                ixgbe_rearm_queues(adapter,
                                    queues & ((u64)1 << i));
-                       mutex_exit(&que->im_mtx);
+                       mutex_exit(&que->dc_mtx);
                }
        }
 
@@ -4697,10 +4712,10 @@
 } /* ixgbe_enable_intr */
 
 /************************************************************************
- * ixgbe_disable_intr
+ * ixgbe_disable_intr_internal
  ************************************************************************/
 static void
-ixgbe_disable_intr(struct adapter *adapter)
+ixgbe_disable_intr_internal(struct adapter *adapter, bool nestok)
 {
        struct ix_queue *que = adapter->queues;
 
@@ -4711,13 +4726,33 @@
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, 0);
 
        for (int i = 0; i < adapter->num_queues; i++, que++)
-               ixgbe_disable_queue(adapter, que->msix);
+               ixgbe_disable_queue_internal(adapter, que->msix, nestok);
 
        IXGBE_WRITE_FLUSH(&adapter->hw);
 
+} /* ixgbe_do_disable_intr_internal */
+
+/************************************************************************
+ * ixgbe_disable_intr
+ ************************************************************************/
+static void
+ixgbe_disable_intr(struct adapter *adapter)
+{
+
+       ixgbe_disable_intr_internal(adapter, true);
 } /* ixgbe_disable_intr */
 
 /************************************************************************
+ * ixgbe_ensure_disabled_intr
+ ************************************************************************/
+void
+ixgbe_ensure_disabled_intr(struct adapter *adapter)
+{
+
+       ixgbe_disable_intr_internal(adapter, false);
+} /* ixgbe_ensure_disabled_intr */
+
+/************************************************************************
  * ixgbe_legacy_irq - Legacy Interrupt Service routine
  ************************************************************************/
 static int
diff -r decfe5ec1057 -r 3484619f2fa0 sys/dev/pci/ixgbe/ixgbe.h
--- a/sys/dev/pci/ixgbe/ixgbe.h Fri Mar 30 03:56:38 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.h Fri Mar 30 03:58:20 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.38 2018/03/30 03:56:38 knakahara Exp $ */
+/* $NetBSD: ixgbe.h,v 1.39 2018/03/30 03:58:20 knakahara Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -339,8 +339,13 @@
        char             namebuf[32];
        char             evnamebuf[32];
 
-       kmutex_t         im_mtx;        /* lock for im_nest and this queue's EIMS/EIMC bit */
-       int              im_nest;
+       kmutex_t         dc_mtx;        /* lock for disabled_count and this queue's EIMS/EIMC bit */
+       int              disabled_count;/*
+                                        * means
+                                        *     0   : this queue is enabled
+                                        *     > 0 : this queue is disabled
+                                        *           the value is ixgbe_disable_queue() called count
+                                        */
 };
 
 /*
diff -r decfe5ec1057 -r 3484619f2fa0 sys/dev/pci/ixgbe/ixgbe_api.h
--- a/sys/dev/pci/ixgbe/ixgbe_api.h     Fri Mar 30 03:56:38 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_api.h     Fri Mar 30 03:58:20 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_api.h,v 1.11 2017/12/06 04:08:50 msaitoh Exp $ */
+/* $NetBSD: ixgbe_api.h,v 1.12 2018/03/30 03:58:20 knakahara Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -227,4 +227,6 @@
 s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
                        u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
 
+void ixgbe_ensure_disabled_intr(struct adapter *);
+
 #endif /* _IXGBE_API_H_ */
diff -r decfe5ec1057 -r 3484619f2fa0 sys/dev/pci/ixgbe/ixgbe_common.c
--- a/sys/dev/pci/ixgbe/ixgbe_common.c  Fri Mar 30 03:56:38 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_common.c  Fri Mar 30 03:58:20 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_common.c,v 1.18 2018/03/16 07:54:08 msaitoh Exp $ */
+/* $NetBSD: ixgbe_common.c,v 1.19 2018/03/30 03:58:20 knakahara Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -1130,7 +1130,27 @@
        ixgbe_disable_rx(hw);
 
        /* Clear interrupt mask to stop interrupts from being generated */
-       IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
+       /*
+        * XXX
+        * This function is called in the state of both interrupt disabled
+        * and interrupt enabled, e.g.
+        * + interrupt disabled case:
+        *   - ixgbe_stop()
+        *     - ixgbe_disable_intr() // interrupt disabled here
+        *     - ixgbe_stop_adapter()
+        *       - hw->mac.ops.stop_adapter()
+        *         == this function
+        * + interrupt enabled case:
+        *   - ixgbe_local_timer1()
+        *     - ixgbe_init_locked()
+        *       - ixgbe_stop_adapter()
+        *         - hw->mac.ops.stop_adapter()
+        *           == this function
+        * Therefore, it causes nest status breaking to nest the status
+        * (that is, que->im_nest++) at all times. So, this function must
+        * use ixgbe_ensure_disabled_intr() instead of ixgbe_disable_intr().
+        */
+       ixgbe_ensure_disabled_intr(hw->back);
 
        /* Clear any pending interrupts, flush previous writes */
        IXGBE_READ_REG(hw, IXGBE_EICR);
diff -r decfe5ec1057 -r 3484619f2fa0 sys/dev/pci/ixgbe/ixv.c
--- a/sys/dev/pci/ixgbe/ixv.c   Fri Mar 30 03:56:38 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixv.c   Fri Mar 30 03:58:20 2018 +0000
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.89 2018/03/20 09:50:33 knakahara Exp $*/
+/*$NetBSD: ixv.c,v 1.90 2018/03/30 03:58:20 knakahara Exp $*/
 
 /******************************************************************************
 
@@ -694,7 +694,7 @@
        ixgbe_free_receive_structures(adapter);
        for (int i = 0; i < adapter->num_queues; i++) {
                struct ix_queue *lque = &adapter->queues[i];
-               mutex_destroy(&lque->im_mtx);
+               mutex_destroy(&lque->dc_mtx);
        }
        free(adapter->queues, M_DEVBUF);
 
@@ -839,14 +839,14 @@
        u32             queue = 1 << vector;
        u32             mask;
 
-       mutex_enter(&que->im_mtx);
-       if (que->im_nest > 0 && --que->im_nest > 0)
+       mutex_enter(&que->dc_mtx);
+       if (que->disabled_count > 0 && --que->disabled_count > 0)
                goto out;
 
        mask = (IXGBE_EIMS_RTX_QUEUE & queue);
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
 out:
-       mutex_exit(&que->im_mtx);
+       mutex_exit(&que->dc_mtx);
 } /* ixv_enable_queue */
 
 /************************************************************************
@@ -860,14 +860,14 @@
        u64             queue = (u64)(1 << vector);
        u32             mask;
 
-       mutex_enter(&que->im_mtx);
-       if (que->im_nest++ > 0)
+       mutex_enter(&que->dc_mtx);
+       if (que->disabled_count++ > 0)
                goto  out;
 
        mask = (IXGBE_EIMS_RTX_QUEUE & queue);
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask);
 out:
-       mutex_exit(&que->im_mtx);
+       mutex_exit(&que->dc_mtx);
 } /* ixv_disable_queue */
 
 static inline void



Home | Main Index | Thread Index | Old Index