From nobody Sun Sep 06 01:20:55 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 4hcspb4tMyz6rR7V for ; Sun, 06 Sep 2026 01:20:55 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hcspb33DBz3PV3 for ; Sun, 06 Sep 2026 01:20:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1788657655; 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=zuXxmT2ibh5X1SgrqCblCVFyqNIQxFGNY7swscF2/o8=; b=FOEjAHaA60ElrwRW0GP4KwNjK4G+9Y1K1qqbpZSzvv8c6eFLjue6BbwI23u22sTYW5c6gK rhqXTZUf+Sb7onCY9FX/P1MLc8i0LFl2Jf/UiyUiyM5MEjd4QSu+kO0NTD+0dq4jSZT1Mn RVEwhL00JIP9WOMS6CqX40rJNx6EeE/+U7LgoTpX2DdW241fqezZ5hucwfuXuBr36NTxQm 0Ync1bSVmTj1ofIrPfLxpIDi5Vf6gu/X27QvNIDo98tDp+OfqZHFGU9Gy1PEDvEkz+Bgo9 erVsQCqEVWy1RBHau0H58iaMNWBARjBrwwwIpab0kaSj93ITW7le8yKRloTilQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1788657655; a=rsa-sha256; cv=none; b=LQobAA4WmZsdwczRT1RWFPfe6bA1M8h5LPHoZ0ME09yJlIObdbzy64+c9LewzJDYeRzcsd QuA+Z4L4BYjUdNfUmJZ+eUQnAnpfhpDYZcCrhx5dhq+9gb9hCVlmatU0LBZqpIcujMnLYs VRbynfTIpNGLIewYVjT4960qMiI8zY/tsHiCC24tb3ImNdxe9dbp2zYyv/fgar7JZhQKPi GxMYyvtQM3XwVyfzxQsZF939rqQc6vwO7tdW6N4/Fd0//xUSj/coAWgQV8XeEQfV/Lcchg tUZPmIYYr0DustfmJ/aXOtaZpqoDGCfAiIBpbrtMC69j7grb14Rm0Xy6oskOGQ== 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=1788657655; 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=zuXxmT2ibh5X1SgrqCblCVFyqNIQxFGNY7swscF2/o8=; b=SgTvE+s2CnFbat3Pv6YoHwGOr5T2EuvhNy5B/BAhNmVzbWLbrqKVR7orDhNKe02U5GesiG pyROUTF524SHzQuocgwm63IRcqrfIWN7Jbwx3rFsVgdjc9h8gktVaQVgjSq1pb0aXs1CZD O/tWYInaRb/nQz3ia3YNQ18aAKG0Y/4ddvOAh8bmIo26J9ep4qfg6TWByeuFNwAxeLj42s 7OKfMvBZcsQN49wB0+NlWSSEwRHxppZ6zfLght/MHphkV0hI29nsqgF/4jdXSU0ZpV1X+i 7XGBJj5vX+W8nMwtpWie94sQYj+qVVdKseVXL6R2xYsoe07jLvXpEGvUC3WMLw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hcspb1Sq7z18Zl for ; Sun, 06 Sep 2026 01:20:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 36a31 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 06 Sep 2026 01:20:55 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 589235de1fd5 - stable/15 - igb: Report 82580 memory ECC errors 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: 589235de1fd5f97f952daec530db75d841d253bb Auto-Submitted: auto-generated Date: Sun, 06 Sep 2026 01:20:55 +0000 Message-Id: <6a9cbff7.36a31.100c29f9@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=589235de1fd5f97f952daec530db75d841d253bb commit 589235de1fd5f97f952daec530db75d841d253bb Author: Kevin Bowling AuthorDate: 2026-08-16 05:49:56 +0000 Commit: Kevin Bowling CommitDate: 2026-09-06 01:20:18 +0000 igb: Report 82580 memory ECC errors 82580 exposes clear-on-read, saturating corrected error counters for the receive and transmit packet buffers. Its two PCIe command memories expose RW1C indications for uncorrectable ECC errors. Sample the packet buffer counters and PCIe indications from the regular hardware statistics update. Fatal recovery samples the PCIe indications from the serialized admin path rather than the interrupt filter. Thus, either the regular statistics pass or recovery reads and clears each indication, but they cannot both account it. Also preserve indications observed while initialization is completing. Expose the exact packet buffer error total and observed PCIe command memory indications under the memory_errors sysctl node. Multiple PCIe errors between samples can collapse into one indication per memory. Validated on an Intel I340-T2 (82580, revision 1). A clean boot and three down/up cycles left the packet-buffer, PCIe, and region-specific counters at zero. Synthetic ICS.FER events advanced fatal_unknown and fatal_resets exactly once on the targeted function without changing the sibling or ECC counters. The 82580 datasheet exposes no ECC or parity error injection register, so corrected packet buffer and PCIe ECC accounting could not be forced independently. Sponsored by: BBOX.io (cherry picked from commit 915c628c4f49b267c8a713b79c4a8b157092d717) --- sys/dev/e1000/e1000_defines.h | 1 + sys/dev/e1000/if_em.c | 68 +++++++++++++++++++++++++++++++++++-------- sys/dev/e1000/if_em.h | 1 + 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h index 56c9418b2419..371fee155dd0 100644 --- a/sys/dev/e1000/e1000_defines.h +++ b/sys/dev/e1000/e1000_defines.h @@ -553,6 +553,7 @@ #define E1000_PCIEECCSTS_82580_ERROR_MASK 0x00000003 #define E1000_LANPERRSTS_82580_ERROR_MASK 0x00007FFF #define E1000_PBECCSTS_82580_ECC_ENABLE 0x00010000 +#define E1000_PBECCSTS_82580_CORR_CNT_MASK 0x000000FF /* 82576 uses PEIND directly rather than the later four-region layout. */ #define E1000_PEIND_82576_NONFATAL_MASK 0x00000007 diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 1ae33bb305e9..6e215152c9e8 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -449,6 +449,8 @@ static void em_finish_fatal_error_reset(struct e1000_softc *); static void em_configure_peind_memory_errors(struct e1000_softc *); static void em_configure_82575_memory_errors(struct e1000_softc *); static void em_configure_82580_memory_errors(struct e1000_softc *); +static void em_update_82580_ecc_stats(struct e1000_softc *, u32, u32, + u32); static void em_if_multi_set(if_ctx_t); static void em_if_update_admin_status(if_ctx_t); static void em_if_debug(if_ctx_t); @@ -2015,10 +2017,11 @@ em_configure_82580_memory_errors(struct e1000_softc *sc) em_clear_82580_memory_error_status(hw, E1000_DRPARS_82580); em_clear_82580_memory_error_status(hw, E1000_DDPARS_82580); em_clear_82580_memory_error_status(hw, E1000_PCIEERRSTS); - em_clear_82580_memory_error_status(hw, E1000_PCIEECCSTS); (void)E1000_READ_REG(hw, E1000_LANPERRSTS); - (void)E1000_READ_REG(hw, E1000_RPBECCSTS); - (void)E1000_READ_REG(hw, E1000_TPBECCSTS); + em_update_82580_ecc_stats(sc, + E1000_READ_REG(hw, E1000_RPBECCSTS), + E1000_READ_REG(hw, E1000_TPBECCSTS), + E1000_READ_REG(hw, E1000_PCIEECCSTS)); E1000_WRITE_REG(hw, E1000_RPBECCSTS, E1000_PBECCSTS_82580_ECC_ENABLE); E1000_WRITE_REG(hw, E1000_TPBECCSTS, @@ -2146,6 +2149,21 @@ em_fatal_error_intr_mask(struct e1000_softc *sc) return (em_memory_error_intr_mask(&sc->hw)); } +static void +em_update_82580_ecc_stats(struct e1000_softc *sc, u32 rpbeccsts, + u32 tpbeccsts, u32 pcieeccsts) +{ + u32 status; + + sc->corrected_error_packet_buffer_count += + (rpbeccsts & E1000_PBECCSTS_82580_CORR_CNT_MASK) + + (tpbeccsts & E1000_PBECCSTS_82580_CORR_CNT_MASK); + status = pcieeccsts & E1000_PCIEECCSTS_82580_ERROR_MASK; + sc->uncorrected_error_pcie_count += bitcount32(status); + if (status != 0) + E1000_WRITE_REG(&sc->hw, E1000_PCIEECCSTS, status); +} + static void em_update_82575_ecc_stats(struct e1000_softc *sc, u32 pbeccsts, u32 rdhests, u32 tdhests) @@ -2337,8 +2355,7 @@ static void em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) { struct e1000_hw *hw; - u32 dma_host, dma_rx, dma_tx, error_mask, lanerr, pcieecc; - u32 pcieerr, peind; + u32 dma_host, dma_rx, dma_tx, error_mask, lanerr, pcieerr, peind; error_mask = em_memory_error_intr_mask(&sc->hw); if (!em_has_memory_errors(&sc->hw) || @@ -2369,7 +2386,6 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) E1000_PEIND_FATAL_MASK; pcieerr = E1000_READ_REG(hw, E1000_PCIEERRSTS) & em_pcie_fatal_error_mask(hw); - pcieecc = 0; dma_host = 0; if (em_has_82580_memory_errors(hw)) { /* @@ -2379,8 +2395,6 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) * status registers. */ peind &= E1000_PEIND_MNG_PARITY_FATAL; - pcieecc = E1000_READ_REG(hw, E1000_PCIEECCSTS) & - E1000_PCIEECCSTS_82580_ERROR_MASK; dma_tx = E1000_READ_REG(hw, E1000_DTPARS_82580); dma_rx = E1000_READ_REG(hw, E1000_DRPARS_82580); dma_host = E1000_READ_REG(hw, @@ -2400,7 +2414,7 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) lanerr = E1000_READ_REG(hw, E1000_LANPERRSTS) & E1000_LANPERRSTS_RETX_BUF; } - if (pcieerr != 0 || pcieecc != 0) + if (pcieerr != 0) peind |= E1000_PEIND_PCIE_PARITY_FATAL; if (lanerr != 0) peind |= E1000_PEIND_LANPORT_PARITY_FATAL; @@ -2408,7 +2422,6 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) peind |= E1000_PEIND_DMA_PARITY_FATAL; sc->fatal_error_peind = peind; sc->fatal_error_pcie = pcieerr; - sc->fatal_error_pcie_ecc = pcieecc; sc->fatal_error_lan = lanerr; sc->fatal_error_dma_tx = dma_tx; sc->fatal_error_dma_rx = dma_rx; @@ -2422,7 +2435,7 @@ em_handle_fatal_error_intr(struct e1000_softc *sc, u32 icr) static bool em_handle_fatal_error_admin(struct e1000_softc *sc) { - u32 error_mask, peind; + u32 error_mask, pcieecc, peind; bool reset_required; if (!atomic_cmpset_acq_32(&sc->fatal_error_state, @@ -2473,6 +2486,20 @@ em_handle_fatal_error_admin(struct e1000_softc *sc) "requesting reset\n", peind); } else { peind = sc->fatal_error_peind; + if (em_has_82580_memory_errors(&sc->hw)) { + pcieecc = E1000_READ_REG(&sc->hw, + E1000_PCIEECCSTS) & + E1000_PCIEECCSTS_82580_ERROR_MASK; + sc->fatal_error_pcie_ecc |= pcieecc; + if (pcieecc != 0) { + peind |= E1000_PEIND_PCIE_PARITY_FATAL; + sc->fatal_error_peind = peind; + } + em_update_82580_ecc_stats(sc, + E1000_READ_REG(&sc->hw, E1000_RPBECCSTS), + E1000_READ_REG(&sc->hw, E1000_TPBECCSTS), + pcieecc); + } if (peind & E1000_PEIND_LANPORT_PARITY_FATAL) sc->fatal_error_lan_count++; if (peind & E1000_PEIND_MNG_PARITY_FATAL) @@ -2555,6 +2582,9 @@ em_handle_fatal_error_admin(struct e1000_softc *sc) * PCIe traffic for a fatal error in any host-owned region, so use the same * order for every 82580 recovery. This differs from the normal reset path, * which disables the bus master first. + * + * Indications that relatch after admin accounting are discarded during + * reset; sticky bits cannot distinguish them from the saved event. */ static void em_prepare_fatal_error_reset(struct e1000_softc *sc) @@ -6035,6 +6065,11 @@ em_update_stats_counters(struct e1000_softc *sc) E1000_READ_REG(&sc->hw, E1000_TDHESTS_82575)); else if (em_has_82576_memory_errors(&sc->hw)) em_update_82576_ecc_stats(sc); + else if (em_has_82580_memory_errors(&sc->hw)) + em_update_82580_ecc_stats(sc, + E1000_READ_REG(&sc->hw, E1000_RPBECCSTS), + E1000_READ_REG(&sc->hw, E1000_TPBECCSTS), + E1000_READ_REG(&sc->hw, E1000_PCIEECCSTS)); else if (em_has_i350_memory_errors(&sc->hw)) em_update_i350_ecc_stats(sc); else if (em_has_i210_memory_errors(&sc->hw)) @@ -6440,7 +6475,16 @@ em_add_hw_stats(struct e1000_softc *sc) "fatal_unknown", CTLFLAG_RD, &sc->fatal_error_unknown_count, "Fatal memory errors without a reported region"); - if (em_has_i210_memory_errors(&sc->hw)) { + if (em_has_82580_memory_errors(&sc->hw)) { + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "corrected_packet_buffer", CTLFLAG_RD, + &sc->corrected_error_packet_buffer_count, + "Corrected packet-buffer ECC errors"); + SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, + "uncorrected_pcie", CTLFLAG_RD, + &sc->uncorrected_error_pcie_count, + "Uncorrected PCIe command-memory ECC indications"); + } else if (em_has_i210_memory_errors(&sc->hw)) { SYSCTL_ADD_UQUAD(ctx, memerr_list, OID_AUTO, "corrected_dma", CTLFLAG_RD, &sc->corrected_error_dma_count, diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h index f3822377aa09..adc8132967ad 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -643,6 +643,7 @@ struct e1000_softc { u64 corrected_error_packet_buffer_count; u64 uncorrected_error_packet_buffer_count; u64 uncorrected_error_dma_count; + u64 uncorrected_error_pcie_count; u64 que_mask;