From nobody Sun Aug 16 20:47:44 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 4hNShc49NHz6pb0b for ; Sun, 16 Aug 2026 20:47:44 +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 4hNShc2MSzz41xh for ; Sun, 16 Aug 2026 20:47:44 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786913264; 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=BhQd9H7z83HrFjR8NyRhSnN20EVtKc7sTR53PtD0eFw=; b=hiAnJEzxnPuC2bwYp5fDwFqdY1lWrzGMCdEogk3LtuZM4FYmCm+U9mEHU4myjqsfZtA42t 790bBvLmCEjIkfrGVfzyHxwzqkfGh/+rik0iFzhcaL3SRGmriR6DRPIOMq0+obp6aE+QeT AuKrPWG2+H/slIbRH/vCLW1unhSJ9AfepCjZv/FWzxE0sYPBMIxdtpE6slAv66aoMUkk3K nJ14s35BzuzmS0hycf5DcPC5Pv9ZqCCslmwlMTmTmMBoTcZm8oFkrDvBVaxiG3XnlcKkee 072t4zpvlhGqhoF6SExiz2IMigaIvUiFpZfG+Zh0golISt5g8KbSyYJob8I0TA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786913264; a=rsa-sha256; cv=none; b=u+XJJgOMkPK68PAlgnxWo71lyu9axjW4zqMFTsDuwPUgWHOTvxZY95JlfsKO55adWxpSXf VaL+BL44hiCrCiu+YV8yFoN7SMPLk2fzj0M1XJg8YmYSYYqR2aSQfX01WwM7Aacj7nOLkk XwV3T3/VMbP+DSnzDJQ6AWoUI3wJ5uIvlhSmfqYPuxEm8TGwI6GI7+ETk8mTCCKIdN8ipB J6tpYeeUJGpgTDXUWnIQNVe+kOgvU6F9x79lrCNlW4dAbeK9G467GvS7l8rIiQPWhnyluC OP6tPT8LxNdSqRcc3NI/X+RRpgYR0EbdxdhfvYgt+GZ2t1/joZ/of1v1WIWz2g== 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=1786913264; 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=BhQd9H7z83HrFjR8NyRhSnN20EVtKc7sTR53PtD0eFw=; b=IHUl26pW5dYjnFSYG7Ojl+cjOPca8dwFY1YLrB8SAKkjXNGZXak2/KHjaCO955c0Gr9tmc x9s3sf5KqTzIUUiuyzH0cnjstu70rVb7SRwwA4JCStHnEFMG93C2hNtTnLJxGv4HvLwiVa f3OI6vFSz5LjG/egoByaxu5KkhXEB8oe0Oz90Z1FnX4zeggGbehmj8UPZEF40PeDq9U8jJ j+BpNv7RUD7oNA9yp5j3BoikXdSfgQ3fhgZJU+t4LZfD60luW/z2GaGXAtneHU5sAuNDHa t8EVF7M/2bEw97OLY7QT7P5z8kKl+mdLkCHVQFXnL4l4n/+cn5qP7T7vtkUoTw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hNShc1K6hzky5 for ; Sun, 16 Aug 2026 20:47:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 45c65 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 16 Aug 2026 20:47:44 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: bc00b347ab9d - stable/15 - ixgbe: rebuild the shared multicast table 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/stable/15 X-Git-Reftype: branch X-Git-Commit: bc00b347ab9d2f5e26a0646a621fa03d57051a73 Auto-Submitted: auto-generated Date: Sun, 16 Aug 2026 20:47:44 +0000 Message-Id: <6a8221f0.45c65.3b5880a6@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=bc00b347ab9d2f5e26a0646a621fa03d57051a73 commit bc00b347ab9d2f5e26a0646a621fa03d57051a73 Author: Kevin Bowling AuthorDate: 2026-07-31 11:53:17 +0000 Commit: Kevin Bowling CommitDate: 2026-08-16 20:44:35 +0000 ixgbe: rebuild the shared multicast table The MTA is shared by the PF and all VFs. The VF mailbox handler only ORs new bits, so hashes survive list removal and VF reset. Conversely, PF multicast updates replace the whole table with PF-only state and discard live VF filters. Rebuild the table from the PF list and every active VF whenever either changes. Clear VF multicast state during reset and PF reinitialization, and remove all VF hashes on SR-IOV teardown. Keep the software shadow and multicast control state synchronized, and avoid writes to unchanged MTA registers. Adapt the aggregate desired-state rebuild introduced for igb(4) in a2ed165f0049 and its write-elision scheme from 350211ab1782 to ixgbe's shared MTA. (cherry picked from commit 1a180b4c86fc7534596cfbe451e25e403db81666) --- sys/dev/ixgbe/if_ix.c | 85 ++++++++++++++++++++++++++++++++++++++++----- sys/dev/ixgbe/if_sriov.c | 39 +++++++++++---------- sys/dev/ixgbe/ixgbe.h | 1 + sys/dev/ixgbe/ixgbe_sriov.h | 1 + 4 files changed, 99 insertions(+), 27 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index eb7e2ab00d3f..6f8c453c0690 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -3827,6 +3827,7 @@ ixgbe_if_init(if_ctx_t ctx) hw->addr_ctrl.rar_used_count = 1; ixgbe_init_hw(hw); + sc->iov_mta_valid = false; ixgbe_initialize_iov(sc); @@ -4179,6 +4180,67 @@ ixgbe_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int idx) return (1); } /* ixgbe_mc_filter_apply */ +#ifdef PCI_IOV +/* + * The MTA is shared by the PF and every VF. Rebuild it from all owners + * because an individual bit cannot be cleared safely when hashes collide. + */ +u_int +ixgbe_iov_rebuild_mta(struct ixgbe_softc *sc) +{ + struct ixgbe_hw *hw; + struct ixgbe_mc_addr *mta; + struct ixgbe_vf *vf; + u32 old_mta[IXGBE_MAX_MTA]; + u32 hash; + u_int i, mcnt; + int vf_index; + + hw = &sc->hw; + mta = sc->mta; + bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES); + mcnt = if_foreach_llmaddr(iflib_get_ifp(sc->ctx), + ixgbe_mc_filter_apply, sc); + + bcopy(hw->mac.mta_shadow, old_mta, sizeof(old_mta)); + bzero(hw->mac.mta_shadow, sizeof(hw->mac.mta_shadow)); + hw->addr_ctrl.num_mc_addrs = mcnt; + hw->addr_ctrl.mta_in_use = 0; + + for (i = 0; i < mcnt; i++) + ixgbe_set_mta(hw, mta[i].addr); + + for (vf_index = 0; vf_index < sc->num_vfs; vf_index++) { + vf = &sc->vfs[vf_index]; + if (!(vf->flags & IXGBE_VF_ACTIVE)) + continue; + + for (i = 0; i < vf->num_mc_hashes; i++) { + hash = vf->mc_hash[i] & 0xfff; + hw->mac.mta_shadow[(hash >> 5) & + (hw->mac.mcft_size - 1)] |= + 1U << (hash & 0x1f); + hw->addr_ctrl.mta_in_use++; + } + } + + for (i = 0; i < hw->mac.mcft_size; i++) { + if (sc->iov_mta_valid && + old_mta[i] == hw->mac.mta_shadow[i]) + continue; + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_MTA(0), i, + hw->mac.mta_shadow[i]); + } + sc->iov_mta_valid = true; + + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, + (hw->addr_ctrl.mta_in_use != 0 ? IXGBE_MCSTCTRL_MFE : 0) | + hw->mac.mc_filter_type); + + return (mcnt); +} +#endif + static void ixgbe_if_multi_set(if_ctx_t ctx) { @@ -4191,16 +4253,23 @@ ixgbe_if_multi_set(if_ctx_t ctx) IOCTL_DEBUGOUT("ixgbe_if_multi_set: begin"); - mta = sc->mta; - bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES); +#ifdef PCI_IOV + if (sc->feat_en & IXGBE_FEATURE_SRIOV) { + mcnt = ixgbe_iov_rebuild_mta(sc); + } else +#endif + { + mta = sc->mta; + bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES); - mcnt = if_foreach_llmaddr(iflib_get_ifp(ctx), ixgbe_mc_filter_apply, - sc); + mcnt = if_foreach_llmaddr(iflib_get_ifp(ctx), + ixgbe_mc_filter_apply, sc); - if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) { - update_ptr = (u8 *)mta; - ixgbe_update_mc_addr_list(&sc->hw, update_ptr, mcnt, - ixgbe_mc_array_itr, true); + if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) { + update_ptr = (u8 *)mta; + ixgbe_update_mc_addr_list(&sc->hw, update_ptr, mcnt, + ixgbe_mc_array_itr, true); + } } fctrl = IXGBE_READ_REG(&sc->hw, IXGBE_FCTRL); diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c index b9e5205cf1b9..dd67680d9c7d 100644 --- a/sys/dev/ixgbe/if_sriov.c +++ b/sys/dev/ixgbe/if_sriov.c @@ -303,9 +303,15 @@ ixgbe_vf_frame_size_compatible(struct ixgbe_softc *sc, struct ixgbe_vf *vf) static void ixgbe_process_vf_reset(struct ixgbe_softc *sc, struct ixgbe_vf *vf) { + bool rebuild_mta; + ixgbe_vf_set_default_vlan(sc, vf, vf->default_vlan); - // XXX clear multicast addresses + rebuild_mta = vf->num_mc_hashes != 0; + vf->num_mc_hashes = 0; + bzero(vf->mc_hash, sizeof(vf->mc_hash)); + if (rebuild_mta) + ixgbe_iov_rebuild_mta(sc); ixgbe_clear_rar(&sc->hw, vf->rar_index); ixgbe_toggle_txdctl(&sc->hw, vf->pool); @@ -431,30 +437,24 @@ ixgbe_vf_set_mc_addr(struct ixgbe_softc *sc, struct ixgbe_vf *vf, u32 *msg) { u16 *list = (u16*)&msg[1]; int entries; - u32 vmolr, vec_bit, vec_reg, mta_reg; + u32 vmolr; entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; entries = min(entries, IXGBE_MAX_VF_MC); vmolr = IXGBE_READ_REG(&sc->hw, IXGBE_VMOLR(vf->pool)); + vmolr &= ~IXGBE_VMOLR_ROMPE; + IXGBE_WRITE_REG(&sc->hw, IXGBE_VMOLR(vf->pool), vmolr); + bzero(vf->mc_hash, sizeof(vf->mc_hash)); + bcopy(list, vf->mc_hash, entries * sizeof(*list)); vf->num_mc_hashes = entries; + ixgbe_iov_rebuild_mta(sc); - /* Set the appropriate MTA bit */ - for (int i = 0; i < entries; i++) { - vf->mc_hash[i] = list[i]; - vec_reg = (vf->mc_hash[i] >> 5) & 0x7F; - vec_bit = vf->mc_hash[i] & 0x1F; - mta_reg = IXGBE_READ_REG(&sc->hw, IXGBE_MTA(vec_reg)); - mta_reg |= (1 << vec_bit); - IXGBE_WRITE_REG(&sc->hw, IXGBE_MTA(vec_reg), mta_reg); - } - - if (entries == 0) - vmolr &= ~IXGBE_VMOLR_ROMPE; - else + if (entries != 0) { vmolr |= IXGBE_VMOLR_ROMPE; - IXGBE_WRITE_REG(&sc->hw, IXGBE_VMOLR(vf->pool), vmolr); + IXGBE_WRITE_REG(&sc->hw, IXGBE_VMOLR(vf->pool), vmolr); + } ixgbe_send_vf_success(sc, vf, msg[0]); } /* ixgbe_vf_set_mc_addr */ @@ -759,9 +759,10 @@ ixgbe_if_iov_uninit(if_ctx_t ctx) IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0); + sc->num_vfs = 0; + ixgbe_iov_rebuild_mta(sc); free(sc->vfs, M_IXGBE_SRIOV); sc->vfs = NULL; - sc->num_vfs = 0; sc->feat_en &= ~IXGBE_FEATURE_SRIOV; } /* ixgbe_if_iov_uninit */ @@ -782,8 +783,8 @@ ixgbe_init_vf(struct ixgbe_softc *sc, struct ixgbe_vf *vf) IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr); ixgbe_vf_set_default_vlan(sc, vf, vf->vlan_tag); - - // XXX multicast addresses + vf->num_mc_hashes = 0; + bzero(vf->mc_hash, sizeof(vf->mc_hash)); if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { ixgbe_set_rar(&sc->hw, vf->rar_index, diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 9120ca5a37ff..ae246433348e 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -441,6 +441,7 @@ struct ixgbe_softc { int num_vfs; int pool; struct ixgbe_vf *vfs; + bool iov_mta_valid; /* Bypass */ struct ixgbe_bp_data bypass; diff --git a/sys/dev/ixgbe/ixgbe_sriov.h b/sys/dev/ixgbe/ixgbe_sriov.h index 3c456ee819f2..c3a988bda886 100644 --- a/sys/dev/ixgbe/ixgbe_sriov.h +++ b/sys/dev/ixgbe/ixgbe_sriov.h @@ -72,6 +72,7 @@ void ixgbe_if_iov_uninit(if_ctx_t); void ixgbe_initialize_iov(struct ixgbe_softc *); void ixgbe_recalculate_max_frame(struct ixgbe_softc *); void ixgbe_ping_all_vfs(struct ixgbe_softc *); +u_int ixgbe_iov_rebuild_mta(struct ixgbe_softc *); int ixgbe_pci_iov_detach(device_t); void ixgbe_define_iov_schemas(device_t, int *); void ixgbe_align_all_queue_indices(struct ixgbe_softc *);