From nobody Thu Jul 30 05:09:05 2026 X-Original-To: dev-commits-src-main@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 4h9cgQ0cQZz6mgHT for ; Thu, 30 Jul 2026 05:09:06 +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 4h9cgP5sdbz3Y7h for ; Thu, 30 Jul 2026 05:09:05 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785388145; 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=c6LEvaONu28VBpA30VqTVR98UfpgZcVmqzDeM8xJE6A=; b=Pce/1jgF5gatZ1yDzqDX+2LlooReVIKO1sRMepm4/khyVYqnvr3e4PkQFGOYzliXIdP7lU hWG+h1kVBDiAT5Q3kjjjc/OVipofS8NPbv2TBdWr2F17tdyI182bZtBg5h/uKnvt+YR/rS T8nxd5JP8Hy3xgyBGhHQYsgayN62a119L7bX/ov8KJ3e61yvyqSVjB+xMdeACgfS1v9hza FOV3xEw/uM2QxomwZLdLgOBtHPbqSS2VlxKUDXD6Lzdc5aIzJjN2uaqBl344XhxerZoet+ MGgO2SxvN1fZUXH5qukH8hXnNd5y7gi46LPoB7/73CEEN7sSfWxREwB3Sktj0w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785388145; a=rsa-sha256; cv=none; b=Q692f+qF0v/i7u0rc1zWmTHBU6A2hptQydxeW76f2+54P+im2Tq2XHaEvty/e6cyqYdzhA gfVx55UbQ8HzOHSNFDDdkUEF+Be4Z7LPagVSmSAH9kDYaBqyhPdETJ6JPa+VUBpJ6wUomY plLqOinwkr9vQM/98jWxHfOWkkR4PiRqL9r5+Tbk2nN91dARYwy3QgEBMvXBf1GQ52nC7h NFgHqthbVnJUS+hSv+XT5bXLtAtQZbYkU+Sy1saG026+EgPyxzo6jWu8EpuvIW5o2D1ZJ1 O280DASTMM/9b0znjpJO3VUz6NcLDvDK8WZLSEBo1P9sqeyHqA1cKa0ehEACVA== 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=1785388145; 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=c6LEvaONu28VBpA30VqTVR98UfpgZcVmqzDeM8xJE6A=; b=UbMDb43gVJr6PhTZd25aniu9dRIo7TFSX7TeKTPUGP0GM4kDDOKP/2xSQr0Juw7asnWCZQ 2n7skJPk2ea/msA8nnrzcKN4E7jy896ksYE/6pnT4uni7w71QQCLY+Z0ggL5uCw4D0gc/s PTrl/j0a20olhZYNy7L6zDKAeliArSODufjtFFaJy+GV+I3NJJNiucSWLXI7F5BEUZ0PSe ggquk7wKwqN230ANozn/T9yC2LMlXKYVwmcoIw1csRd9G7dWVEs4CNRisRhakEK19s1R9b RI+jEYVKpfnRZPWcZ5zDNtx93eAH9mfpZGvFg8hdnd/nmfRvYboJw/HPBxq5kA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h9cgP4nkSzyMG for ; Thu, 30 Jul 2026 05:09:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 320ea by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 30 Jul 2026 05:09:05 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 5ce6c94f9859 - main - igb: Update only changed IOV VLAN filters List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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: 5ce6c94f98599e5ae0595ff5178a224145b6225f Auto-Submitted: auto-generated Date: Thu, 30 Jul 2026 05:09:05 +0000 Message-Id: <6a6adc71.320ea.35d6e2a5@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=5ce6c94f98599e5ae0595ff5178a224145b6225f commit 5ce6c94f98599e5ae0595ff5178a224145b6225f Author: Kevin Bowling AuthorDate: 2026-07-29 09:09:24 +0000 Commit: Kevin Bowling CommitDate: 2026-07-30 05:08:24 +0000 igb: Update only changed IOV VLAN filters Keep the full VFTA/VLVF software recomputation and clear-map-set ordering, but compare each phase against the authoritative old value. Write only VFTA words and VLVF slots whose effective contents change. I350 uses its software VFTA shadow because erratum 20 makes live reads unreliable; an invalid shadow forces a complete clear before sparse restoration. 82576 continues to diff against live VFTA reads. Add SDT probes for every logical write phase and the final software images so hardware tests can verify exact elision counts. On my I350 DUT, the old full table path averaged 819 us across 31 VLAN removals versus about 79 us for the PF statistics sweep. Sponsored by: BBOX.io --- sys/dev/e1000/if_igb_iov.c | 98 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/sys/dev/e1000/if_igb_iov.c b/sys/dev/e1000/if_igb_iov.c index 8b8dfcd0a8f6..9b2c77a92eb7 100644 --- a/sys/dev/e1000/if_igb_iov.c +++ b/sys/dev/e1000/if_igb_iov.c @@ -11,6 +11,7 @@ #ifdef PCI_IOV #include +#include #include #define IGB_IOV_RAH_POOLSEL_SHIFT 18 @@ -78,6 +79,23 @@ struct igb_vf_mac_filter { MALLOC_DEFINE(M_IGB_IOV, "igb_iov", "igb SR-IOV allocations"); +/* + * These logical-write probes let hardware tests verify the elision policy. + * e1000_write_vfta_i350() expands one VFTA call into ten physical writes, so + * the probes intentionally count calls made by the rebuild rather than MMIO + * transactions. The state probe exposes the final software images while the + * stack arrays are still live. + */ +SDT_PROVIDER_DEFINE(igb_iov); +SDT_PROBE_DEFINE3(igb_iov, vlan, rebuild, vfta_clear, + "struct e1000_softc *", "u_int", "uint32_t"); +SDT_PROBE_DEFINE3(igb_iov, vlan, rebuild, vlvf_write, + "struct e1000_softc *", "u_int", "uint32_t"); +SDT_PROBE_DEFINE3(igb_iov, vlan, rebuild, vfta_set, + "struct e1000_softc *", "u_int", "uint32_t"); +SDT_PROBE_DEFINE3(igb_iov, vlan, rebuild, state, + "struct e1000_softc *", "uint32_t *", "uint32_t *"); + static const struct timeval igb_iov_nack_interval = { 2, 0 }; static const struct timeval igb_iov_mbx_log_interval = { 2, 0 }; static const struct timeval igb_iov_spoof_log_interval = { 2, 0 }; @@ -470,6 +488,29 @@ igb_iov_intr_mask(const struct e1000_softc *sc) return (E1000_IMS_VMMB | E1000_IMS_MDDET); } +static void +igb_iov_vfta_shadow_invalidate(struct e1000_softc *sc) +{ + + /* + * I350 erratum 20 makes VFTA reads unreliable while VMDq loopback or + * anti-spoofing is active. The shadow is therefore authoritative + * until a reset or another independent hardware writer invalidates + * it. Readback cannot reliably audit a stale-but-valid shadow on + * this part, so keep all shadow mutation in these two helpers. + */ + memset(sc->iov_vfta, 0, sizeof(sc->iov_vfta)); + sc->iov_vfta_valid = false; +} + +static void +igb_iov_vfta_shadow_store(struct e1000_softc *sc, const u32 *vfta) +{ + + memcpy(sc->iov_vfta, vfta, sizeof(sc->iov_vfta)); + sc->iov_vfta_valid = true; +} + static void igb_iov_notify_vfs_reset(struct e1000_softc *sc) { @@ -558,7 +599,7 @@ igb_iov_reset_prepare(struct e1000_softc *sc) if (sc->iov_mbx_retry_initialized) callout_stop(&sc->iov_mbx_retry); sc->iov_mta_valid = false; - sc->iov_vfta_valid = false; + igb_iov_vfta_shadow_invalidate(sc); atomic_readandclear_32(&sc->iov_mdd_cause); atomic_readandclear_32(&sc->iov_pending); atomic_readandclear_32(&sc->iov_spoof_pending); @@ -657,9 +698,11 @@ igb_iov_rebuild_vlan(struct e1000_softc *sc) struct e1000_hw *hw; struct igb_vf *vf; u32 old_vlvf[E1000_VLVF_ARRAY_SIZE]; - u32 vfta[EM_VFTA_SIZE], vlvf[E1000_VLVF_ARRAY_SIZE]; + u32 effective_vfta[EM_VFTA_SIZE], vfta[EM_VFTA_SIZE]; + u32 vlvf[E1000_VLVF_ARRAY_SIZE]; u32 old_vfta, rctl, vmolr; - bool pf_overflow, pf_vlan_promisc, preserve_pf; + bool force_vfta, pf_overflow, pf_vlan_promisc, preserve_pf; + bool vfta_changed, vlvf_changed; int i, vid; if (!igb_iov_enabled(sc)) @@ -769,28 +812,54 @@ igb_iov_rebuild_vlan(struct e1000_softc *sc) * transition to a PF-only VLAN deliberately retains VFTA membership * and falls through to the default PF pool. */ + force_vfta = hw->mac.type == e1000_i350 && + !sc->iov_vfta_valid; + vfta_changed = false; for (i = 0; i < EM_VFTA_SIZE; i++) { /* * I350 erratum 20 makes VFTA reads unreliable while VMDq * loopback or anti-spoofing is active. Its ten-write - * workaround is already in e1000_write_vfta_i350(); keep a - * software shadow for the read side of this transition. + * workaround is already in e1000_write_vfta_i350(). Force a + * complete clear when the authoritative shadow is invalid; + * 82576 can safely diff against its live register contents. */ if (hw->mac.type == e1000_i350) - old_vfta = sc->iov_vfta_valid ? sc->iov_vfta[i] : 0; + old_vfta = force_vfta ? 0 : sc->iov_vfta[i]; else old_vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, i); - e1000_write_vfta(hw, i, old_vfta & vfta[i]); + effective_vfta[i] = old_vfta & vfta[i]; + if (force_vfta || effective_vfta[i] != old_vfta) { + SDT_PROBE3(igb_iov, vlan, rebuild, vfta_clear, + sc, i, effective_vfta[i]); + e1000_write_vfta(hw, i, effective_vfta[i]); + vfta_changed = true; + } } - E1000_WRITE_FLUSH(hw); + if (vfta_changed) + E1000_WRITE_FLUSH(hw); + vlvf_changed = false; for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) - E1000_WRITE_REG(hw, E1000_VLVF(i), vlvf[i]); - E1000_WRITE_FLUSH(hw); + if (vlvf[i] != old_vlvf[i]) { + SDT_PROBE3(igb_iov, vlan, rebuild, vlvf_write, + sc, i, vlvf[i]); + E1000_WRITE_REG(hw, E1000_VLVF(i), vlvf[i]); + vlvf_changed = true; + } + if (vlvf_changed) + E1000_WRITE_FLUSH(hw); + vfta_changed = false; for (i = 0; i < EM_VFTA_SIZE; i++) - e1000_write_vfta(hw, i, vfta[i]); - memcpy(sc->iov_vfta, vfta, sizeof(sc->iov_vfta)); - sc->iov_vfta_valid = true; + if (vfta[i] != effective_vfta[i]) { + SDT_PROBE3(igb_iov, vlan, rebuild, vfta_set, + sc, i, vfta[i]); + e1000_write_vfta(hw, i, vfta[i]); + vfta_changed = true; + } + if (vfta_changed) + E1000_WRITE_FLUSH(hw); + SDT_PROBE3(igb_iov, vlan, rebuild, state, sc, vfta, vlvf); + igb_iov_vfta_shadow_store(sc, vfta); } static bool @@ -1740,8 +1809,7 @@ igb_if_iov_uninit(if_ctx_t ctx) sc->iov_mta_valid = false; sc->iov_pf_mdd_blocked = false; sc->iov_pf_vlan_promisc = false; - sc->iov_vfta_valid = false; - memset(sc->iov_vfta, 0, sizeof(sc->iov_vfta)); + igb_iov_vfta_shadow_invalidate(sc); sc->tx_queues[0].txr.me = 0; sc->rx_queues[0].rxr.me = 0; atomic_readandclear_32(&sc->iov_mdd_cause);