From nobody Fri Oct 31 21:01:43 2025 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 4cyth76Zttz6FCqD; Fri, 31 Oct 2025 21:01:43 +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 4cyth75sQnz3LRD; Fri, 31 Oct 2025 21:01:43 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1761944503; 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=tf+K0jU65zzHFrb8LKt0qj26qYTkFwytGRU2UM/7FUk=; b=s7NDb/XzsCOl4BomxWVWGzxJzatkPxmsjyPcVvdqdcT0p1N93hVY9LCYy81UHSMPU5ZHs1 jIriil+yAKeRoMl/iyeN/Sefd9IMVOpMJ3Yv7Df5gvhe7/1EtnyHFcfRjQS3BcVQJeHUIo BYJhkNAj0fqwKtPaN/FgbiSVv4wRedCwKEjOsMbW3TGqBo2ZnqjJsu3cIyOXXGhvqomHZL oxKODFxS5QQ7LP+eDVhJHFgYv/HKL4OSmBHFrhw5Rh8GHEDQR+rgNORjtuEbQEWuTpfGPV jibh+egrvRWG5fWDds23Kshl77KnLvE/2x4gi30oGEYbap8zwbRlVB2xhFjEjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1761944503; 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=tf+K0jU65zzHFrb8LKt0qj26qYTkFwytGRU2UM/7FUk=; b=aZ+enoPXSkjrenmiaj9DNVV8f14QFDSCq0EHE+0zuv44/hNNJQj49YRjWG92NkRxOwEl7G KoSBkE3Qolu3P+V3ebJID1H7/PuK4q8LHgkFaolwQ5plicpMz3m02i6oFFeDqOGjX9mD89 a3gzbRWZ007ek3CZ0aSX+zzH9rkT6M+WKxJf7ZNMX46SQ2YzfX7evGHD19xaFizYw8nckk /+2u9sqaIoFT/BHVr3BMnxIjLC4KBWvy5zzBzVrkEYjDnDv+hxrjnqKs6NPxslS0YTDxLk T3O6s0ejSUFIs1dk8ZjtLyKjOm07fghsADSIifYEOM3+/aCs3AghmErx3oTBuw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1761944503; a=rsa-sha256; cv=none; b=a8vHGXegZnNgy32ITFt/nk8GWGw7+Us0BHlcSJHe64PENpdvMrr1rxYiXYnMaGV1trZddT R8HW5k5o/JelUn6a8np7qnEFXyuscSNEDxFDtuuf1ysAGz6YKTF2wUVeMyDdJHUbcxB0sR m/STXz4VoZYuOtXaa5IkoJ13fznRjyln45jdjznMme+yGpp1r4E0rxadshipkb5zTQ7lTm OHJx6AA83NPQXnM3bLlgKOupYi703X7HD/dD7ewS9Y26BeygNo5Gs06rhSeSkEpoOBPMv/ hJTrcz0KQoOZ8xnZ4X//Fec9hNH0cjlegl9hjb7rtYpo//y3YXPYLhxx2a5PNA== 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 4cyth75CDjz1NhZ; Fri, 31 Oct 2025 21:01:43 +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 59VL1hef084041; Fri, 31 Oct 2025 21:01:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 59VL1hXs084038; Fri, 31 Oct 2025 21:01:43 GMT (envelope-from git) Date: Fri, 31 Oct 2025 21:01:43 GMT Message-Id: <202510312101.59VL1hXs084038@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: b2b2a4788f79 - stable/14 - ixl(4): fix multicast promiscuous mode state tracking and filter management 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 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/14 X-Git-Reftype: branch X-Git-Commit: b2b2a4788f7925f41d902df6b7f3d19bccd6f42f Auto-Submitted: auto-generated The branch stable/14 has been updated by kgalazka: URL: https://cgit.FreeBSD.org/src/commit/?id=b2b2a4788f7925f41d902df6b7f3d19bccd6f42f commit b2b2a4788f7925f41d902df6b7f3d19bccd6f42f Author: Bhosale, Yogesh AuthorDate: 2025-10-16 20:02:45 +0000 Commit: Krzysztof Galazka CommitDate: 2025-10-31 20:57:48 +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 f45354d29300..69925a131b35 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 4f384e7191af..99851af61cfe 100644 --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -592,24 +592,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); @@ -632,30 +637,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