Module Name: src Committed By: martin Date: Thu Mar 1 19:02:15 UTC 2018
Modified Files: src/sys/dev/pci/ixgbe [netbsd-8]: ix_txrx.c ixgbe.c ixgbe.h ixv.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.24.2.4 -r1.24.2.5 src/sys/dev/pci/ixgbe/ix_txrx.c cvs rdiff -u -r1.88.2.10 -r1.88.2.11 src/sys/dev/pci/ixgbe/ixgbe.c cvs rdiff -u -r1.24.6.3 -r1.24.6.4 src/sys/dev/pci/ixgbe/ixgbe.h cvs rdiff -u -r1.56.2.7 -r1.56.2.8 src/sys/dev/pci/ixgbe/ixv.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/ix_txrx.c diff -u src/sys/dev/pci/ixgbe/ix_txrx.c:1.24.2.4 src/sys/dev/pci/ixgbe/ix_txrx.c:1.24.2.5 --- src/sys/dev/pci/ixgbe/ix_txrx.c:1.24.2.4 Mon Feb 26 13:55:54 2018 +++ src/sys/dev/pci/ixgbe/ix_txrx.c Thu Mar 1 19:02:15 2018 @@ -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 @@ ixgbe_allocate_queues(struct adapter *ad 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); Index: src/sys/dev/pci/ixgbe/ixgbe.c diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.88.2.10 src/sys/dev/pci/ixgbe/ixgbe.c:1.88.2.11 --- src/sys/dev/pci/ixgbe/ixgbe.c:1.88.2.10 Mon Feb 26 13:55:54 2018 +++ src/sys/dev/pci/ixgbe/ixgbe.c Thu Mar 1 19:02:15 2018 @@ -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 @@ static inline void 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 @@ ixgbe_enable_queue(struct adapter *adapt if (mask) IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); } +out: + mutex_exit(&que->im_mtx); } /* ixgbe_enable_queue */ /************************************************************************ @@ -2407,9 +2414,14 @@ static inline void 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 @@ ixgbe_disable_queue(struct adapter *adap 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_detach(device_t dev, int flags) 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 @@ ixgbe_enable_intr(struct adapter *adapte 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; Index: src/sys/dev/pci/ixgbe/ixgbe.h diff -u src/sys/dev/pci/ixgbe/ixgbe.h:1.24.6.3 src/sys/dev/pci/ixgbe/ixgbe.h:1.24.6.4 --- src/sys/dev/pci/ixgbe/ixgbe.h:1.24.6.3 Mon Feb 26 13:55:54 2018 +++ src/sys/dev/pci/ixgbe/ixgbe.h Thu Mar 1 19:02:15 2018 @@ -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 ix_queue { 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; }; /* Index: src/sys/dev/pci/ixgbe/ixv.c diff -u src/sys/dev/pci/ixgbe/ixv.c:1.56.2.7 src/sys/dev/pci/ixgbe/ixv.c:1.56.2.8 --- src/sys/dev/pci/ixgbe/ixv.c:1.56.2.7 Mon Feb 26 13:55:54 2018 +++ src/sys/dev/pci/ixgbe/ixv.c Thu Mar 1 19:02:15 2018 @@ -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 @@ ixv_detach(device_t dev, int flags) 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 @@ static inline void 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 @@ ixv_enable_intr(struct adapter *adapter) 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;