Source-Changes-HG archive

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

[src/netbsd-8]: src/sys/dev/pci/ixgbe Pull up following revision(s) (requeste...



details:   https://anonhg.NetBSD.org/src/rev/42d92682d8b7
branches:  netbsd-8
changeset: 851434:42d92682d8b7
user:      martin <martin%NetBSD.org@localhost>
date:      Thu Mar 01 19:02:15 2018 +0000

description:
Pull up following revision(s) (requested by knakahara in ticket #597):
        sys/dev/pci/ixgbe/ixgbe.h: revision 1.31
        sys/dev/pci/ixgbe/ix_txrx.c: revision 1.33
        sys/dev/pci/ixgbe/ixgbe.c: revision 1.127
        sys/dev/pci/ixgbe/ixv.c: revision 1.82
Fix poll mode assumption breaking.
ixgbe_{enable,disable}_intr() forcibly enable/disable all interrupts
regardless of current state. That can break poll mode assumption,
that is, queue interrupts must not occur while polling Tx/Rx rings.
E.g. "ifconfig ixg0 delete && ifconfig ixg0 192.168.0.1" on heavy
load traffic can causes this issue.
This fix may have 1% or 2% performance impact at short packets.
XXX
ixgbe_rearm_queues() which is called only via watchdog can also break
this poll mode assumption because writing EICS casues interrupts
immediately when interrupt auto mask enabled.
We will fix it with other issues about watchdog later.
ok by msaitoh@n.o.
Apply ixgbe.c:r1.127 to ixv.c. Pointed out by msaitoh@n.o.

diffstat:

 sys/dev/pci/ixgbe/ix_txrx.c |   5 ++++-
 sys/dev/pci/ixgbe/ixgbe.c   |  36 ++++++++++++++++++++++++++++--------
 sys/dev/pci/ixgbe/ixgbe.h   |   5 ++++-
 sys/dev/pci/ixgbe/ixv.c     |  30 ++++++++++++++++++++++++++++--
 4 files changed, 64 insertions(+), 12 deletions(-)

diffs (206 lines):

diff -r 94d82d4489ce -r 42d92682d8b7 sys/dev/pci/ixgbe/ix_txrx.c
--- a/sys/dev/pci/ixgbe/ix_txrx.c       Thu Mar 01 17:15:13 2018 +0000
+++ b/sys/dev/pci/ixgbe/ix_txrx.c       Thu Mar 01 19:02:15 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.24.2.4 2018/02/26 13:55:54 martin Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.24.2.5 2018/03/01 19:02:15 martin Exp $ */
 
 /******************************************************************************
 
@@ -2260,6 +2260,9 @@
                que->me = i;
                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;
        }
 
        return (0);
diff -r 94d82d4489ce -r 42d92682d8b7 sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Thu Mar 01 17:15:13 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Thu Mar 01 19:02:15 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.88.2.10 2018/02/26 13:55:54 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.88.2.11 2018/03/01 19:02:15 martin Exp $ */
 
 /******************************************************************************
 
@@ -2384,9 +2384,14 @@
 ixgbe_enable_queue(struct adapter *adapter, u32 vector)
 {
        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 && --que->im_nest > 0)
+               goto out;
+
        if (hw->mac.type == ixgbe_mac_82598EB) {
                mask = (IXGBE_EIMS_RTX_QUEUE & queue);
                IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
@@ -2398,6 +2403,8 @@
                if (mask)
                        IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
        }
+out:
+       mutex_exit(&que->im_mtx);
 } /* ixgbe_enable_queue */
 
 /************************************************************************
@@ -2407,9 +2414,14 @@
 ixgbe_disable_queue(struct adapter *adapter, u32 vector)
 {
        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;
+
        if (hw->mac.type == ixgbe_mac_82598EB) {
                mask = (IXGBE_EIMS_RTX_QUEUE & queue);
                IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask);
@@ -2421,6 +2433,8 @@
                if (mask)
                        IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
        }
+out:
+       mutex_exit(&que->im_mtx);
 } /* ixgbe_disable_queue */
 
 /************************************************************************
@@ -3427,6 +3441,10 @@
 
        ixgbe_free_transmit_structures(adapter);
        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);
+       }
        free(adapter->queues, M_DEVBUF);
        free(adapter->mta, M_DEVBUF);
 
@@ -4568,15 +4586,17 @@
 static void
 ixgbe_disable_intr(struct adapter *adapter)
 {
+       struct ix_queue *que = adapter->queues;
+
+       /* disable interrupts other than queues */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~IXGBE_EIMC_RTX_QUEUE);
+
        if (adapter->msix_mem)
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, 0);
-       if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
-       } else {
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
-       }
+
+       for (int i = 0; i < adapter->num_queues; i++, que++)
+               ixgbe_disable_queue(adapter, que->msix);
+
        IXGBE_WRITE_FLUSH(&adapter->hw);
 
        return;
diff -r 94d82d4489ce -r 42d92682d8b7 sys/dev/pci/ixgbe/ixgbe.h
--- a/sys/dev/pci/ixgbe/ixgbe.h Thu Mar 01 17:15:13 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.h Thu Mar 01 19:02:15 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.24.6.3 2018/02/26 13:55:54 martin Exp $ */
+/* $NetBSD: ixgbe.h,v 1.24.6.4 2018/03/01 19:02:15 martin Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -335,6 +335,9 @@
        struct evcnt     irqs;
        char             namebuf[32];
        char             evnamebuf[32];
+
+       kmutex_t         im_mtx;        /* lock for im_nest and this queue's EIMS/EIMC bit */
+       int              im_nest;
 };
 
 /*
diff -r 94d82d4489ce -r 42d92682d8b7 sys/dev/pci/ixgbe/ixv.c
--- a/sys/dev/pci/ixgbe/ixv.c   Thu Mar 01 17:15:13 2018 +0000
+++ b/sys/dev/pci/ixgbe/ixv.c   Thu Mar 01 19:02:15 2018 +0000
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.56.2.7 2018/02/26 13:55:54 martin Exp $*/
+/*$NetBSD: ixv.c,v 1.56.2.8 2018/03/01 19:02:15 martin Exp $*/
 
 /******************************************************************************
 
@@ -671,6 +671,10 @@
 
        ixgbe_free_transmit_structures(adapter);
        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);
+       }
        free(adapter->queues, M_DEVBUF);
 
        IXGBE_CORE_LOCK_DESTROY(adapter);
@@ -811,22 +815,36 @@
 ixv_enable_queue(struct adapter *adapter, u32 vector)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ix_queue *que = &adapter->queues[vector];
        u32             queue = 1 << vector;
        u32             mask;
 
+       mutex_enter(&que->im_mtx);
+       if (que->im_nest > 0 && --que->im_nest > 0)
+               goto out;
+
        mask = (IXGBE_EIMS_RTX_QUEUE & queue);
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
+out:
+       mutex_exit(&que->im_mtx);
 } /* ixv_enable_queue */
 
 static inline void
 ixv_disable_queue(struct adapter *adapter, u32 vector)
 {
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ix_queue *que = &adapter->queues[vector];
        u64             queue = (u64)(1 << vector);
        u32             mask;
 
+       mutex_enter(&que->im_mtx);
+       if (que->im_nest++ > 0)
+               goto  out;
+
        mask = (IXGBE_EIMS_RTX_QUEUE & queue);
        IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask);
+out:
+       mutex_exit(&que->im_mtx);
 } /* ixv_disable_queue */
 
 static inline void
@@ -1922,8 +1940,16 @@
 static void
 ixv_disable_intr(struct adapter *adapter)
 {
+       struct ix_queue *que = adapter->queues;
+
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0);
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, ~0);
+
+       /* disable interrupts other than queues */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, adapter->vector);
+
+       for (int i = 0; i < adapter->num_queues; i++, que++)
+               ixv_disable_queue(adapter, que->msix);
+
        IXGBE_WRITE_FLUSH(&adapter->hw);
 
        return;



Home | Main Index | Thread Index | Old Index