From nobody Fri Oct 31 20:52:42 2025 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 4cytTk4WyZz6FCRh; Fri, 31 Oct 2025 20:52:42 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cytTk3q78z3HT9; Fri, 31 Oct 2025 20:52:42 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1761943962; 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=hrALdxYmKGycSTAEf+3XAZoT9+whke0FdZfTZt4TDtw=; b=lUOQ59Mu1ANx+ZNHHF8aothieQIyAY1E2jRaxkIz9aLHRFtLzhYop/Ks2uQUZBLc8ibOyk L0iiDusrMfId1GlnltxS95Bkd+2Vy6OxfXaFvUl2IvA7GAGPHpbkAI/YCZiVffp6ATYU0O pS+JuYOOXbIO5rK95I27xcca3rojOY37WgkAwyNKcEwRasmQZAQhcKu5B4+4exYO7oSs9e AoGfNfpLS3mTxqF49c4thlITAboYlmfaBwUTcznOlAwq53z3C+0EULeZMzvPwjXudNoCJR BdLqUHqdLu9VJTWjgjQGZZNxQPuGSJDzpP4tgqO7Yi1TzvJK/QlWwuZmVRJLGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1761943962; 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=hrALdxYmKGycSTAEf+3XAZoT9+whke0FdZfTZt4TDtw=; b=rb4lxhhsYNSX8+7iTWmLx4I2+P5VMv9F6OzQ9toc0OzBtlr9dXmggI1nA984P7s/wHG1uB U8wpc0DITV3kCQ0J+gZ6tHfbOFW0pe0/jwfCbSx7vvVRpSJn0I/Yfe9GfuSNYEOYLz698j ubzT2M5Mof5MdxeBKqez+BX/ERV6GdHsg7Up+uQg8WZLTsfOJvG92lK1cNFtiAmVF2dRl4 W1nAP8xXc9WAG6eo2aY5R9rk1jgVrRZGBNi5Z4b7QlWpZW9e9JFIEc2WYQ4I68hqGEqFM+ cBsmIfcqhVTux2TGAybaNn7cAzvDcix7dODmgcdg6gM5VwaWLVyW3blwEe0b8A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1761943962; a=rsa-sha256; cv=none; b=Fv1BY5h+hsH7JezXQWoZgP/GSWyFleNZD+MEkDQd40OyXHWN4me8rCcsp/ac1NSzZFk2NZ 5tWahKjqYObj8I5JAS5IK8LIzLVw+cXh0X7oVd65oldZ0aWc3xXBuOCUzRkT+km1Rtwue4 DgH2PY23ku1ffhag+GRlLw9jlH5AeDrCOQFznB6uvHFzLzaR4JG897xP8dCrrOLVmkd9A/ BN3ZtuFw+qR8ANV/UJzj0vx7OGUbFgcr1hgLg0NxwX2UBzBd+HrHJWB8t2qQ1Sy93jhWF4 oAMah7pvFD6kcmmVt7bXfg5reHU3K6G3SGu/GTYNU3sKPBTo4ZfQpCYZlX70+g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cytTk3Gwkz1N72; Fri, 31 Oct 2025 20:52:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 59VKqgrh068050; Fri, 31 Oct 2025 20:52:42 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 59VKqgN4068047; Fri, 31 Oct 2025 20:52:42 GMT (envelope-from git) Date: Fri, 31 Oct 2025 20:52:42 GMT Message-Id: <202510312052.59VKqgN4068047@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Krzysztof Galazka Subject: git: f3c442950de3 - stable/15 - ixl(4): fix multicast promiscuous mode state tracking and filter management 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kgalazka X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: f3c442950de3b34dda24ecb258171c32d161b1fd Auto-Submitted: auto-generated The branch stable/15 has been updated by kgalazka: URL: https://cgit.FreeBSD.org/src/commit/?id=f3c442950de3b34dda24ecb258171c32d161b1fd commit f3c442950de3b34dda24ecb258171c32d161b1fd Author: Bhosale, Yogesh AuthorDate: 2025-10-16 20:02:45 +0000 Commit: Krzysztof Galazka CommitDate: 2025-10-31 20:47:20 +0000 ixl(4): fix multicast promiscuous mode state tracking and filter management This change reapplies the improvements from commit 89e7335 and adds additional fixes and code optimizations on top of it. The ixl driver supports up to 128 multicast filters in hardware. When this limit is exceeded, the driver should enable multicast promiscuous mode. When the count drops below 128, it should disable promiscuous mode and restore individual filters. The driver previously had problems that could corrupt multicast filters list. The main issue was that ixl_dis_multi_promisc() would attempt to disable promiscuous mode without checking if it was actually enabled, potentially corrupting existing filters. There was also no state tracking across driver functions, leading to redundant operations. This change adds an IXL_FLAGS_MC_PROMISC flag to track the multicast promiscuous mode state. The flag is set when enabling promiscuous mode and cleared when disabling it. Early return checks prevent redundant operations when the mode is already in the desired state, avoiding filter corruption and unnecessary hardware calls. Signed-off-by: Yogesh Bhosale yogesh.bhosale@intel.com PR: 283820 Approved by: kbowling (mentor) Tested by: gowtham.kumar.ks_intel.com Sponsored by: Intel Corporation Differential Revision: https://reviews.freebsd.org/D52549 (cherry picked from commit 46a8a1f08f88c278e60ebb6daa7a551eb641c67b) --- sys/dev/ixl/if_ixl.c | 27 +++++++++++- sys/dev/ixl/ixl.h | 1 + sys/dev/ixl/ixl_pf_main.c | 110 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 120 insertions(+), 18 deletions(-) diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 43c3af056b67..aa2e69ea0b5a 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -1480,17 +1480,33 @@ ixl_if_multi_set(if_ctx_t ctx) struct ixl_pf *pf = iflib_get_softc(ctx); struct ixl_vsi *vsi = &pf->vsi; struct i40e_hw *hw = vsi->hw; + enum i40e_status_code status; int mcnt; + if_t ifp = iflib_get_ifp(ctx); IOCTL_DEBUGOUT("ixl_if_multi_set: begin"); /* Delete filters for removed multicast addresses */ ixl_del_multi(vsi, false); - mcnt = min(if_llmaddr_count(iflib_get_ifp(ctx)), MAX_MULTICAST_ADDR); + mcnt = min(if_llmaddr_count(ifp), MAX_MULTICAST_ADDR); if (__predict_false(mcnt == MAX_MULTICAST_ADDR)) { - i40e_aq_set_vsi_multicast_promiscuous(hw, + /* Check if promisc mode is already enabled, if yes return */ + if (vsi->flags & IXL_FLAGS_MC_PROMISC) + return; + + status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, TRUE, NULL); + if (status != I40E_SUCCESS) + if_printf(ifp, "Failed to enable multicast promiscuous " + "mode, status: %s\n", i40e_stat_str(hw, status)); + else { + if_printf(ifp, "Enabled multicast promiscuous mode\n"); + + /* Set the flag to track promiscuous mode */ + vsi->flags |= IXL_FLAGS_MC_PROMISC; + } + /* Delete all existing MC filters */ ixl_del_multi(vsi, true); return; } @@ -1693,6 +1709,13 @@ ixl_if_promisc_set(if_ctx_t ctx, int flags) return (err); err = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, multi, NULL); + + /* Update the multicast promiscuous flag based on the new state */ + if (multi) + vsi->flags |= IXL_FLAGS_MC_PROMISC; + else + vsi->flags &= ~IXL_FLAGS_MC_PROMISC; + return (err); } diff --git a/sys/dev/ixl/ixl.h b/sys/dev/ixl/ixl.h index 95379448b570..ab0f38307d90 100644 --- a/sys/dev/ixl/ixl.h +++ b/sys/dev/ixl/ixl.h @@ -202,6 +202,7 @@ #define IXL_FLAGS_KEEP_TSO6 (1 << 1) #define IXL_FLAGS_USES_MSIX (1 << 2) #define IXL_FLAGS_IS_VF (1 << 3) +#define IXL_FLAGS_MC_PROMISC (1 << 4) #define IXL_VSI_IS_PF(v) ((v->flags & IXL_FLAGS_IS_VF) == 0) #define IXL_VSI_IS_VF(v) ((v->flags & IXL_FLAGS_IS_VF) != 0) diff --git a/sys/dev/ixl/ixl_pf_main.c b/sys/dev/ixl/ixl_pf_main.c index 1752efc02fff..b62619ced5cb 100644 --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -593,24 +593,29 @@ ixl_add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) * Routines for multicast and vlan filter management. * *********************************************************************/ + +/** + * ixl_add_multi - Add multicast filters to the hardware + * @vsi: The VSI structure + * + * In case number of multicast filters in the IFP exceeds 127 entries, + * multicast promiscuous mode will be enabled and the filters will be removed + * from the hardware + */ void ixl_add_multi(struct ixl_vsi *vsi) { if_t ifp = vsi->ifp; - struct i40e_hw *hw = vsi->hw; int mcnt = 0; struct ixl_add_maddr_arg cb_arg; IOCTL_DEBUGOUT("ixl_add_multi: begin"); - mcnt = if_llmaddr_count(ifp); - if (__predict_false(mcnt >= MAX_MULTICAST_ADDR)) { - i40e_aq_set_vsi_multicast_promiscuous(hw, - vsi->seid, TRUE, NULL); - /* delete all existing MC filters */ - ixl_del_multi(vsi, true); - return; - } + /* + * There is no need to check if the number of multicast addresses + * exceeds the MAX_MULTICAST_ADDR threshold and set promiscuous mode + * here, as all callers already handle this case. + */ cb_arg.vsi = vsi; LIST_INIT(&cb_arg.to_add); @@ -633,30 +638,103 @@ ixl_match_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) return (0); } +/** + * ixl_dis_multi_promisc - Disable multicast promiscuous mode + * @vsi: The VSI structure + * @vsi_mcnt: Number of multicast filters in the VSI + * + * Disable multicast promiscuous mode based on number of entries in the IFP + * and the VSI, then re-add multicast filters. + * + */ +static void +ixl_dis_multi_promisc(struct ixl_vsi *vsi, int vsi_mcnt) +{ + struct ifnet *ifp = vsi->ifp; + struct i40e_hw *hw = vsi->hw; + int ifp_mcnt = 0; + enum i40e_status_code status; + + /* + * Check if multicast promiscuous mode was actually enabled. + * If promiscuous mode was not enabled, don't attempt to disable it. + * Also, don't disable if IFF_PROMISC or IFF_ALLMULTI is set. + */ + if (!(vsi->flags & IXL_FLAGS_MC_PROMISC) || + (if_getflags(ifp) & (IFF_PROMISC | IFF_ALLMULTI))) + return; + + ifp_mcnt = if_llmaddr_count(ifp); + /* + * Equal lists or empty ifp list mean the list has not been changed + * and in such case avoid disabling multicast promiscuous mode as it + * was not previously enabled. Case where multicast promiscuous mode has + * been enabled is when vsi_mcnt == 0 && ifp_mcnt > 0. + */ + if (ifp_mcnt == vsi_mcnt || ifp_mcnt == 0 || + ifp_mcnt >= MAX_MULTICAST_ADDR) + return; + + status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, + FALSE, NULL); + if (status != I40E_SUCCESS) { + if_printf(ifp, "Failed to disable multicast promiscuous " + "mode, status: %s\n", i40e_stat_str(hw, status)); + + return; + } + + /* Clear the flag since promiscuous mode is now disabled */ + vsi->flags &= ~IXL_FLAGS_MC_PROMISC; + if_printf(ifp, "Disabled multicast promiscuous mode\n"); + + ixl_add_multi(vsi); +} + +/** + * ixl_del_multi - Delete multicast filters from the hardware + * @vsi: The VSI structure + * @all: Bool to determine if all the multicast filters should be removed + * + * In case number of multicast filters in the IFP drops to 127 entries, + * multicast promiscuous mode will be disabled and the filters will be reapplied + * to the hardware. + */ void ixl_del_multi(struct ixl_vsi *vsi, bool all) { - struct ixl_ftl_head to_del; + int to_del_cnt = 0, vsi_mcnt = 0; if_t ifp = vsi->ifp; struct ixl_mac_filter *f, *fn; - int mcnt = 0; + struct ixl_ftl_head to_del; IOCTL_DEBUGOUT("ixl_del_multi: begin"); LIST_INIT(&to_del); /* Search for removed multicast addresses */ LIST_FOREACH_SAFE(f, &vsi->ftl, ftle, fn) { - if ((f->flags & IXL_FILTER_MC) == 0 || - (!all && (if_foreach_llmaddr(ifp, ixl_match_maddr, f) == 0))) + if ((f->flags & IXL_FILTER_MC) == 0) + continue; + + /* Count all the multicast filters in the VSI for comparison */ + vsi_mcnt++; + + if (!all && if_foreach_llmaddr(ifp, ixl_match_maddr, f) != 0) continue; LIST_REMOVE(f, ftle); LIST_INSERT_HEAD(&to_del, f, ftle); - mcnt++; + to_del_cnt++; } - if (mcnt > 0) - ixl_del_hw_filters(vsi, &to_del, mcnt); + if (to_del_cnt > 0) { + ixl_del_hw_filters(vsi, &to_del, to_del_cnt); + return; + } + + ixl_dis_multi_promisc(vsi, vsi_mcnt); + + IOCTL_DEBUGOUT("ixl_del_multi: end"); } void