git: 941113a0097e - main - e1000: fix 82574 MSI-X interrupt throttling

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a652ac8.43823.679927a9__1490.78272968239$1785014996$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=941113a0097ea047bd493f7f78b384718249779d

commit 941113a0097ea047bd493f7f78b384718249779d
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-07-25 10:43:28 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-07-25 21:27:51 +0000

    e1000: fix 82574 MSI-X interrupt throttling
    
    em_newitr() and the per-queue interrupt_rate sysctl both tested
    que->msix to decide whether an 82574 is running in MSI-X mode.  0 is a
    valid MSI-X vector so queue 0 was misclassified as legacy/MSI.
    
    Test sc->intr_type == IFLIB_INTR_MSIX instead.  While here, index the tx
    EITR read by tque->msix rather than tque->me so it matches the register
    em_newitr() actually writes; the two differ once tx_num_queues exceeds
    rx_num_queues.
    
    Also seed que->itr_setting in em_initialize_receive_unit() with the rate
    the hardware was just programmed with.  Otherwise an itr_setting left
    over from AIM across an interface re-init makes the change detection in
    em_newitr() suppress the write that would restore it, leaving the
    hardware at the default rate while software believes otherwise.
    
    Fixes:          3e501ef89667 ("e1000: Re-add AIM")
    MFC after:      3 days
---
 sys/dev/e1000/if_em.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 5547c4ec8614..1e54d5ea998d 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1792,7 +1792,8 @@ em_set_next_itr:
 
 		if (newitr != que->itr_setting) {
 			que->itr_setting = newitr;
-			if (hw->mac.type == e1000_82574 && que->msix) {
+			if (hw->mac.type == e1000_82574 &&
+			    sc->intr_type == IFLIB_INTR_MSIX) {
 				E1000_WRITE_REG(hw,
 				    E1000_EITR_82574(que->msix),
 				    que->itr_setting);
@@ -3834,6 +3835,19 @@ em_initialize_receive_unit(if_ctx_t ctx)
 			/* Set the default interrupt throttling rate */
 			E1000_WRITE_REG(hw, E1000_ITR,
 			    EM_INTS_TO_ITR(em_max_interrupt_rate));
+
+			/*
+			 * The 82574 MSI-X EITR registers are programmed
+			 * with the same value further below.  Either way
+			 * the hardware now holds the default rate, so seed
+			 * the software copy to match; otherwise a stale
+			 * itr_setting left over from AIM makes em_newitr()
+			 * skip the write that would restore it.
+			 */
+			for (i = 0, que = sc->rx_queues; i < sc->rx_num_queues;
+			    i++, que++)
+				que->itr_setting =
+				    EM_INTS_TO_ITR(em_max_interrupt_rate);
 		}
 
 		/* XXX TEMPORARY WORKAROUND: on some systems with 82573
@@ -4957,8 +4971,9 @@ em_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS)
 		hw = &tque->sc->hw;
 		if (hw->mac.type >= igb_mac_min)
 			reg = E1000_READ_REG(hw, E1000_EITR(tque->me));
-		else if (hw->mac.type == e1000_82574 && tque->msix)
-			reg = E1000_READ_REG(hw, E1000_EITR_82574(tque->me));
+		else if (hw->mac.type == e1000_82574 &&
+		    tque->sc->intr_type == IFLIB_INTR_MSIX)
+			reg = E1000_READ_REG(hw, E1000_EITR_82574(tque->msix));
 		else
 			reg = E1000_READ_REG(hw, E1000_ITR);
 	} else {
@@ -4966,7 +4981,8 @@ em_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS)
 		hw = &rque->sc->hw;
 		if (hw->mac.type >= igb_mac_min)
 			reg = E1000_READ_REG(hw, E1000_EITR(rque->msix));
-		else if (hw->mac.type == e1000_82574 && rque->msix)
+		else if (hw->mac.type == e1000_82574 &&
+		    rque->sc->intr_type == IFLIB_INTR_MSIX)
 			reg = E1000_READ_REG(hw,
 			    E1000_EITR_82574(rque->msix));
 		else
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.