From nobody Sun Aug 2 04:22:59 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hCRVr327gz6n5c7 for ; Sun, 02 Aug 2026 04:23:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hCRVq6pVwz49Fw for ; Sun, 02 Aug 2026 04:22:59 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785644580; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=GbOi1rP4rgJH738fq90EiMVCTmNe17Ri2+CJj/qjKXI=; b=k8CU6DKz0Uea+mRbJyrZiZa4Bgl3ZSxpjG+qrDr+T0fyo0+unKfeazHL+w4LD//oQy7+Ch lOLvn+ILfx0AGpbImNJKi4pKxTQXmrjuJy11Jiq2llLEC6nq4aRhgZaE7TsuvPU9h8Yu4L wzBo6IhYuAU1pW16ToZWXdo8UnHUClCVWIaHBfqlMneYMX2M35Q8RqhVpiAyJjZ4PN14CK sqzXsrnSFh++MBHjaYdS5Xq6GtIqlA4iuFEdwqh//HuaRkncCUOhrVfeLBUV5vuPZ+YKgE web4jfNnfl0W8jjO0xyvSlkDqeBgFa3drHFGIzg0+6xbjBW6vI3FmYOB9AUM0w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785644580; a=rsa-sha256; cv=none; b=cKZ82Wim6AI2uMkyvhrRc8qbtJaZGPSVpv+1TLKXG9FUhgRdhyKuYpFo2lklwCOgvr2U/c gMMXVEzked+UxtDIoudL9AU3pfLPCYB5Aqyt9gjegwFbhUhWg2Uf1tjuRQx79H99f4PChm 5GmYk8FpHdkpUVPXSOZJW9oWaoqq44hZeyoNlSvPUYiJTYgArx2ZzqgJRorFQP5AlJnJ7k 40cpUhsHHwTcdZJcNTuJcOj9a8rZftLBRpOKCtXqOfFshhHhd/uxURaHBanaNa60ELMkc+ Lb8onhfLVjvlLlsXRNEnFy+ezBNzTZxG2/Y5L7/wRlaHOCvrYvtuOillNZd+UA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785644580; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=GbOi1rP4rgJH738fq90EiMVCTmNe17Ri2+CJj/qjKXI=; b=GQItsXEzyQbr2zyRnV4pluT4K7ZoqKPZK5UyY+6gQWsjUsR0RJyk3Uf5m3EVaza6G1xmOM 3HfCy9WjIgOvakFbBNPAatElh59SWqR3I62iz8ZGyYMjmcPIksfUDCnOw+YEWNDdKwZvju 3fskvFclwWpDYNtGwrCTE+uLz018OZee0AftDRWwL1/eijdpo6Cnq32CX1OHWvb25VXkft 3LdrPHpLmJwV4wtfFdcFEtTn2RDq+G1UlyQSFPt4Yfa6KDm7EM1MvYuyg3uRKOAQ0TGCXO 8CZuNHBS1K6Tk/B4qHQbv09gOGYCXgzeE6MIzziyyRA+tiL9uITI75lUDhZ6CQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hCRVq5Ln3z1DYx for ; Sun, 02 Aug 2026 04:22:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3a5ef by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 02 Aug 2026 04:22:59 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 5b380c2b183c - stable/15 - e1000: restore packet-size AIM List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 5b380c2b183c915925d08c5535d17e4391251acb Auto-Submitted: auto-generated Date: Sun, 02 Aug 2026 04:22:59 +0000 Message-Id: <6a6ec623.3a5ef.70ab1065@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=5b380c2b183c915925d08c5535d17e4391251acb commit 5b380c2b183c915925d08c5535d17e4391251acb Author: Kevin Bowling AuthorDate: 2026-07-25 23:49:31 +0000 Commit: Kevin Bowling CommitDate: 2026-08-02 04:20:25 +0000 e1000: restore packet-size AIM Restore the packet-size calculation introduced in a69ed8dfb381 and used by igb(4) until the iflib conversion in f2d6ace4a684. It derives interrupt holdoff from average packet size, so RSS queue count does not change its behavior. The calculation follows the pre-iflib code. Retain the current normal and low-latency rate caps, and keep the current setting when an interval has no usable sample. Fixes: 3e501ef89667 ("e1000: Re-add AIM") (cherry picked from commit dc4a5087b160c1a94d135ab636642defe2c71c20) --- sys/dev/e1000/if_em.c | 170 +++++++++++++++++++------------------------------- sys/dev/e1000/if_em.h | 11 +++- 2 files changed, 73 insertions(+), 108 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 28a9ebc39a78..e7fc65ab711e 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1692,12 +1692,60 @@ em_aim_tx_delta(struct tx_ring *txr, u32 *bytes, u32 *packets) txr->tx_packets_last = now_packets; } -enum itr_latency_target { - itr_latency_disabled = 0, - itr_latency_lowest = 1, - itr_latency_low = 2, - itr_latency_bulk = 3 -}; +/********************************************************************* + * + * Do Adaptive Interrupt Moderation: + * - Calculate based on average size over the last interval + * + * Returns interrupts per second rather than a register value, so that the + * caller's EM_INTS_TO_ITR()/IGB_INTS_TO_EITR() conversion applies, or zero + * if the interval carried no packet to measure. + * + *********************************************************************/ +static u32 +em_ring_itr(struct e1000_softc *sc, u32 rxbytes, u32 rxpackets, u32 txbytes, + u32 txpackets) +{ + u32 newitr = 0; + + if (txbytes && txpackets) + newitr = txbytes / txpackets; + if (rxbytes && rxpackets) + newitr = max(newitr, rxbytes / rxpackets); + + /* + * No packet was observed, so there is no size to work from. Report no + * observation and let the caller keep the rate it already has. + */ + if (newitr == 0) + return (0); + + newitr += 24; /* account for hardware frame, crc */ + /* set an upper boundary */ + newitr = min(newitr, 3000); + /* Be nice to the mid range */ + if ((newitr > 300) && (newitr < 1200)) + newitr = (newitr / 3); + else + newitr = (newitr / 2); + + /* The value above was written straight to EITR; make it a rate */ + newitr = EM_AIM_DIVIDEND / newitr; + + /* + * Cap the rate: enable_aim=1 is the normal setting, enable_aim=2 opts + * into the low latency end. The original was unbounded and would ask + * for ~95k ints/s on minimum sized frames. There is deliberately no + * floor, so jumbo traffic settles near 2.7k ints/s. + */ + if (sc->enable_aim == 1) + newitr = min(newitr, EM_INTS_20K); + else + newitr = min(newitr, EM_INTS_70K); + + return (newitr); +} + /********************************************************************* * * Helper to calculate next (E)ITR value for AIM @@ -1709,10 +1757,8 @@ em_newitr(struct e1000_softc *sc, struct em_rx_queue *que, { struct e1000_hw *hw = &sc->hw; struct em_tx_queue *tx_que; - u32 bytes, bytes_per_packet, packets; u32 ringbytes, ringpackets, rxbytes, rxpackets, txbytes, txpackets; u32 newitr; - u8 nextlatency; int i; em_aim_rx_delta(rxr, &rxbytes, &rxpackets); @@ -1736,108 +1782,22 @@ em_newitr(struct e1000_softc *sc, struct em_rx_queue *que, if (txbytes == 0 && rxbytes == 0) return; - newitr = 0; - - if (sc->enable_aim) { - nextlatency = rxr->rx_nextlatency; - + if (sc->enable_aim == 0) { + newitr = em_max_interrupt_rate; + } else if (sc->link_speed < SPEED_1000) { /* Use half default (4K) ITR if sub-gig */ - if (sc->link_speed < SPEED_1000) { - newitr = EM_INTS_4K; - goto em_set_next_itr; - } - /* Want at least enough packet buffer for two frames to AIM */ - if (sc->shared->isc_max_frame_size * 2 > (sc->pba << 10)) { - newitr = em_max_interrupt_rate; - goto em_set_next_itr; - } - - bytes = bytes_per_packet = packets = 0; - /* Get largest values from the associated tx and rx ring */ - if (txpackets != 0) { - bytes = txbytes; - bytes_per_packet = txbytes / txpackets; - packets = txpackets; - } - if (rxpackets != 0) { - bytes = lmax(bytes, rxbytes); - bytes_per_packet = - lmax(bytes_per_packet, rxbytes / rxpackets); - packets = lmax(packets, rxpackets); - } - - /* Latency state machine */ - switch (nextlatency) { - case itr_latency_disabled: /* Bootstrapping */ - nextlatency = itr_latency_low; - break; - case itr_latency_lowest: /* 70k ints/s */ - /* TSO and jumbo frames */ - if (bytes_per_packet > 8000) - nextlatency = itr_latency_bulk; - else if ((packets < 5) && (bytes > 512)) - nextlatency = itr_latency_low; - break; - case itr_latency_low: /* 20k ints/s */ - if (bytes > 10000) { - /* Handle TSO */ - if (bytes_per_packet > 8000) - nextlatency = itr_latency_bulk; - else if ((packets < 10) || - (bytes_per_packet > 1200)) - nextlatency = itr_latency_bulk; - else if (packets > 35) - nextlatency = itr_latency_lowest; - } else if (bytes_per_packet > 2000) { - nextlatency = itr_latency_bulk; - } else if (packets < 3 && bytes < 512) { - nextlatency = itr_latency_lowest; - } - break; - case itr_latency_bulk: /* 4k ints/s */ - if (bytes > 25000) { - if (packets > 35) - nextlatency = itr_latency_low; - } else if (bytes < 1500) - nextlatency = itr_latency_low; - break; - default: - nextlatency = itr_latency_low; - device_printf(sc->dev, - "Unexpected newitr transition %d\n", nextlatency); - break; - } - - /* Trim itr_latency_lowest for default AIM setting */ - if (sc->enable_aim == 1 && nextlatency == itr_latency_lowest) - nextlatency = itr_latency_low; - - /* Request new latency */ - rxr->rx_nextlatency = nextlatency; - } else { - /* We may have toggled to AIM disabled */ - nextlatency = itr_latency_disabled; - rxr->rx_nextlatency = nextlatency; - } - - /* ITR state machine */ - switch(nextlatency) { - case itr_latency_lowest: - newitr = EM_INTS_70K; - break; - case itr_latency_low: - newitr = EM_INTS_20K; - break; - case itr_latency_bulk: newitr = EM_INTS_4K; - break; - case itr_latency_disabled: - default: + } else if (sc->shared->isc_max_frame_size * 2 > (sc->pba << 10)) { + /* Want at least enough packet buffer for two frames to AIM */ newitr = em_max_interrupt_rate; - break; + } else { + newitr = em_ring_itr(sc, rxbytes, rxpackets, txbytes, + txpackets); + /* No usable observation; leave the rate where it is */ + if (newitr == 0) + return; } -em_set_next_itr: if (hw->mac.type >= igb_mac_min) { newitr = IGB_INTS_TO_EITR(newitr); diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index 47e71c35d078..c7ebad7adaab 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -260,6 +260,14 @@ #define IGB_EITR_TO_INTS(i) ((IGB_EITR_DIVIDEND << IGB_EITR_SHIFT) / \ ((i) & IGB_QVECTOR_MASK)) +/* + * The average packet size calculation in em_ring_itr() yields an EITR + * interval field value. That field is quarter microsecond granular (see + * IGB_EITR_SHIFT), so an interval of V is 1000000 / (V / 4) interrupts per + * second. + */ +#define EM_AIM_DIVIDEND (IGB_EITR_DIVIDEND << IGB_EITR_SHIFT) + #define IGB_LINK_ITR 2000 #define I210_LINK_DELAY 1000 @@ -478,9 +486,6 @@ struct rx_ring { uint64_t rx_aim_snapshot __aligned(8); u32 rx_packets_last; u32 rx_bytes_last; - - /* Next requested ITR latency */ - u8 rx_nextlatency; }; static __inline void