Module Name:    src
Committed By:   knakahara
Date:           Mon Feb 26 04:19:00 UTC 2018

Modified Files:
        src/sys/dev/pci/ixgbe: ix_txrx.c ixgbe.c ixgbe.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/pci/ixgbe/ix_txrx.c
cvs rdiff -u -r1.126 -r1.127 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/pci/ixgbe/ixgbe.h

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.32 src/sys/dev/pci/ixgbe/ix_txrx.c:1.33
--- src/sys/dev/pci/ixgbe/ix_txrx.c:1.32	Thu Feb 22 10:02:08 2018
+++ src/sys/dev/pci/ixgbe/ix_txrx.c	Mon Feb 26 04:19:00 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.32 2018/02/22 10:02:08 msaitoh Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.33 2018/02/26 04:19:00 knakahara 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.126 src/sys/dev/pci/ixgbe/ixgbe.c:1.127
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.126	Thu Feb 22 10:02:08 2018
+++ src/sys/dev/pci/ixgbe/ixgbe.c	Mon Feb 26 04:19:00 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.126 2018/02/22 10:02:08 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.127 2018/02/26 04:19:00 knakahara 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.30 src/sys/dev/pci/ixgbe/ixgbe.h:1.31
--- src/sys/dev/pci/ixgbe/ixgbe.h:1.30	Thu Feb 22 10:02:08 2018
+++ src/sys/dev/pci/ixgbe/ixgbe.h	Mon Feb 26 04:19:00 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.30 2018/02/22 10:02:08 msaitoh Exp $ */
+/* $NetBSD: ixgbe.h,v 1.31 2018/02/26 04:19:00 knakahara 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;
 };
 
 /*

Reply via email to