Module Name: src Committed By: knakahara Date: Fri Mar 30 03:58:20 UTC 2018
Modified Files: src/sys/dev/pci/ixgbe: ix_txrx.c ixgbe.c ixgbe.h ixgbe_api.h ixgbe_common.c ixv.c Log Message: Don't write EIMC directly. It is required to manage with struct ix_queue status. XXX pullup-8 To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.37 src/sys/dev/pci/ixgbe/ix_txrx.c cvs rdiff -u -r1.138 -r1.139 src/sys/dev/pci/ixgbe/ixgbe.c cvs rdiff -u -r1.38 -r1.39 src/sys/dev/pci/ixgbe/ixgbe.h cvs rdiff -u -r1.11 -r1.12 src/sys/dev/pci/ixgbe/ixgbe_api.h cvs rdiff -u -r1.18 -r1.19 src/sys/dev/pci/ixgbe/ixgbe_common.c cvs rdiff -u -r1.89 -r1.90 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.36 src/sys/dev/pci/ixgbe/ix_txrx.c:1.37 --- src/sys/dev/pci/ixgbe/ix_txrx.c:1.36 Thu Mar 15 06:48:51 2018 +++ src/sys/dev/pci/ixgbe/ix_txrx.c Fri Mar 30 03:58:20 2018 @@ -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 @@ ixgbe_allocate_queues(struct adapter *ad 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); Index: src/sys/dev/pci/ixgbe/ixgbe.c diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.138 src/sys/dev/pci/ixgbe/ixgbe.c:1.139 --- src/sys/dev/pci/ixgbe/ixgbe.c:1.138 Fri Mar 30 03:56:38 2018 +++ src/sys/dev/pci/ixgbe/ixgbe.c Fri Mar 30 03:58:20 2018 @@ -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 @@ ixgbe_enable_queue(struct adapter *adapt 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_enable_queue(struct adapter *adapt 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_disable_queue(struct adapter *adap 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_detach(device_t dev, int flags) 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 @@ ixgbe_local_timer1(void *arg) 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(struct adapter *adapte } /* 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_disable_intr(struct adapter *adapt 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 Index: src/sys/dev/pci/ixgbe/ixgbe.h diff -u src/sys/dev/pci/ixgbe/ixgbe.h:1.38 src/sys/dev/pci/ixgbe/ixgbe.h:1.39 --- src/sys/dev/pci/ixgbe/ixgbe.h:1.38 Fri Mar 30 03:56:38 2018 +++ src/sys/dev/pci/ixgbe/ixgbe.h Fri Mar 30 03:58:20 2018 @@ -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 @@ struct ix_queue { 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 + */ }; /* Index: src/sys/dev/pci/ixgbe/ixgbe_api.h diff -u src/sys/dev/pci/ixgbe/ixgbe_api.h:1.11 src/sys/dev/pci/ixgbe/ixgbe_api.h:1.12 --- src/sys/dev/pci/ixgbe/ixgbe_api.h:1.11 Wed Dec 6 04:08:50 2017 +++ src/sys/dev/pci/ixgbe/ixgbe_api.h Fri Mar 30 03:58:20 2018 @@ -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 @@ void ixgbe_enable_rx(struct ixgbe_hw *hw 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_ */ Index: src/sys/dev/pci/ixgbe/ixgbe_common.c diff -u src/sys/dev/pci/ixgbe/ixgbe_common.c:1.18 src/sys/dev/pci/ixgbe/ixgbe_common.c:1.19 --- src/sys/dev/pci/ixgbe/ixgbe_common.c:1.18 Fri Mar 16 07:54:08 2018 +++ src/sys/dev/pci/ixgbe/ixgbe_common.c Fri Mar 30 03:58:20 2018 @@ -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 @@ s32 ixgbe_stop_adapter_generic(struct ix 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); Index: src/sys/dev/pci/ixgbe/ixv.c diff -u src/sys/dev/pci/ixgbe/ixv.c:1.89 src/sys/dev/pci/ixgbe/ixv.c:1.90 --- src/sys/dev/pci/ixgbe/ixv.c:1.89 Tue Mar 20 09:50:33 2018 +++ src/sys/dev/pci/ixgbe/ixv.c Fri Mar 30 03:58:20 2018 @@ -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 @@ ixv_detach(device_t dev, int flags) 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 @@ ixv_enable_queue(struct adapter *adapter 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 @@ ixv_disable_queue(struct adapter *adapte 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