From nobody Sun Aug 2 04:27:41 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 4hCRcF3gKWz6n6Hv for ; Sun, 02 Aug 2026 04:27:41 +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 4hCRcF1fkFz4FX7 for ; Sun, 02 Aug 2026 04:27:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785644861; 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=+X4SwtQ3r6g4mOuj6YLm4Bq7jkzVVY6IWDobL3sX2Ss=; b=E4sKRStixKsN6EYVHTwf/z7+CXyhqcqL9lnAOhvxgfRp2g2zECVLDyqcQrO5pCjzPUAvur N7cCff9BQAjCiAKDD6r9eq+CVWtVX2cXs/Q9hZ/8jLhaycWKBoWfw99HPwJDiR0w6W3Oux p4zojUGF+old1aJC0tXv7JIxh2hQ4ZWHpqdKA3VdlCA8hraDUiPGwSf7kVMDwEHaZ1+JHU oZ0bPxcv/x2P7Ynqur18BTmH7vjt6dqT+CJEZq5RFfF/rPeXz6MOiYI5H8+5cJQqQnAjdN XRLzoQPnopZYri1bFGMK11wBLL5zDG6SOnQwzFYn1EgP4INh1gUojTbwVwLPcA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785644861; a=rsa-sha256; cv=none; b=r1ymu19MIHKhu3RzH2DqZbi8+6b/dHPgVUezpXZaFsKaWzooDx7tQqHF/CB/tMns6c+TuI rl8T/3WsNof1YTgpzTtz1QrsdIEoEZrcCE2lx4g1zmZ9oWxuZ6F64rQewM+Z7erEoH4Qd2 Osg4IEDuXP/F1grZUmzSZhOdCoIILI0Q1r5wTWx+6MuyC57hVkBPR+jw9v0ObhRMkPxdOM aKOaj5lDxdPUGb3Bgb1B01MKGi2IDh5V1+m3KbO1NXEa88SkHLn7XmNDetUOr+8AFK9X09 an1/SnKeIokqHgnnSjJqNx/YyCbDoWNbuU7GxKEPt05WmNT6/G/zAat/hFWevA== 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=1785644861; 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=+X4SwtQ3r6g4mOuj6YLm4Bq7jkzVVY6IWDobL3sX2Ss=; b=jaf8Xvobi4/v5pCyjBWIKujNxweAw+pgDMK5RZArV2RgLVpIEdkzkhX5IVmoR+hcf7AG3q P92EGb0DTat3vMG/mv29qkBe4ETAbU2VBxCR1c+Fi4WZwylDmu9gIiZlrPRuZS17JNTtuQ f6PE9cZjdLm2nAVkjuRxbODZbDvma8zT81ar917ZM0pU71qfMqUt7O7ifDqRPpo4cqBPR9 wiSlskMMH7OMVG51JZpsvIJNAceX8+8wEZvpPH3Q4kdW6YUFwjtWU5qMCiKCVohfo+NQ+3 9DVY0MJFNn/Kv21w/fQuV0+KdbhJRFl0BQLQ/7ZfmfoH6pRZqka8nULNnz76mQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hCRcF0jMdz1DcH for ; Sun, 02 Aug 2026 04:27:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3bb4f by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 02 Aug 2026 04:27:41 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 010ed395bf5b - stable/14 - igc: use 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/14 X-Git-Reftype: branch X-Git-Commit: 010ed395bf5b7bd246ed3e7200c3fc15afd413a4 Auto-Submitted: auto-generated Date: Sun, 02 Aug 2026 04:27:41 +0000 Message-Id: <6a6ec73d.3bb4f.1b5db01f@gitrepo.freebsd.org> The branch stable/14 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=010ed395bf5b7bd246ed3e7200c3fc15afd413a4 commit 010ed395bf5b7bd246ed3e7200c3fc15afd413a4 Author: Kevin Bowling AuthorDate: 2026-07-26 00:00:22 +0000 Commit: Kevin Bowling CommitDate: 2026-08-02 04:26:57 +0000 igc: use packet-size AIM Use the packet-size calculation introduced for igb(4) in a69ed8dfb381 and retained there 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 igb code. Retain igc's normal and low-latency rate caps, and keep the current setting when an interval has no usable sample. (cherry picked from commit 01e7acd38d411c78caba1c4078bb3683f586e1c2) --- sys/dev/igc/if_igc.c | 171 ++++++++++++++++++++------------------------------- sys/dev/igc/if_igc.h | 11 +++- 2 files changed, 73 insertions(+), 109 deletions(-) diff --git a/sys/dev/igc/if_igc.c b/sys/dev/igc/if_igc.c index a5d3965a739a..df82d5a4e073 100644 --- a/sys/dev/igc/if_igc.c +++ b/sys/dev/igc/if_igc.c @@ -943,12 +943,60 @@ igc_aim_tx_delta(struct tx_ring *txr, u32 *bytes, u32 *packets) txr->tx_packets_last = now_packets; } -enum eitr_latency_target { - eitr_latency_disabled = 0, - eitr_latency_lowest = 1, - eitr_latency_low = 2, - eitr_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 IGC_INTS_TO_EITR() conversion applies, or zero if the interval + * carried no packet to measure. + * + *********************************************************************/ +static u32 +igc_ring_itr(struct igc_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 = IGC_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, IGC_INTS_20K); + else + newitr = min(newitr, IGC_INTS_70K); + + return (newitr); +} + /********************************************************************* * * Helper to calculate next EITR value for AIM @@ -960,10 +1008,8 @@ igc_neweitr(struct igc_softc *sc, struct igc_rx_queue *que, { struct igc_hw *hw = &sc->hw; struct igc_tx_queue *tx_que; - u32 bytes, bytes_per_packet, packets; u32 ringbytes, ringpackets, rxbytes, rxpackets, txbytes, txpackets; u32 neweitr; - u8 nextlatency; int i; igc_aim_rx_delta(rxr, &rxbytes, &rxpackets); @@ -987,109 +1033,22 @@ igc_neweitr(struct igc_softc *sc, struct igc_rx_queue *que, if (txbytes == 0 && rxbytes == 0) return; - neweitr = 0; - - if (sc->enable_aim) { - nextlatency = rxr->rx_nextlatency; - + if (sc->enable_aim == 0) { + neweitr = igc_max_interrupt_rate; + } else if (sc->link_speed < SPEED_1000) { /* Use half default (4K) ITR if sub-gig */ - if (sc->link_speed < 1000) { - neweitr = IGC_INTS_4K; - goto igc_set_next_eitr; - } - /* Want at least enough packet buffer for two frames to AIM */ - if (sc->shared->isc_max_frame_size * 2 > (sc->pba << 10)) { - neweitr = igc_max_interrupt_rate; - goto igc_set_next_eitr; - } - - 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 eitr_latency_disabled: /* Bootstrapping */ - nextlatency = eitr_latency_low; - break; - case eitr_latency_lowest: /* 70k ints/s */ - /* TSO and jumbo frames */ - if (bytes_per_packet > 8000) - nextlatency = eitr_latency_bulk; - else if ((packets < 5) && (bytes > 512)) - nextlatency = eitr_latency_low; - break; - case eitr_latency_low: /* 20k ints/s */ - if (bytes > 10000) { - /* Handle TSO */ - if (bytes_per_packet > 8000) - nextlatency = eitr_latency_bulk; - else if ((packets < 10) || - (bytes_per_packet > 1200)) - nextlatency = eitr_latency_bulk; - else if (packets > 35) - nextlatency = eitr_latency_lowest; - } else if (bytes_per_packet > 2000) { - nextlatency = eitr_latency_bulk; - } else if (packets < 3 && bytes < 512) { - nextlatency = eitr_latency_lowest; - } - break; - case eitr_latency_bulk: /* 4k ints/s */ - if (bytes > 25000) { - if (packets > 35) - nextlatency = eitr_latency_low; - } else if (bytes < 1500) - nextlatency = eitr_latency_low; - break; - default: - nextlatency = eitr_latency_low; - device_printf(sc->dev, - "Unexpected neweitr transition %d\n", - nextlatency); - break; - } - - /* Trim itr_latency_lowest for default AIM setting */ - if (sc->enable_aim == 1 && nextlatency == eitr_latency_lowest) - nextlatency = eitr_latency_low; - - /* Request new latency */ - rxr->rx_nextlatency = nextlatency; - } else { - /* We may have toggled to AIM disabled */ - nextlatency = eitr_latency_disabled; - rxr->rx_nextlatency = nextlatency; - } - - /* ITR state machine */ - switch(nextlatency) { - case eitr_latency_lowest: - neweitr = IGC_INTS_70K; - break; - case eitr_latency_low: - neweitr = IGC_INTS_20K; - break; - case eitr_latency_bulk: neweitr = IGC_INTS_4K; - break; - case eitr_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 */ neweitr = igc_max_interrupt_rate; - break; + } else { + neweitr = igc_ring_itr(sc, rxbytes, rxpackets, txbytes, + txpackets); + /* No usable observation; leave the rate where it is */ + if (neweitr == 0) + return; } -igc_set_next_eitr: neweitr = IGC_INTS_TO_EITR(neweitr); neweitr |= IGC_EITR_CNT_IGNR; diff --git a/sys/dev/igc/if_igc.h b/sys/dev/igc/if_igc.h index 4af08e03fedb..a090eeb12247 100644 --- a/sys/dev/igc/if_igc.h +++ b/sys/dev/igc/if_igc.h @@ -176,6 +176,14 @@ #define IGC_EITR_TO_INTS(i) ((IGC_EITR_DIVIDEND << IGC_EITR_SHIFT) / \ ((i) & IGC_QVECTOR_MASK)) +/* + * The average packet size calculation in igc_ring_itr() yields an EITR + * interval field value. That field is quarter microsecond granular (see + * IGC_EITR_SHIFT), so an interval of V is 1000000 / (V / 4) interrupts per + * second. + */ +#define IGC_AIM_DIVIDEND (IGC_EITR_DIVIDEND << IGC_EITR_SHIFT) + /* * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be * multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will @@ -299,9 +307,6 @@ struct rx_ring { uint64_t rx_aim_snapshot __aligned(8); u32 rx_packets_last; u32 rx_bytes_last; - - /* Next requested EITR latency */ - u8 rx_nextlatency; }; static __inline void