git: 941113a0097e - main - e1000: fix 82574 MSI-X interrupt throttling
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 25 Jul 2026 21:29:44 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=941113a0097ea047bd493f7f78b384718249779d
commit 941113a0097ea047bd493f7f78b384718249779d
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-07-25 10:43:28 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
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