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

Reply via email to