From nobody Sun Aug 23 03:41:18 2026 X-Original-To: dev-commits-src-all@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 4hSKb25phPz6pgZ9 for ; Sun, 23 Aug 2026 03:41:18 +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 4hSKb251N1z3rgZ for ; Sun, 23 Aug 2026 03:41:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787456478; 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=ltYEH1x/DV0x5jdYgUCNr0clCX2RxGazzs4/QSS5Oc4=; b=FqdiU7uWacUMu3lBiZpDX/tmhr3a0mi4jODnetNpVgoLNGqYwgk9xK8GdlaMt7celJHG+d Zo1BRMZ0uDxJv9ZW7P8plyRTbSPxUZ1HjxTWOGZ6LKnz58X/irRyGRCTjtqiSchJqqCeHL nIbi1MuVoQS8zqtDa+D0LMZcFNsrsy6wyzB/nHLtb3h41iR7D0QAcSUDSEMPCRN1EExy7/ 5yazPrWmP41jMCRgKEm160tCpry2iQRyTLRfUwPbtj21ox87I3y38B3yFeKWKBOmz/jvMP f+43ZMqj6vtTgBvORzI6h0JuzsXa6v2ossCCc+bfkx5XZhE5KNLeZgbuQLLyRA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787456478; a=rsa-sha256; cv=none; b=XBxObIKqp1s4fSjDGrE1T3wEp4wPZrV2ZrMNUpLCc1NySHpRY3/6IxdoljgHEFBcT4byuK u5uoS1PKrXxpV3MBZgFMiTLNg4rI4T6DDOinrQJ+moGrGg8m7iMGFjWCiqEd1HBCL+RnVx fw8kHbyCmFArWtVW1OY0gP4E6KvPJDc/+QuiQzEF+EzYX6j60zX2/Vmad0uEflFMPgPe6J +oyLJTChM4kvS8k3x0VFc9JFgCNukbCLeCDAftvkzKN3q2Ex2fypvGtRwqtjLUuePUB6LB N0EbonUDnPKUBCC9NNCtJC8rKWVjxn3900kqBJ8xCfkNbbgyM8VKcqvmrOkdjg== 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=1787456478; 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=ltYEH1x/DV0x5jdYgUCNr0clCX2RxGazzs4/QSS5Oc4=; b=SBm67AuVvrXgCDEspx0+5ycAyQyokg6O11gLaGTGfXPKZu7Y9ksZoXMjETSu3tlsKEPkaJ Pa3TPuBJzlTotJM+hwtC66DVgpizZtAk+eptzXPoHgo7u0ZY/krZh9oZZNUDGSOWz+Kt6R rzxqoc/hLAsq5IUEYIF34Cgu1Lo/wk5+w/73cu/ggkLJ9KDeoiTHxPwlA+r4zidxRNCr6p phunQW3gP6lV1wfY/RsLutmSMpz0doq7gWtDXANTObxK9sgg3XIFv/VK2ARRTr8W4Fdj4m OdB8GbBzo5vxc0kzH2XXCHqMgSbImWRfKLJj8P7x2NLDwm9rgeZveJm/IF2okA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hSKb23Xp5z1Ffr for ; Sun, 23 Aug 2026 03:41:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1c32e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 23 Aug 2026 03:41:18 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 915c628c4f49 - main - igb: Report 82580 memory ECC errors List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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/main X-Git-Reftype: branch X-Git-Commit: 915c628c4f49b267c8a713b79c4a8b157092d717 Auto-Submitted: auto-generated Date: Sun, 23 Aug 2026 03:41:18 +0000 Message-Id: <6a8a6bde.1c32e.170caa7@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=915c628c4f49b267c8a713b79c4a8b157092d717 commit 915c628c4f49b267c8a713b79c4a8b157092d717 Author: Kevin Bowling AuthorDate: 2026-08-16 05:49:56 +0000 Commit: Kevin Bowling CommitDate: 2026-08-23 03:34:23 +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. MFC after: 2 weeks Sponsored by: BBOX.io --- 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 95f50c6694a6..aeb38fd4fb10 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -462,6 +462,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); @@ -2303,10 +2305,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, @@ -2434,6 +2437,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) @@ -2625,8 +2643,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) || @@ -2657,7 +2674,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)) { /* @@ -2667,8 +2683,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, @@ -2688,7 +2702,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; @@ -2696,7 +2710,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; @@ -2710,7 +2723,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, @@ -2761,6 +2774,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) @@ -2843,6 +2870,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) @@ -6587,6 +6617,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)) @@ -7101,7 +7136,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 0901c1ce5780..d4d2b3db9457 100644 --- a/sys/dev/e1000/if_em.h +++ b/sys/dev/e1000/if_em.h @@ -648,6 +648,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; #ifdef PCI_IOV struct igb_vf *vfs;