From: Petr Oros <poros@redhat.com>
To: Simon Horman <horms@kernel.org>
Cc: netdev@vger.kernel.org, aleksandr.loktionov@intel.com
Subject: Re: [PATCH iwl-net v2 1/2] ice: skip per-VLAN promisc rules when default VSI Rx rule is set
Date: Mon, 29 Jun 2026 14:06:41 +0200 [thread overview]
Message-ID: <3af161de-b79a-49dc-a2fa-48e182b1c626@redhat.com> (raw)
In-Reply-To: <20260623162526.1099096-2-horms@kernel.org>
On 6/23/26 18:25, Simon Horman wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> Full review at: https://sashiko.dev
> ---
> Subject: ice: skip per-VLAN promisc rules when default VSI Rx rule is set
>
> This patch optimizes the number of hardware switch rules used when an ice
> port is part of a vlan-filtering bridge. It avoids installing per-VLAN
> promiscuous rules if the broad default VSI Rx rule is already catching
> all traffic.
>
>> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
>> index e2fbe111f8496..efb1f536de6c7 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_main.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> [ ... ]
>> @@ -442,17 +496,12 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
> [Severity: High]
> This is a pre-existing issue, but does MAC filter overflow fail to force
> promiscuous mode, resulting in silent packet drops?
Pre-existing; the promisc_forced_on fallback is not changed by this patch.
>
> When the hardware MAC filter limit is reached (LIBIE_AQ_RC_ENOSPC), the driver
> attempts to fall back to promiscuous mode by setting promisc_forced_on = true.
>
> However, the execution flow then reaches a check for IFF_PROMISC:
>
> if (vsi->current_netdev_flags & IFF_PROMISC) {
> /* Apply Rx filter rule to get traffic from wire */
> ...
> } else {
> /* Clear Rx filter to remove traffic from wire */
>
> Since the user never explicitly requested IFF_PROMISC, this evaluates to false,
> causing the driver to take the else branch. The else branch actively disables
> the default VSI rule and clears promiscuous mode instead of enabling it. The
> fallback feature appears to be non-functional, leading to lost traffic for
> newly added MACs.
>
> [Severity: High]
> This is a pre-existing issue, but could this function prevent retries of
> incomplete configurations and break multicast promiscuity if any default
> VSI is already active?
v3 will address the multicast half: ice_set_promisc(ICE_MCAST_PROMISC_BITS)
will be issued whenever the netdev is promiscuous, not only inside the
!ice_is_dflt_vsi_in_use() branch.
>
> In ice_vsi_sync_fltr(), the setup of multicast promiscuity and disabling of
> Rx filtering is gated:
>
> if (!ice_is_dflt_vsi_in_use(vsi->port_info)) {
> err = ice_set_dflt_vsi(vsi);
> ...
> err = ice_set_promisc(vsi, ICE_MCAST_PROMISC_BITS);
> if (err)
> goto out_promisc;
> }
>
> If ice_set_dflt_vsi() succeeds but the subsequent ice_set_promisc() fails,
> the function jumps to out_promisc to trigger a retry. On the next cycle,
> ice_is_dflt_vsi_in_use() returns true because this VSI is now the default,
> causing the entire block to be skipped and leaving the VSI misconfigured.
>
> Furthermore, if another VSI (such as a VF) is already the default VSI,
> the PF VSI entirely skips setting multicast promiscuity, breaking multicast
> reception in promiscuous mode.
>
>> } else {
>> /* Clear Rx filter to remove traffic from wire */
>> if (ice_is_vsi_dflt_vsi(vsi)) {
>> - err = ice_clear_dflt_vsi(vsi);
>> + err = ice_vsi_exit_dflt_promisc(vsi);
>> if (err) {
>> - netdev_err(netdev, "Error %d clearing default VSI %i Rx rule\n",
>> - err, vsi->vsi_num);
>> vsi->current_netdev_flags |=
>> IFF_PROMISC;
>> goto out_promisc;
>> }
>> - if (vsi->netdev->features &
>> - NETIF_F_HW_VLAN_CTAG_FILTER)
>> - vlan_ops->ena_rx_filtering(vsi);
>> }
> [ ... ]
>> @@ -3675,10 +3724,9 @@ int ice_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
>> while (test_and_set_bit(ICE_CFG_BUSY, vsi->state))
>> usleep_range(1000, 2000);
> [Severity: High]
> This is a pre-existing issue, but isn't there a risk of TOCTOU races with
> this ad-hoc lock pattern lacking memory barriers?
Pre-existing; the ICE_CFG_BUSY locking is not changed by this patch.
>
> The driver spins on ICE_CFG_BUSY using test_and_set_bit() and usleep_range()
> to guard VSI filter synchronization. The lock is subsequently dropped using
> clear_bit(ICE_CFG_BUSY, vsi->state) at the exit label.
>
> Because clear_bit() lacks a memory release barrier, the CPU or compiler can
> reorder memory stores from the critical section to occur after the flag is
> cleared, leading to data races and corruption of shared filter state on
> weakly ordered architectures.
>
>> - /* Add multicast promisc rule for the VLAN ID to be added if
>> - * all-multicast is currently enabled.
>> - */
>> - if (vsi->current_netdev_flags & IFF_ALLMULTI) {
>> + /* skip the per-VID rule when the DFLT Rx rule already covers this VID */
>> + if ((vsi->current_netdev_flags & IFF_ALLMULTI) &&
>> + !ice_is_vsi_dflt_vsi(vsi)) {
>> ret = ice_fltr_set_vsi_promisc(&vsi->back->hw, vsi->idx,
>> ICE_MCAST_VLAN_PROMISC_BITS,
>> vid);
>> @@ -3696,11 +3744,12 @@ int ice_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
>> if (ret)
>> goto finish;
> [Severity: High]
> This is a pre-existing issue, but what happens if vlan_ops->add_vlan()
> fails here? Is the hardware switch rule leaked?
Pre-existing; the add_vlan() error unwind is not changed by this patch.
>
> When adding a VLAN to an interface with IFF_ALLMULTI enabled, this function
> first allocates a promiscuous switch rule in hardware via
> ice_fltr_set_vsi_promisc().
>
> If this succeeds but the subsequent call to vlan_ops->add_vlan() fails
> (e.g., due to ENOSPC or memory allocation failure), the function returns
> early without rolling back the promiscuous rule. Because the network stack
> considers the VLAN addition to have failed, ice_vlan_rx_kill_vid() will
> never be called for this VID, permanently leaking a Flow Lookup Unit (FLU).
>
>> - /* If all-multicast is currently enabled and this VLAN ID is only one
>> - * besides VLAN-0 we have to update look-up type of multicast promisc
>> - * rule for VLAN-0 from ICE_SW_LKUP_PROMISC to ICE_SW_LKUP_PROMISC_VLAN.
>> + /* On the first non-zero VLAN, promote the VLAN-0 multicast promisc
>> + * rule from ICE_SW_LKUP_PROMISC to ICE_SW_LKUP_PROMISC_VLAN. Skip when
>> + * the DFLT Rx rule is installed; it already covers every VID.
>> */
>> if ((vsi->current_netdev_flags & IFF_ALLMULTI) &&
>> + !ice_is_vsi_dflt_vsi(vsi) &&
>> ice_vsi_num_non_zero_vlans(vsi) == 1) {
> [ ... ]
>> @@ -3763,11 +3812,12 @@ int ice_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
>> ICE_MCAST_VLAN_PROMISC_BITS, vid);
>>
>> if (!ice_vsi_has_non_zero_vlans(vsi)) {
>> - /* Update look-up type of multicast promisc rule for VLAN 0
>> - * from ICE_SW_LKUP_PROMISC_VLAN to ICE_SW_LKUP_PROMISC when
>> - * all-multicast is enabled and VLAN 0 is the only VLAN rule.
>> + /* Last non-zero VLAN gone: demote the VLAN-0 multicast promisc
>> + * rule back to ICE_SW_LKUP_PROMISC. Skip when the DFLT Rx rule
>> + * is installed; no recipe swap is needed.
>> */
>> - if (vsi->current_netdev_flags & IFF_ALLMULTI) {
>> + if ((vsi->current_netdev_flags & IFF_ALLMULTI) &&
>> + !ice_is_vsi_dflt_vsi(vsi)) {
> [Severity: High]
> Will this modification cause a stale switch rule (ICE_SW_LKUP_PROMISC_VLAN for
> vid=0) to be permanently leaked if the last VLAN is removed while the DFLT VSI
> rule is active?
Real, and introduced by v1/v2. v3 will drop the two vid=0 recipe-swap
guards, so the rule is demoted back to ICE_SW_LKUP_PROMISC when the last
VLAN is removed and never stranded.
Petr
>
> This patch skips demoting the vid=0 multicast promiscuous rule from
> ICE_SW_LKUP_PROMISC_VLAN back to ICE_SW_LKUP_PROMISC when the last VLAN is
> removed, if ice_is_vsi_dflt_vsi(vsi) is true.
>
> However, if the interface later drops IFF_PROMISC (removing the DFLT VSI rule)
> and then drops IFF_ALLMULTI, ice_clear_promisc() is called. Because the
> interface now has zero VLANs, ice_clear_promisc() executes its else branch:
>
> } else {
> status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
> promisc_m, 0);
> }
>
> This only searches and clears rules from the ICE_SW_LKUP_PROMISC recipe. The
> stranded rule in the ICE_SW_LKUP_PROMISC_VLAN recipe is never cleared,
> resulting in a permanent hardware switch rule leak.
>
>> ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
>> ICE_MCAST_VLAN_PROMISC_BITS,
>> 0);
next prev parent reply other threads:[~2026-06-29 12:09 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-22 11:34 [PATCH iwl-net v2 0/2] ice: fix DFLT Rx rule handling for promisc and switchdev Petr Oros
2026-06-22 11:34 ` [PATCH iwl-net v2 1/2] ice: skip per-VLAN promisc rules when default VSI Rx rule is set Petr Oros
2026-06-23 16:25 ` Simon Horman
2026-06-29 12:06 ` Petr Oros [this message]
2026-06-22 11:34 ` [PATCH iwl-net v2 2/2] ice: preserve uplink DFLT Rx rule on switchdev release Petr Oros
2026-06-23 16:25 ` Simon Horman
2026-06-29 13:21 ` Petr Oros
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3af161de-b79a-49dc-a2fa-48e182b1c626@redhat.com \
--to=poros@redhat.com \
--cc=aleksandr.loktionov@intel.com \
--cc=horms@kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox