* [PATCH net-next 1/3] mlxsw: Convert to async version of ndo_set_rx_mode
From: Ido Schimmel @ 2026-07-08 12:39 UTC (permalink / raw)
To: netdev; +Cc: davem, kuba, pabeni, edumazet, petrm, andrew+netdev, Ido Schimmel
In-Reply-To: <20260708123933.1303291-1-idosch@nvidia.com>
Commit c5b9b518adab ("mlxsw: spectrum: Add set_rx_mode ndo stub") added
a stub for ndo_set_rx_mode to prevent dev_ifsioc() from returning an
error for the SIOCADDMULTI and SIOCDELMULTI cases.
Since then dev_ifsioc() was taught to also accept ndo_set_rx_mode_async
and commit 3cbd22938877 ("net: warn ops-locked drivers still using
ndo_set_rx_mode") modified register_netdevice() to warn when registering
an ops-locked net device that still uses ndo_set_rx_mode instead of
ndo_set_rx_mode_async.
In preparation for converting the driver to be ops-locked, convert the
ndo_set_rx_mode stub to a ndo_set_rx_mode_async stub.
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 82569162d2e5..3ee1272dcf0e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -663,8 +663,11 @@ static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
-static void mlxsw_sp_set_rx_mode(struct net_device *dev)
+static int mlxsw_sp_set_rx_mode_async(struct net_device *dev,
+ struct netdev_hw_addr_list *uc,
+ struct netdev_hw_addr_list *mc)
{
+ return 0;
}
static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
@@ -1191,7 +1194,7 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
.ndo_stop = mlxsw_sp_port_stop,
.ndo_start_xmit = mlxsw_sp_port_xmit,
.ndo_setup_tc = mlxsw_sp_setup_tc,
- .ndo_set_rx_mode = mlxsw_sp_set_rx_mode,
+ .ndo_set_rx_mode_async = mlxsw_sp_set_rx_mode_async,
.ndo_set_mac_address = mlxsw_sp_port_set_mac_address,
.ndo_change_mtu = mlxsw_sp_port_change_mtu,
.ndo_get_stats64 = mlxsw_sp_port_get_stats64,
--
2.54.0
^ permalink raw reply related
* Re: [PATCH net-next 00/11][pull request] Intel Wired LAN Driver Updates 2026-07-01 (igc, igb)
From: Paolo Abeni @ 2026-07-08 12:41 UTC (permalink / raw)
To: Tony Nguyen, davem, kuba, edumazet, andrew+netdev, netdev; +Cc: horms
In-Reply-To: <20260701210303.1745310-1-anthony.l.nguyen@intel.com>
On 7/1/26 11:02 PM, Tony Nguyen wrote:
> Kohei Enju adds ethtool support for get/set hash key on igc and adds
> setting of skb hash type based on values from Rx descriptor on igb.
>
> Takashi Kozu adds ethtool support for get/set hash key on igb.
>
> Faizal adds support for forcing link speed via ethtool when
> autonegotiation is disabled on the igc driver.
>
> The following are changes since commit d6e81529749190123aa0040626c7e5dbc20fdc9a:
> Merge branch 'net-fib_rules-rtnl-less-rtm_newrule-and-rtm_delrule'
> and are available in the git repository at:
> git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue 1GbE
Sashiko gemini has some comments, please follow-up with them as needed:
https://sashiko.dev/#/patchset/20260701210303.1745310-1-anthony.l.nguyen%40intel.com
/P
^ permalink raw reply
* [PATCH net-next 2/3] mlxsw: ethtool: Prepare for RTNL-less ethtool operations
From: Ido Schimmel @ 2026-07-08 12:39 UTC (permalink / raw)
To: netdev; +Cc: davem, kuba, pabeni, edumazet, petrm, andrew+netdev, Ido Schimmel
In-Reply-To: <20260708123933.1303291-1-idosch@nvidia.com>
A subsequent patch is going to make the driver ops-locked and allow
ethtool operations to run without RTNL. In preparation for this change,
tell the core about a couple of ethtool operations that should remain
under RTNL:
1. Set pause parameters: Configures the port's headroom buffer which is
also configured by RTNL-only paths such as DCB and qdisc. These paths
can probably be converted to acquire the netdev instance lock, but this
operation in not frequently called (unlike stats query), so avoid the
added complexity for now.
2. Get link state: Calls ethtool_op_get_link() which requires RTNL. See
commit 1105ef941c1a ("net: ethtool: keep rtnl_lock for ops using
ethtool_op_get_link()").
All the other operations do not access shared resources, do not invoke
helpers that require RTNL or already have the appropriate locking in
place.
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
index 7f78b1ef61cc..3bdb532d833b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
@@ -1262,6 +1262,8 @@ mlxsw_sp_set_module_power_mode(struct net_device *dev,
const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
.cap_link_lanes_supported = true,
+ .op_needs_rtnl = ETHTOOL_OP_NEEDS_RTNL_SPAUSEPARAM |
+ ETHTOOL_OP_NEEDS_RTNL_GLINK,
.get_drvinfo = mlxsw_sp_port_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_link_ext_state = mlxsw_sp_port_get_link_ext_state,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 3/3] mlxsw: Tell the core to use the netdev instance lock
From: Ido Schimmel @ 2026-07-08 12:39 UTC (permalink / raw)
To: netdev; +Cc: davem, kuba, pabeni, edumazet, petrm, andrew+netdev, Ido Schimmel
In-Reply-To: <20260708123933.1303291-1-idosch@nvidia.com>
After the previous changes the driver is now ready to have its net
device and ethtool operations invoked with the netdev instance lock
held.
Tell the core about it by setting request_ops_lock to true.
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 3ee1272dcf0e..815e8d8e3185 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -1552,6 +1552,7 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u16 local_port,
dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
dev->lltx = true;
dev->netns_immutable = true;
+ dev->request_ops_lock = true;
dev->min_mtu = ETH_MIN_MTU;
dev->max_mtu = MLXSW_PORT_MAX_MTU - MLXSW_PORT_ETH_FRAME_HDR;
--
2.54.0
^ permalink raw reply related
* Re: [Intel-wired-lan] [PATCH iwl-net v3 1/2] ice: skip per-VLAN promisc rules when default VSI Rx rule is set
From: Petr Oros @ 2026-07-08 12:44 UTC (permalink / raw)
To: Marcin Szycik, netdev
Cc: Ivan Vecera, Alice Michael, Przemek Kitszel, Eric Dumazet,
linux-kernel, Martyna Szapar-Mudlaw, Andrew Lunn, Tony Nguyen,
Simon Horman, intel-wired-lan, Jacob Keller, Jakub Kicinski,
Paolo Abeni, David S. Miller
In-Reply-To: <f03d0930-9f51-45ad-9ed4-e9df335b8fa7@linux.intel.com>
On 7/3/26 18:34, Marcin Szycik wrote:
>
> On 01.07.2026 15:36, Petr Oros wrote:
>> When an ice port in a vlan-filtering bridge goes promiscuous (typical for
>> bond slaves), the driver installs a per-VLAN ICE_SW_LKUP_PROMISC_VLAN rule
>> for every VID on top of the broad ICE_SW_LKUP_DFLT VSI Rx rule. Each rule
>> consumes one of the ~32K Flow Lookup Unit (FLU) entries the device shares
>> across PFs, so a wide trunk (vid 2-4094) over several PFs overruns the
>> pool: firmware rejects further Add Switch Rules with ENOSPC (AQ 0x10) and
>> the DFLT Rx rule itself fails to install:
>>
>> ice 0000:5c:00.1: Failed to set VSI 14 as the default forwarding
>> VSI, error -5
>> ice 0000:5c:00.1 ens1f1: Error -5 setting default VSI 14 Rx rule
>>
>> Once a switch context is overrun the retries can also come back as ENOENT
>> (AQ 0x2), which has misled triage toward a perceived recipe binding defect
>> rather than a capacity issue.
>>
>> The DFLT rule already catches every packet on the port regardless of VLAN
>> tag, so the per-VLAN promisc expansion is redundant while it is installed.
>> Skip it at the two sites that drive it, ice_set_promisc() and
>> ice_vlan_rx_add_vid(), keyed on ice_is_vsi_dflt_vsi() rather than the
>> netdev IFF_PROMISC flag so a failed or LAG-suppressed DFLT install still
>> falls back to the per-VLAN rules.
>>
>> IFF_ALLMULTI and IFF_PROMISC can reach ice_vsi_sync_fltr() in separate
>> passes (a bridge join sets them through separate calls), so the allmulti
>> pass may expand the per-VID rules before the DFLT rule exists. Drop those
>> now-redundant rules right after ice_set_dflt_vsi() installs the DFLT rule;
>> ice_vsi_exit_dflt_promisc() reinstates them when promisc is cleared.
>>
>> ice_vsi_sync_fltr() subscribed multicast promiscuity only inside the
>> "default VSI not yet in use" branch, so a promiscuous VSI that finds the
>> default VSI rule already present (owned by another VSI, or preserved
>> across a switchdev session) ended up in unicast promisc with no multicast
>> subscription. Issue ice_set_promisc(ICE_MCAST_PROMISC_BITS) whenever the
>> netdev is promiscuous; it is idempotent and returns 0 if the rule is
>> already present.
>>
>> Fixes: 1273f89578f2 ("ice: Fix broken IFF_ALLMULTI handling")
>> Signed-off-by: Petr Oros <poros@redhat.com>
>> ---
>> v3:
>> - Dropped the two vid=0 ICE_SW_LKUP_PROMISC <-> ICE_SW_LKUP_PROMISC_VLAN
>> recipe-swap guards in ice_vlan_rx_add_vid() and ice_vlan_rx_kill_vid();
>> each swap is net-zero and guarding the demote stranded the vid=0 rule
>> in ICE_SW_LKUP_PROMISC_VLAN when the last VLAN was removed under the
>> DFLT rule. Reported by review.
>> - Drop the now-redundant per-VID multicast promisc rules right after
>> ice_set_dflt_vsi(). A bridge join raises IFF_ALLMULTI and IFF_PROMISC
>> in separate sync passes, so the allmulti pass expands the per-VID rules
>> before the DFLT rule exists; the cleanup keeps them from lingering and
>> exhausting the FLU pool. ice_vsi_exit_dflt_promisc() reinstates them on
>> promisc off. Reported by review.
>> - Issue ice_set_promisc(ICE_MCAST_PROMISC_BITS) whenever the netdev is
>> promiscuous, not only when this VSI installs the default VSI rule, so
>> multicast promisc is not lost when the rule is already in use (owned by
>> another VSI, or preserved across a switchdev session). Reported by
>> review.
>> - Hoisted the combined VLAN promisc mask in ice_clear_promisc() into a
>> local for alignment. Dropped Aleksandr's Reviewed-by since the code
>> changed.
>>
>> v2: https://lore.kernel.org/all/20260622113428.2565255-2-poros@redhat.com/
>> v1: https://lore.kernel.org/all/89efbea9831175e6f57e9fe8557f7a0e48e050b7.1781786935.git.poros@redhat.com/
>> ---
>> drivers/net/ethernet/intel/ice/ice_main.c | 111 ++++++++++++++++++----
>> 1 file changed, 90 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
>> index b43d420ece99ca..a84de6cf6eb078 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_main.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
>> @@ -274,7 +274,8 @@ static int ice_set_promisc(struct ice_vsi *vsi, u8 promisc_m)
>> if (vsi->type != ICE_VSI_PF)
>> return 0;
>>
>> - if (ice_vsi_has_non_zero_vlans(vsi)) {
>> + /* skip per-VID expansion; the DFLT Rx rule already covers every VID */
>> + if (ice_vsi_has_non_zero_vlans(vsi) && !ice_is_vsi_dflt_vsi(vsi)) {
>> promisc_m |= (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX);
>> status = ice_fltr_set_vlan_vsi_promisc(&vsi->back->hw, vsi,
>> promisc_m);
>> @@ -304,9 +305,20 @@ static int ice_clear_promisc(struct ice_vsi *vsi, u8 promisc_m)
>> return 0;
>>
>> if (ice_vsi_has_non_zero_vlans(vsi)) {
>> - promisc_m |= (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX);
>> + u8 vlan_promisc_m = promisc_m | ICE_PROMISC_VLAN_RX |
>> + ICE_PROMISC_VLAN_TX;
>> + int vid0_status;
>> +
>> + /* set time used either recipe (per-VID PROMISC_VLAN, or vid=0
> I find this sentence hard to understand - did you mean "ice_set_promisc() used
> either recipe..."?
>
>> + * PROMISC via the ice_set_promisc() else branch), so clear
>> + * both; clearing an absent rule succeeds
> What do you mean by this? Both will return -EEXIST if rule is absent. There can
> also be other errors.
>
>> + */
>> status = ice_fltr_clear_vlan_vsi_promisc(&vsi->back->hw, vsi,
>> - promisc_m);
>> + vlan_promisc_m);
>> + vid0_status = ice_fltr_clear_vsi_promisc(&vsi->back->hw,
>> + vsi->idx, promisc_m, 0);
>> + if (status == 0)
>> + status = vid0_status;
>> } else {
>> status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
>> promisc_m, 0);
>> @@ -317,6 +329,59 @@ static int ice_clear_promisc(struct ice_vsi *vsi, u8 promisc_m)
>> return status;
>> }
>>
>> +/**
>> + * ice_vsi_exit_dflt_promisc - drop the default VSI Rx rule on promisc off
>> + * @vsi: the VSI leaving promiscuous mode
>> + *
>> + * For an IFF_ALLMULTI VSI with VLANs the per-VID multicast rules are
>> + * reinstated before the default rule is cleared so coverage never lapses;
>> + * the then redundant vid=0 rule is dropped best-effort. The callees log
>> + * their own failures, so error returns are not re-logged here.
>> + *
>> + * Return: 0 on success, negative on error with the default rule left in place.
>> + */
>> +static int ice_vsi_exit_dflt_promisc(struct ice_vsi *vsi)
>> +{
>> + struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
>> + struct net_device *netdev = vsi->netdev;
>> + struct ice_hw *hw = &vsi->back->hw;
>> + bool restore_mc;
>> + int err;
>> +
>> + restore_mc = (vsi->current_netdev_flags & IFF_ALLMULTI) &&
>> + ice_vsi_has_non_zero_vlans(vsi);
>> +
>> + if (restore_mc) {
>> + err = ice_fltr_set_vlan_vsi_promisc(hw, vsi,
>> + ICE_MCAST_VLAN_PROMISC_BITS);
>> + if (err && err != -EEXIST)
>> + return err;
>> + }
>> +
>> + err = ice_clear_dflt_vsi(vsi);
>> + if (err)
>> + return err;
>> +
>> + if (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
>> + vlan_ops->ena_rx_filtering(vsi);
>> +
>> + if (restore_mc)
>> + ice_fltr_clear_vsi_promisc(hw, vsi->idx, ICE_MCAST_PROMISC_BITS,
>> + 0);
>> +
>> + return 0;
>> +}
>> +
>> +/* Drop the per-VID multicast promisc rules, redundant once the default
>> + * VSI Rx rule covers every VID. A no-op when the VSI has no VLANs.
>> + */
>> +static void ice_vsi_clear_vlan_mc_promisc(struct ice_vsi *vsi)
>> +{
>> + if (ice_vsi_has_non_zero_vlans(vsi))
> Nit: could flip condition to decrease indent level.
>
>> + ice_fltr_clear_vlan_vsi_promisc(&vsi->back->hw, vsi,
>> + ICE_MCAST_VLAN_PROMISC_BITS);
> Error code ignored, not sure if intentionally.
The ignored error code is intentional: it only drops rules made redundant
by the default VSI rule, and a leftover is harmless while that rule is
installed.
I will address all the comment/style points in v4.
Many thanks,
Petr
>
>> +}
>> +
>> /**
>> * ice_vsi_sync_fltr - Update the VSI filter list to the HW
>> * @vsi: ptr to the VSI
>> @@ -429,30 +494,35 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
>> err = 0;
>> vlan_ops->dis_rx_filtering(vsi);
>>
>> - /* promiscuous mode implies allmulticast so
>> - * that VSIs that are in promiscuous mode are
>> - * subscribed to multicast packets coming to
>> - * the port
>> + /* DFLT now covers every VID; drop the per-VID
>> + * multicast promisc rules a prior IFF_ALLMULTI
>> + * pass may have installed (separate passes on a
>> + * bridge join) so they do not linger and exhaust
>> + * the FLU pool. exit_dflt_promisc() reinstates
> Please use the full function name.
>
>> + * them on promisc off.
>> */
>> - err = ice_set_promisc(vsi,
>> - ICE_MCAST_PROMISC_BITS);
>> - if (err)
>> - goto out_promisc;
>> + ice_vsi_clear_vlan_mc_promisc(vsi);
>> }
>> +
>> + /* Promiscuous mode implies allmulticast. Subscribe
>> + * the VSI to all multicast even when the default VSI
>> + * rule is already in use and the block above is
>> + * skipped (it may be owned by another VSI, or
>> + * preserved across a switchdev session); the unicast
>> + * catch-all does not cover the multicast subscription.
>> + */
>> + err = ice_set_promisc(vsi, ICE_MCAST_PROMISC_BITS);
>> + if (err)
>> + goto out_promisc;
>> } 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);
>> }
>>
>> /* disable allmulti here, but only if allmulti is not
>> @@ -3676,10 +3746,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);
>>
>> - /* 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);
> Thanks,
> Marcin
>
^ permalink raw reply
* [PATCH net-next] net: ip6_tunnel: use tunnel parameters for fill_forward_path route lookup
From: Lorenzo Bianconi @ 2026-07-08 12:48 UTC (permalink / raw)
To: David Ahern, Ido Schimmel, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Pablo Neira Ayuso,
Florian Westphal
Cc: netdev, netfilter-devel, Lorenzo Bianconi
Pass source address, output interface and flowlabel (carrying TClass
and flow label) from the tunnel configuration to the flowi6 struct in
ip6_tnl_fill_forward_path(), aligning the route lookup with the slow
path in ipxip6_tnl_xmit().
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
net/ipv6/ip6_tunnel.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index bf8e40af60b0..557d8637ac57 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1847,6 +1847,10 @@ static int ip6_tnl_fill_forward_path(struct net_device_path_ctx *ctx,
struct ip6_tnl *t = netdev_priv(ctx->dev);
struct flowi6 fl6 = {
.daddr = t->parms.raddr,
+ .saddr = t->parms.laddr,
+ .flowi6_oif = t->parms.link,
+ .flowlabel = t->parms.flowinfo &
+ (IPV6_TCLASS_MASK | IPV6_FLOWLABEL_MASK),
};
struct dst_entry *dst;
int err;
---
base-commit: 08030ddb87b4c6c6a2c03c82731b5e188f02f5b9
change-id: 20260708-ip6ip6-route-lookup-fill_forward_path-9fc45a9118e9
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH v2 net 0/3] ipv4/ipv6: Fix UAF and memory leak in IGMP/MLD
From: patchwork-bot+netdevbpf @ 2026-07-08 12:50 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, kuba, pabeni, horms, kuniyu, idosch, dsahern, netdev,
eric.dumazet
In-Reply-To: <20260705181756.963063-1-edumazet@google.com>
Hello:
This series was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Sun, 5 Jul 2026 18:17:53 +0000 you wrote:
> This series addresses two potential UAF vulnerabilities
> and memory leaks in the IPv4 IGMP and IPv6 MLD subsystems.
>
> The first two patches fix a UAF where the packet receive path races with
> device teardown. If the device refcount has already hit 0 (but the memory
> is still held by RCU), incoming IGMP/MLD packets trying to schedule delayed
> work or timers would call refcount_inc() on the 0 refcount, triggering a
> warning and eventually leading to a UAF when the work runs after the device
> has been freed. This is fixed by introducing safe hold helpers using
> refcount_inc_not_zero(). In MLD, we also ensure we only enqueue the skb
> if we successfully acquired the device reference, to avoid leaking skbs
> when the device is being destroyed.
>
> [...]
Here is the summary with links:
- [v2,net,1/3] ipv4: igmp: Fix potential UAF in igmp_gq_start_timer()
https://git.kernel.org/netdev/net/c/7b19c0f81ed1
- [v2,net,2/3] ipv6: mcast: Fix potential UAF in MLD delayed work
https://git.kernel.org/netdev/net/c/9b26518b6896
- [v2,net,3/3] ipv4: igmp: Fix potential memory leaks in igmp_mod_timer() and igmp_stop_timer()
https://git.kernel.org/netdev/net/c/3546deaa0c30
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [PATCH bpf-next 0/1] selftests: drv-net: XDP RX checksum metadata test
From: Vladimir Vdovin @ 2026-07-08 12:51 UTC (permalink / raw)
To: lorenzo
Cc: sdf, kuba, andrii, ast, daniel, hawk, john.fastabend, martin.lau,
sdf.kernel, bpf, netdev, Vladimir Vdovin
In-Reply-To: <akZ7QPfn83OUx5Vm@lore-desk>
Hi Lorenzo,
Here is the driver selftest for your XDP RX checksum series, as
discussed. It is written against your b4/bpf-xdp-meta-rxcksum branch
(the bitmask ip_summed + cksum/cksum_level API) and applies on top of
it rebased onto net-next, since the drv-net xdp_metadata.py test it
extends only exists there. Feel free to pick it straight into v4.
It adds an xdp_rx_csum program to xdp_metadata.bpf.o and two cases
gated on the "checksum" xdp-rx-metadata feature (SKIP on devices
without it, e.g. netdevsim):
- xdp_rx_csum_valid (tcp/udp variants): traffic with a correct
checksum from the remote endpoint must be reported with a usable
verdict (CHECKSUM_UNNECESSARY and/or CHECKSUM_COMPLETE);
- xdp_rx_csum_invalid: UDP with a corrupted L4 checksum (net/lib
csum -E) must not be reported as CHECKSUM_UNNECESSARY.
One question on the invalid case: I assert only that UNNECESSARY is not
set for a corrupted checksum (COMPLETE may still legitimately be
reported, since it carries the raw sum for wrong packets too). Is that
the documented expectation you and Jakub want the test to encode, or
should it be stricter?
Thanks,
Vladimir
Vladimir Vdovin (1):
selftests: drv-net: add XDP RX checksum metadata tests
.../selftests/drivers/net/hw/xdp_metadata.py | 103 ++++++++++++++++
.../selftests/net/lib/xdp_metadata.bpf.c | 112 ++++++++++++++++--
2 files changed, 202 insertions(+), 13 deletions(-)
--
2.47.0
^ permalink raw reply
* [PATCH bpf-next 1/1] selftests: drv-net: add XDP RX checksum metadata tests
From: Vladimir Vdovin @ 2026-07-08 12:51 UTC (permalink / raw)
To: lorenzo
Cc: sdf, kuba, andrii, ast, daniel, hawk, john.fastabend, martin.lau,
sdf.kernel, bpf, netdev, Vladimir Vdovin
In-Reply-To: <cover.1783514455.git.deliran@verdict.gg>
Extend the xdp_metadata.py driver test with coverage for
bpf_xdp_metadata_rx_checksum().
Add an xdp_rx_csum program to xdp_metadata.bpf.o that reads the RX
checksum verdict and stores the ip_summed bitmask, the hw checksum
value and the checksum level into a map. The L4 port/protocol filter
is the same as in the existing xdp_rss_hash program, so move it into a
common helper.
The new cases only run on devices whose driver implements the
xmo_rx_checksum callback, detected through the "checksum" bit of the
xdp-rx-metadata-features netlink attribute; on other devices they
report SKIP:
- xdp_rx_csum_valid (tcp/udp variants): traffic with a correct
checksum sent from the remote endpoint must be reported with a
usable verdict, i.e. CHECKSUM_UNNECESSARY and/or CHECKSUM_COMPLETE;
- xdp_rx_csum_invalid: UDP packets with a corrupted L4 checksum
(sent with the net/lib csum tool) must not be reported as
CHECKSUM_UNNECESSARY.
Signed-off-by: Vladimir Vdovin <deliran@verdict.gg>
---
.../selftests/drivers/net/hw/xdp_metadata.py | 103 ++++++++++++++++
.../selftests/net/lib/xdp_metadata.bpf.c | 112 ++++++++++++++++--
2 files changed, 202 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/xdp_metadata.py b/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
index 33a1985356d9..687c43a1797a 100644
--- a/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
+++ b/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
@@ -8,6 +8,8 @@ These tests load device-bound XDP programs from xdp_metadata.bpf.o
that call metadata kfuncs, send traffic, and verify the extracted
metadata via BPF maps.
"""
+import time
+
from lib.py import ksft_run, ksft_eq, ksft_exit, ksft_ge, ksft_ne, ksft_pr
from lib.py import KsftNamedVariant, ksft_variants
from lib.py import CmdExitFailure, KsftSkipEx, NetDrvEpEnv
@@ -81,8 +83,22 @@ _RSS_KEY_TYPE = 1
_RSS_KEY_PKT_CNT = 2
_RSS_KEY_ERR_CNT = 3
+_CSUM_KEY_IP_SUMMED = 0
+_CSUM_KEY_CKSUM = 1
+_CSUM_KEY_LEVEL = 2
+_CSUM_KEY_PKT_CNT = 3
+_CSUM_KEY_ERR_CNT = 4
+
XDP_RSS_L4 = 0x8 # BIT(3) from enum xdp_rss_hash_type
+# Mirror of enum xdp_checksum from include/net/xdp.h
+XDP_CHECKSUM_NONE = 0x1
+XDP_CHECKSUM_UNNECESSARY = 0x2
+XDP_CHECKSUM_COMPLETE = 0x4
+
+# Fixed destination port of the net/lib csum tool
+_CSUM_TOOL_PORT = 34000
+
@ksft_variants([
KsftNamedVariant("tcp", "tcp"),
@@ -130,6 +146,91 @@ def test_xdp_rss_hash(cfg, proto):
f"RSS hash type should include L4 for {proto.upper()} traffic")
+def _require_rx_csum_meta(cfg):
+ """Skip unless the device exposes XDP RX checksum metadata."""
+ dev_info = cfg.netnl.dev_get({"ifindex": cfg.ifindex})
+ rx_meta = dev_info.get("xdp-rx-metadata-features", [])
+ if "checksum" not in rx_meta:
+ raise KsftSkipEx("device does not support XDP rx checksum metadata")
+
+
+@ksft_variants([
+ KsftNamedVariant("tcp", "tcp"),
+ KsftNamedVariant("udp", "udp"),
+])
+def test_xdp_rx_csum_valid(cfg, proto):
+ """Test RX checksum metadata for packets with a correct checksum.
+
+ Loads the xdp_rx_csum program, sends traffic with a valid L4 checksum
+ from the remote endpoint, and verifies that the device reported a
+ usable checksum verdict (CHECKSUM_UNNECESSARY and/or a
+ CHECKSUM_COMPLETE value) via bpf_xdp_metadata_rx_checksum().
+ """
+ _require_rx_csum_meta(cfg)
+
+ prog_info = _load_xdp_metadata_prog(cfg, "xdp_rx_csum")
+
+ port = rand_port()
+ bpf_map_set("map_xdp_setup", _SETUP_KEY_PORT, port)
+
+ csum_map_id = prog_info["maps"]["map_csum"]
+
+ _send_probe(cfg, port, proto=proto)
+
+ csum = bpf_map_dump(csum_map_id)
+
+ pkt_cnt = csum.get(_CSUM_KEY_PKT_CNT, 0)
+ err_cnt = csum.get(_CSUM_KEY_ERR_CNT, 0)
+ ip_summed = csum.get(_CSUM_KEY_IP_SUMMED, 0)
+
+ ksft_ge(pkt_cnt, 1, comment="should have received at least one packet")
+ ksft_eq(err_cnt, 0, comment=f"RX checksum error count: {err_cnt}")
+
+ ksft_pr(f" ip_summed: {ip_summed:#x} cksum: "
+ f"{csum.get(_CSUM_KEY_CKSUM, 0):#010x} "
+ f"level: {csum.get(_CSUM_KEY_LEVEL, 0)}")
+ ksft_ne(ip_summed & (XDP_CHECKSUM_UNNECESSARY | XDP_CHECKSUM_COMPLETE), 0,
+ "device should report a checksum verdict for a valid packet")
+
+
+def test_xdp_rx_csum_invalid(cfg):
+ """Test RX checksum metadata for packets with a corrupted checksum.
+
+ Sends UDP packets with an intentionally bad L4 checksum using the
+ net/lib csum tool and verifies the device does not claim it validated
+ them: the CHECKSUM_UNNECESSARY bit must not be set.
+ """
+ _require_rx_csum_meta(cfg)
+
+ ipver = cfg.addr_ipver
+ bin_remote = cfg.remote.deploy(cfg.net_lib_dir / "csum")
+
+ prog_info = _load_xdp_metadata_prog(cfg, "xdp_rx_csum")
+
+ bpf_map_set("map_xdp_setup", _SETUP_KEY_PORT, _CSUM_TOOL_PORT)
+
+ csum_map_id = prog_info["maps"]["map_csum"]
+
+ cmd(f"{bin_remote} -i {cfg.remote_ifname} -n 20 -{ipver} "
+ f"-S {cfg.remote_addr} -D {cfg.addr} -r 1 -T -E",
+ host=cfg.remote)
+
+ # no receiver to synchronize against; let NAPI drain the last packets
+ time.sleep(1)
+
+ csum = bpf_map_dump(csum_map_id)
+
+ pkt_cnt = csum.get(_CSUM_KEY_PKT_CNT, 0)
+ ip_summed = csum.get(_CSUM_KEY_IP_SUMMED, 0)
+
+ ksft_ge(pkt_cnt, 1, comment="should have received at least one packet")
+
+ ksft_pr(f" ip_summed: {ip_summed:#x}")
+ ksft_eq(ip_summed & XDP_CHECKSUM_UNNECESSARY, 0,
+ "device must not report CHECKSUM_UNNECESSARY for a corrupted "
+ "checksum")
+
+
def main():
"""Run XDP metadata kfunc tests against a real device."""
with NetDrvEpEnv(__file__) as cfg:
@@ -137,6 +238,8 @@ def main():
ksft_run(
[
test_xdp_rss_hash,
+ test_xdp_rx_csum_valid,
+ test_xdp_rx_csum_invalid,
],
args=(cfg,))
ksft_exit()
diff --git a/tools/testing/selftests/net/lib/xdp_metadata.bpf.c b/tools/testing/selftests/net/lib/xdp_metadata.bpf.c
index f71f59215239..70decae0a663 100644
--- a/tools/testing/selftests/net/lib/xdp_metadata.bpf.c
+++ b/tools/testing/selftests/net/lib/xdp_metadata.bpf.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#include <stddef.h>
+#include <stdbool.h>
#include <linux/bpf.h>
#include <linux/in.h>
#include <linux/if_ether.h>
@@ -40,6 +41,24 @@ struct {
__uint(max_entries, 4);
} map_rss SEC(".maps");
+/* RX checksum results: key 0 = ip_summed bitmask, key 1 = hw cksum value,
+ * key 2 = cksum level, key 3 = packet count, key 4 = error count.
+ */
+enum {
+ CSUM_KEY_IP_SUMMED = 0,
+ CSUM_KEY_CKSUM = 1,
+ CSUM_KEY_LEVEL = 2,
+ CSUM_KEY_PKT_CNT = 3,
+ CSUM_KEY_ERR_CNT = 4,
+};
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __type(key, __u32);
+ __type(value, __u32);
+ __uint(max_entries, 5);
+} map_csum SEC(".maps");
+
/* Mirror of enum xdp_rss_hash_type from include/net/xdp.h.
* Needed because the enum is not part of UAPI headers.
*/
@@ -55,8 +74,20 @@ enum xdp_rss_hash_type {
XDP_RSS_L4_ICMP = 1U << 8,
};
+/* Mirror of enum xdp_checksum from include/net/xdp.h.
+ * Needed because the enum is not part of UAPI headers.
+ */
+enum xdp_checksum {
+ XDP_CHECKSUM_NONE = 1U << 0,
+ XDP_CHECKSUM_UNNECESSARY = 1U << 1,
+ XDP_CHECKSUM_COMPLETE = 1U << 2,
+};
+
extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash,
enum xdp_rss_hash_type *rss_type) __ksym;
+extern int bpf_xdp_metadata_rx_checksum(const struct xdp_md *ctx,
+ enum xdp_checksum *ip_summed,
+ __u32 *cksum, __u8 *cksum_level) __ksym;
static __always_inline __u16 get_dest_port(void *l4, void *data_end,
__u8 protocol)
@@ -78,41 +109,39 @@ static __always_inline __u16 get_dest_port(void *l4, void *data_end,
return 0;
}
-SEC("xdp")
-int xdp_rss_hash(struct xdp_md *ctx)
+/* Return true when the packet matches the L4 protocol and destination
+ * port configured in map_xdp_setup (zero/unset filters match anything).
+ */
+static __always_inline bool xdp_match_setup(struct xdp_md *ctx)
{
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
- enum xdp_rss_hash_type rss_type = 0;
struct ethhdr *eth = data;
__u8 l4_proto = 0;
- __u32 hash = 0;
- __u32 key, val;
void *l4 = NULL;
- __u32 *cnt;
- int ret;
+ __u32 key;
if ((void *)(eth + 1) > data_end)
- return XDP_PASS;
+ return false;
if (eth->h_proto == bpf_htons(ETH_P_IP)) {
struct iphdr *iph = (void *)(eth + 1);
if ((void *)(iph + 1) > data_end)
- return XDP_PASS;
+ return false;
l4_proto = iph->protocol;
l4 = (void *)(iph + 1);
} else if (eth->h_proto == bpf_htons(ETH_P_IPV6)) {
struct ipv6hdr *ip6h = (void *)(eth + 1);
if ((void *)(ip6h + 1) > data_end)
- return XDP_PASS;
+ return false;
l4_proto = ip6h->nexthdr;
l4 = (void *)(ip6h + 1);
}
if (!l4)
- return XDP_PASS;
+ return false;
/* Filter on the configured protocol (map_xdp_setup key XDP_PROTO).
* When set, only process packets matching the requested L4 protocol.
@@ -121,7 +150,7 @@ int xdp_rss_hash(struct xdp_md *ctx)
__s32 *proto_cfg = bpf_map_lookup_elem(&map_xdp_setup, &key);
if (proto_cfg && *proto_cfg != 0 && l4_proto != (__u8)*proto_cfg)
- return XDP_PASS;
+ return false;
/* Filter on the configured port (map_xdp_setup key XDP_PORT).
* Only applies to protocols with ports (UDP, TCP).
@@ -133,9 +162,24 @@ int xdp_rss_hash(struct xdp_md *ctx)
__u16 dest = get_dest_port(l4, data_end, l4_proto);
if (!dest || bpf_ntohs(dest) != (__u16)*port_cfg)
- return XDP_PASS;
+ return false;
}
+ return true;
+}
+
+SEC("xdp")
+int xdp_rss_hash(struct xdp_md *ctx)
+{
+ enum xdp_rss_hash_type rss_type = 0;
+ __u32 hash = 0;
+ __u32 key, val;
+ __u32 *cnt;
+ int ret;
+
+ if (!xdp_match_setup(ctx))
+ return XDP_PASS;
+
ret = bpf_xdp_metadata_rx_hash(ctx, &hash, &rss_type);
if (ret < 0) {
key = RSS_KEY_ERR_CNT;
@@ -160,4 +204,46 @@ int xdp_rss_hash(struct xdp_md *ctx)
return XDP_PASS;
}
+SEC("xdp")
+int xdp_rx_csum(struct xdp_md *ctx)
+{
+ enum xdp_checksum ip_summed = 0;
+ __u8 cksum_level = 0;
+ __u32 cksum = 0;
+ __u32 key, val;
+ __u32 *cnt;
+ int ret;
+
+ if (!xdp_match_setup(ctx))
+ return XDP_PASS;
+
+ ret = bpf_xdp_metadata_rx_checksum(ctx, &ip_summed, &cksum,
+ &cksum_level);
+ if (ret < 0) {
+ key = CSUM_KEY_ERR_CNT;
+ cnt = bpf_map_lookup_elem(&map_csum, &key);
+ if (cnt)
+ __sync_fetch_and_add(cnt, 1);
+ return XDP_PASS;
+ }
+
+ key = CSUM_KEY_IP_SUMMED;
+ val = (__u32)ip_summed;
+ bpf_map_update_elem(&map_csum, &key, &val, BPF_ANY);
+
+ key = CSUM_KEY_CKSUM;
+ bpf_map_update_elem(&map_csum, &key, &cksum, BPF_ANY);
+
+ key = CSUM_KEY_LEVEL;
+ val = cksum_level;
+ bpf_map_update_elem(&map_csum, &key, &val, BPF_ANY);
+
+ key = CSUM_KEY_PKT_CNT;
+ cnt = bpf_map_lookup_elem(&map_csum, &key);
+ if (cnt)
+ __sync_fetch_and_add(cnt, 1);
+
+ return XDP_PASS;
+}
+
char _license[] SEC("license") = "GPL";
--
2.47.0
^ permalink raw reply related
* Re: [PATCH net] net: airoha: Fix DMA direction for NPU mailbox buffer
From: Lorenzo Bianconi @ 2026-07-08 12:57 UTC (permalink / raw)
To: Wayen Yan
Cc: netdev, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
In-Reply-To: <178351055214.98729.11403147818632027428@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2638 bytes --]
> airoha_npu_send_msg() always maps the mailbox buffer with DMA_TO_DEVICE,
> but some callers expect the NPU to write response data back into the
> same buffer:
>
> - airoha_npu_wlan_msg_get() (NPU_OP_GET): NPU writes response into
> the buffer, then the caller reads it via memcpy()
> - airoha_npu_ppe_stats_setup() (NPU_OP_SET): NPU writes back
> npu_stats_addr field in the response
>
> On non-cache-coherent architectures like EN7581 (Cortex-A53 without
> hardware cache coherency for NPU DMA), DMA_TO_DEVICE unmap is a no-op
> — it does not invalidate the CPU cache. If the NPU-written cache line
> is still present in the CPU cache when the caller reads the buffer,
> the CPU observes stale data instead of the NPU response.
>
> This is a timing-sensitive bug: small mailbox buffers (~24 bytes)
> typically fit in a single cache line and may survive in the cache
> until the caller reads them, producing silent data corruption rather
> than a crash. The bug is more likely to trigger when the caller reads
> the response immediately after dma_unmap_single() without intervening
> cache-evicting operations.
>
> Fix by using DMA_BIDIRECTIONAL for both map and unmap, which ensures
> dma_unmap_single() invalidates the CPU cache on non-coherent systems.
> The mailbox buffers are small so there is no performance concern.
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
>
> Fixes: c52918744ee1e49cea86622a2633b9782446428f ("net: airoha: npu: Move memory allocation in airoha_npu_send_msg() caller")
> Signed-off-by: Wayen Yan <win847@gmail.com>
> ---
> drivers/net/ethernet/airoha/airoha_npu.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c
> index 870d61fdd9c6..b679bed952de 100644
> --- a/drivers/net/ethernet/airoha/airoha_npu.c
> +++ b/drivers/net/ethernet/airoha/airoha_npu.c
> @@ -168,7 +168,7 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,
> dma_addr_t dma_addr;
> int ret;
>
> - dma_addr = dma_map_single(npu->dev, p, size, DMA_TO_DEVICE);
> + dma_addr = dma_map_single(npu->dev, p, size, DMA_BIDIRECTIONAL);
> ret = dma_mapping_error(npu->dev, dma_addr);
> if (ret)
> return ret;
> @@ -191,7 +191,7 @@ static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,
>
> spin_unlock_bh(&npu->cores[core].lock);
>
> - dma_unmap_single(npu->dev, dma_addr, size, DMA_TO_DEVICE);
> + dma_unmap_single(npu->dev, dma_addr, size, DMA_BIDIRECTIONAL);
>
> return ret;
> }
> --
> 2.51.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v3 04/12] net: mctp: usb: Improve IN endpoint status handling
From: Oliver Neukum @ 2026-07-08 12:57 UTC (permalink / raw)
To: Jeremy Kerr, Matt Johnston, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Greg Kroah-Hartman
Cc: netdev, linux-usb
In-Reply-To: <20260708-dev-mctp-usb-1-1-v3-4-9e710155cdbf@codeconstruct.com.au>
On 08.07.26 11:58, Jeremy Kerr wrote:
Hi,
> @@ -198,6 +254,8 @@ static int mctp_usb_open(struct net_device *dev)
> struct mctp_usb *mctp_usb = netdev_priv(dev);
>
> WRITE_ONCE(mctp_usb->rx_stopped, false);
> + mctp_usb->clear_halt = false;
> + mctp_usb->in_err_count = 0;
What allows the assumption that mctp_usb_open() does not race
with error handling? What happens if the device is still stalled?
It seems to me that you need to wait for the halt to be cleared.
Regards
Oliver
^ permalink raw reply
* [PATCH iwl-net v4 0/2] ice: fix DFLT Rx rule handling for promisc and switchdev
From: Petr Oros @ 2026-07-08 12:57 UTC (permalink / raw)
To: netdev
Cc: Petr Oros, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Alice Michael, Jacob Keller, Ivan Vecera, Simon Horman,
Martyna Szapar-Mudlaw, Marcin Szycik, intel-wired-lan,
linux-kernel
Two fixes for the uplink default VSI Rx rule (DFLT) on E810 when the
netdev is in IFF_PROMISC.
Patch 1 drops the redundant per-VLAN promisc expansion that exhausts
the FLU pool on a wide VLAN trunk across several PFs.
Patch 2 keeps the DFLT Rx rule across a switchdev teardown instead of
clobbering the promisc state the operator asked for.
Changes since v3 (review comments from Marcin Szycik):
- Patch 1: reworded the ice_clear_promisc() and the per-VID cleanup
comments, and flipped the ice_vsi_clear_vlan_mc_promisc() guard to an
early return (noting the clear is best-effort). No functional change.
- Patch 2: no change, added Marcin's and Aleksandr's Reviewed-by.
Link to v3:
https://lore.kernel.org/all/20260701133601.2118382-1-poros@redhat.com/
Link to v2:
https://lore.kernel.org/all/20260622113428.2565255-1-poros@redhat.com/
Link to v1:
https://lore.kernel.org/all/cover.1781786935.git.poros@redhat.com/
Petr Oros (2):
ice: skip per-VLAN promisc rules when default VSI Rx rule is set
ice: preserve uplink DFLT Rx rule on switchdev release
drivers/net/ethernet/intel/ice/ice_eswitch.c | 18 ++-
drivers/net/ethernet/intel/ice/ice_main.c | 109 +++++++++++++++----
2 files changed, 102 insertions(+), 25 deletions(-)
--
2.54.0
^ permalink raw reply
* [PATCH iwl-net v4 1/2] ice: skip per-VLAN promisc rules when default VSI Rx rule is set
From: Petr Oros @ 2026-07-08 12:57 UTC (permalink / raw)
To: netdev
Cc: Petr Oros, Tony Nguyen, Przemek Kitszel, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Alice Michael, Jacob Keller, Ivan Vecera, Simon Horman,
Martyna Szapar-Mudlaw, Marcin Szycik, intel-wired-lan,
linux-kernel
In-Reply-To: <20260708125755.706263-1-poros@redhat.com>
When an ice port in a vlan-filtering bridge goes promiscuous (typical for
bond slaves), the driver installs a per-VLAN ICE_SW_LKUP_PROMISC_VLAN rule
for every VID on top of the broad ICE_SW_LKUP_DFLT VSI Rx rule. Each rule
consumes one of the ~32K Flow Lookup Unit (FLU) entries the device shares
across PFs, so a wide trunk (vid 2-4094) over several PFs overruns the
pool: firmware rejects further Add Switch Rules with ENOSPC (AQ 0x10) and
the DFLT Rx rule itself fails to install:
ice 0000:5c:00.1: Failed to set VSI 14 as the default forwarding
VSI, error -5
ice 0000:5c:00.1 ens1f1: Error -5 setting default VSI 14 Rx rule
Once a switch context is overrun the retries can also come back as ENOENT
(AQ 0x2), which has misled triage toward a perceived recipe binding defect
rather than a capacity issue.
The DFLT rule already catches every packet on the port regardless of VLAN
tag, so the per-VLAN promisc expansion is redundant while it is installed.
Skip it at the two sites that drive it, ice_set_promisc() and
ice_vlan_rx_add_vid(), keyed on ice_is_vsi_dflt_vsi() rather than the
netdev IFF_PROMISC flag so a failed or LAG-suppressed DFLT install still
falls back to the per-VLAN rules.
IFF_ALLMULTI and IFF_PROMISC can reach ice_vsi_sync_fltr() in separate
passes (a bridge join sets them through separate calls), so the allmulti
pass may expand the per-VID rules before the DFLT rule exists. Drop those
now-redundant rules right after ice_set_dflt_vsi() installs the DFLT rule;
ice_vsi_exit_dflt_promisc() reinstates them when promisc is cleared.
ice_vsi_sync_fltr() subscribed multicast promiscuity only inside the
"default VSI not yet in use" branch, so a promiscuous VSI that finds the
default VSI rule already present (owned by another VSI, or preserved
across a switchdev session) ended up in unicast promisc with no multicast
subscription. Issue ice_set_promisc(ICE_MCAST_PROMISC_BITS) whenever the
netdev is promiscuous; it is idempotent and returns 0 if the rule is
already present.
Fixes: 1273f89578f2 ("ice: Fix broken IFF_ALLMULTI handling")
Signed-off-by: Petr Oros <poros@redhat.com>
---
v4 (review comments from Marcin Szycik):
- Reworded the ice_clear_promisc() and the per-VID cleanup comments.
- Flipped the ice_vsi_clear_vlan_mc_promisc() guard to an early return to
reduce indentation, and noted that the clear is best-effort.
No functional change.
v3: https://lore.kernel.org/all/20260701133601.2118382-2-poros@redhat.com/
v2: https://lore.kernel.org/all/20260622113428.2565255-2-poros@redhat.com/
v1: https://lore.kernel.org/all/89efbea9831175e6f57e9fe8557f7a0e48e050b7.1781786935.git.poros@redhat.com/
---
drivers/net/ethernet/intel/ice/ice_main.c | 109 +++++++++++++++++-----
1 file changed, 88 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index b43d420ece99ca..f1fef26eeadac9 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -274,7 +274,8 @@ static int ice_set_promisc(struct ice_vsi *vsi, u8 promisc_m)
if (vsi->type != ICE_VSI_PF)
return 0;
- if (ice_vsi_has_non_zero_vlans(vsi)) {
+ /* skip per-VID expansion; the DFLT Rx rule already covers every VID */
+ if (ice_vsi_has_non_zero_vlans(vsi) && !ice_is_vsi_dflt_vsi(vsi)) {
promisc_m |= (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX);
status = ice_fltr_set_vlan_vsi_promisc(&vsi->back->hw, vsi,
promisc_m);
@@ -304,9 +305,20 @@ static int ice_clear_promisc(struct ice_vsi *vsi, u8 promisc_m)
return 0;
if (ice_vsi_has_non_zero_vlans(vsi)) {
- promisc_m |= (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX);
+ u8 vlan_promisc_m = promisc_m | ICE_PROMISC_VLAN_RX |
+ ICE_PROMISC_VLAN_TX;
+ int vid0_status;
+
+ /* the vid=0 rule may be in either recipe (the recipe used to
+ * set it is not recorded), so clear both; clearing an absent
+ * rule returns 0
+ */
status = ice_fltr_clear_vlan_vsi_promisc(&vsi->back->hw, vsi,
- promisc_m);
+ vlan_promisc_m);
+ vid0_status = ice_fltr_clear_vsi_promisc(&vsi->back->hw,
+ vsi->idx, promisc_m, 0);
+ if (!status)
+ status = vid0_status;
} else {
status = ice_fltr_clear_vsi_promisc(&vsi->back->hw, vsi->idx,
promisc_m, 0);
@@ -317,6 +329,61 @@ static int ice_clear_promisc(struct ice_vsi *vsi, u8 promisc_m)
return status;
}
+/**
+ * ice_vsi_exit_dflt_promisc - drop the default VSI Rx rule on promisc off
+ * @vsi: the VSI leaving promiscuous mode
+ *
+ * For an IFF_ALLMULTI VSI with VLANs the per-VID multicast rules are
+ * reinstated before the default rule is cleared so coverage never lapses;
+ * the then redundant vid=0 rule is dropped best-effort. The callees log
+ * their own failures, so error returns are not re-logged here.
+ *
+ * Return: 0 on success, negative on error with the default rule left in place.
+ */
+static int ice_vsi_exit_dflt_promisc(struct ice_vsi *vsi)
+{
+ struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
+ struct net_device *netdev = vsi->netdev;
+ struct ice_hw *hw = &vsi->back->hw;
+ bool restore_mc;
+ int err;
+
+ restore_mc = (vsi->current_netdev_flags & IFF_ALLMULTI) &&
+ ice_vsi_has_non_zero_vlans(vsi);
+
+ if (restore_mc) {
+ err = ice_fltr_set_vlan_vsi_promisc(hw, vsi,
+ ICE_MCAST_VLAN_PROMISC_BITS);
+ if (err && err != -EEXIST)
+ return err;
+ }
+
+ err = ice_clear_dflt_vsi(vsi);
+ if (err)
+ return err;
+
+ if (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+ vlan_ops->ena_rx_filtering(vsi);
+
+ if (restore_mc)
+ ice_fltr_clear_vsi_promisc(hw, vsi->idx, ICE_MCAST_PROMISC_BITS,
+ 0);
+
+ return 0;
+}
+
+/* Drop the per-VID multicast promisc rules made redundant by the default
+ * VSI Rx rule; best-effort, a leftover is harmless while that rule stands.
+ */
+static void ice_vsi_clear_vlan_mc_promisc(struct ice_vsi *vsi)
+{
+ if (!ice_vsi_has_non_zero_vlans(vsi))
+ return;
+
+ ice_fltr_clear_vlan_vsi_promisc(&vsi->back->hw, vsi,
+ ICE_MCAST_VLAN_PROMISC_BITS);
+}
+
/**
* ice_vsi_sync_fltr - Update the VSI filter list to the HW
* @vsi: ptr to the VSI
@@ -429,30 +496,31 @@ static int ice_vsi_sync_fltr(struct ice_vsi *vsi)
err = 0;
vlan_ops->dis_rx_filtering(vsi);
- /* promiscuous mode implies allmulticast so
- * that VSIs that are in promiscuous mode are
- * subscribed to multicast packets coming to
- * the port
+ /* a prior allmulti pass may have added per-VID
+ * rules now covered by the DFLT rule
*/
- err = ice_set_promisc(vsi,
- ICE_MCAST_PROMISC_BITS);
- if (err)
- goto out_promisc;
+ ice_vsi_clear_vlan_mc_promisc(vsi);
}
+
+ /* Promiscuous mode implies allmulticast. Subscribe
+ * the VSI to all multicast even when the default VSI
+ * rule is already in use and the block above is
+ * skipped (it may be owned by another VSI, or
+ * preserved across a switchdev session); the unicast
+ * catch-all does not cover the multicast subscription.
+ */
+ err = ice_set_promisc(vsi, ICE_MCAST_PROMISC_BITS);
+ if (err)
+ goto out_promisc;
} 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);
}
/* disable allmulti here, but only if allmulti is not
@@ -3676,10 +3744,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);
- /* 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);
--
2.54.0
^ permalink raw reply related
* [PATCH iwl-net v4 2/2] ice: preserve uplink DFLT Rx rule on switchdev release
From: Petr Oros @ 2026-07-08 12:57 UTC (permalink / raw)
To: netdev
Cc: Petr Oros, Marcin Szycik, Aleksandr Loktionov, Tony Nguyen,
Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Alice Michael, Jacob Keller,
Ivan Vecera, Simon Horman, Martyna Szapar-Mudlaw, intel-wired-lan,
linux-kernel
In-Reply-To: <20260708125755.706263-1-poros@redhat.com>
When the uplink PF is promiscuous, ice_vsi_sync_fltr() installs an
ICE_SW_LKUP_DFLT catch-all Rx rule on the uplink VSI. Entering switchdev
re-affirms it through the idempotent ice_set_dflt_vsi(), but
ice_eswitch_release_env() removed both the Rx and Tx DFLT rules
unconditionally on teardown. That clobbered a promisc-owned Rx rule: it
disappeared while IFF_PROMISC was still set and the sync path was not
retriggered, leaving the uplink without the catch-all the netdev
requested.
Skip the Rx DFLT removal when the uplink is promiscuous, both in
ice_eswitch_release_env() and the err_def_tx unwind of
ice_eswitch_setup_env(); the Tx leg, owned by switchdev, is still removed.
Test the live netdev->flags, the same value ena_rx_filtering() ->
ice_cfg_vlan_pruning() above already keys on, so the preserved rule and
the pruning state stay consistent, including for a promisc change made
while switchdev ran (which never reached the gated filter sync).
Fixes: 5c07be96d8b3 ("ice: Avoid setting default Rx VSI twice in switchdev setup")
Reviewed-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Petr Oros <poros@redhat.com>
---
v4:
- No code change, added Marcin's and Aleksandr's Reviewed-by.
v3: https://lore.kernel.org/all/20260701133601.2118382-3-poros@redhat.com/
v2: https://lore.kernel.org/all/20260622113428.2565255-3-poros@redhat.com/
v1: https://lore.kernel.org/all/deef5756e534ef06c12d910c5305d3fd205d30a0.1781786935.git.poros@redhat.com/
---
drivers/net/ethernet/intel/ice/ice_eswitch.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch.c b/drivers/net/ethernet/intel/ice/ice_eswitch.c
index c30e27bbfe6e25..07e2016fb9481f 100644
--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
@@ -66,8 +66,10 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
ICE_FLTR_TX);
err_def_tx:
- ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
- ICE_FLTR_RX);
+ /* keep the Rx DFLT rule if the uplink is promiscuous (see release_env) */
+ if (!(uplink_vsi->netdev->flags & IFF_PROMISC))
+ ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx,
+ false, ICE_FLTR_RX);
err_def_rx:
ice_vsi_del_vlan_zero(uplink_vsi);
err_vlan_zero:
@@ -276,8 +278,16 @@ static void ice_eswitch_release_env(struct ice_pf *pf)
vlan_ops->ena_rx_filtering(uplink_vsi);
ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
ICE_FLTR_TX);
- ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,
- ICE_FLTR_RX);
+
+ /* Keep the Rx DFLT rule if the uplink is promiscuous; it must outlive
+ * the session. Test the live netdev->flags, the same value
+ * ena_rx_filtering() -> ice_cfg_vlan_pruning() above keys its decision
+ * on, so the preserved DFLT rule and the pruning state stay consistent.
+ */
+ if (!(uplink_vsi->netdev->flags & IFF_PROMISC))
+ ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx,
+ false, ICE_FLTR_RX);
+
ice_fltr_add_mac_and_broadcast(uplink_vsi,
uplink_vsi->port_info->mac.perm_addr,
ICE_FWD_TO_VSI);
--
2.54.0
^ permalink raw reply related
* Re: [PATCH net] net: airoha: Fix potential use-after-free in airoha_ppe_deinit()
From: Lorenzo Bianconi @ 2026-07-08 13:03 UTC (permalink / raw)
To: Wayen Yan
Cc: netdev, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
In-Reply-To: <178351022574.97989.6880403520276841703@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]
> airoha_ppe_deinit() replaces the NPU pointer with NULL via
> rcu_replace_pointer() but does not wait for existing RCU readers
> to exit before calling ppe_deinit() and airoha_npu_put(). This can
> cause a use-after-free if a reader in an RCU read-side critical
> section still holds a reference to the NPU when it is freed.
>
> The init path (airoha_ppe_init) already calls synchronize_rcu()
> after rcu_assign_pointer(), but the deinit path introduced in
> commit 6abcf751bc08 ("net: airoha: Fix schedule while atomic in
> airoha_ppe_deinit()") omitted the matching barrier when switching
> from rcu_read_lock()/rcu_dereference() to rcu_replace_pointer().
>
> Add synchronize_rcu() before ppe_deinit() to ensure all existing
> RCU readers have completed before the NPU resources are released.
>
> Fixes: 6abcf751bc084804a9e5b3051442e8a2ce67f48a ("net: airoha: Fix schedule while atomic in airoha_ppe_deinit()")
> Signed-off-by: Wayen Yan <win847@gmail.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/ethernet/airoha/airoha_ppe.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
> index e7c78293002a..f6396925722d 100644
> --- a/drivers/net/ethernet/airoha/airoha_ppe.c
> +++ b/drivers/net/ethernet/airoha/airoha_ppe.c
> @@ -1659,6 +1659,7 @@ void airoha_ppe_deinit(struct airoha_eth *eth)
> npu = rcu_replace_pointer(eth->npu, NULL,
> lockdep_is_held(&flow_offload_mutex));
> if (npu) {
> + synchronize_rcu();
> npu->ops.ppe_deinit(npu);
> airoha_npu_put(npu);
> }
> --
> 2.51.0
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH] net: phy: marvell: Add soft reset for 88E1510
From: Andrew Lunn @ 2026-07-08 13:04 UTC (permalink / raw)
To: Ben Brown
Cc: hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Chris Packham
In-Reply-To: <c77dd281-9ae2-4634-a670-bd6c70afb3df@alliedtelesis.co.nz>
> > Lets take a step back.
> >
> > What sort of reset are we talking about? Software or hardware?
> >
> > Andrew
>
> It is doing a hardware reset using a GPIO line.
>
> When linked down the phy gets put into reset using a hardware GPIO line,
> during link up the phy initializes the hardware using phy_init_hw(),
> which de-asserts that reset GPIO. Then trivial setup is done before
> the driver specific config_init().
>
> When we are doing the marvell m88e1510_config_init() the first page
> write is not applying so it ends up writing configuration to the wrong
> registers. When testing fixes adding a 15us sleep before changing the
> page also meant the page was updated correctly.
reset-gpios:
maxItems: 1
description:
The GPIO phandle and specifier for the PHY reset signal.
reset-assert-us:
description:
Delay after the reset was asserted in microseconds. If this
property is missing the delay will be skipped.
reset-deassert-us:
description:
Delay after the reset was deasserted in microseconds. If
this property is missing the delay will be skipped.
What delays are you using?
Andrew
^ permalink raw reply
* Re: [PATCH net v2] ppp: defer channel free to an RCU grace period to fix pppol2tp RX UAF
From: Petr Pavlu @ 2026-07-08 13:04 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Qingfang Deng, Breno Leitao, Norbert Szetei, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Taegu Ha, Kees Cook, linux-ppp, linux-kernel, Guillaume Nault,
netdev, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, linux-modules, Paul E. McKenney
In-Reply-To: <20260708074904.xnpi0mlh@linutronix.de>
On 7/8/26 9:49 AM, Sebastian Andrzej Siewior wrote:
> On 2026-07-07 17:32:10 [+0200], Petr Pavlu wrote:
>>> --- a/kernel/module/main.c
>>> +++ b/kernel/module/main.c
>>> @@ -858,6 +858,9 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
>>> goto out;
>>>
>>> mutex_unlock(&module_mutex);
>>> +
>>> + /* Ensure all rcu callbacks issued by the module have completed */
>>> + rcu_barrier();
>>> /* Final destruction now no one is using it. */
>>> if (mod->exit != NULL)
>>> mod->exit();
>>>
>>> make sense?
>>
>> This is discussed in Documentation/RCU/rcubarrier.rst and
>> Documentation/RCU/Design/Requirements/Requirements.rst. The latter
>> contains:
>
> I am aware of this. It is just not the first time I stumble about this.
> But maybe with the AI review these days there won't be a miss.
>
>> I don't know if the last part about unacceptable latencies is still
>> relevant. I haven't done any measurements myself.
>
> There is a synchronize_rcu() later on. I think I could replace it with a
> call_rcu() so we might end up even. I was thinking about about it last
> time I was touching modules but somehow I stopped where I stopped.
> The question is just, is it worth doing it or is it reasonable to expect
> that it is done correctly.
As RCU usage in modules is now more common, I see an argument for the
module loader to invoke rcu_barrier() during module unload to make RCU
usage easier. In general, module unloading is a rare operation, so even
if it becomes somewhat slower, I don't expect it to be a significant
issue.
One problem is that I'm not sure where the new rcu_barrier() call should
be placed. The prototype adds it before calling the module's exit
function. Would this actually fit all modules? From a quick look, I can
see that various modules call it at different points during their exit.
--
Thanks,
Petr
^ permalink raw reply
* Re: [PATCH net] nfc: nci: fix out-of-bounds read in activation parameter parsing
From: Simon Horman @ 2026-07-08 13:07 UTC (permalink / raw)
To: Muhammad Bilal
Cc: David Heidelberg, netdev, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, oe-linux-nfc, linux-kernel
In-Reply-To: <20260628210026.129941-1-meatuni001@gmail.com>
On Mon, Jun 29, 2026 at 02:00:26AM +0500, Muhammad Bilal wrote:
> nci_extract_activation_params_iso_dep() and
> nci_extract_activation_params_nfc_dep() receive a pointer into the
> RF_INTF_ACTIVATED_NTF notification but are not told how many bytes
> remain. Each reads a one-byte length field (rats_res_len,
> attrib_res_len, atr_res_len or atr_req_len) and then memcpy()s that many
> bytes from the packet. The length is clamped to the destination size,
> but it is never checked against the remaining activation-parameter data,
> so a notification whose length field is larger than the data present
> reads past the end of the buffer.
>
> The sibling nci_extract_rf_params_*() helpers were recently given a
> data_len argument and matching remaining-length checks, but the
> activation-parameter helpers were not updated.
>
> Pass the remaining length down and validate each field against it before
> copying, as the rf_params helpers do.
>
> Fixes: ac2068384034 ("NFC: Parse NCI NFC-DEP activation params")
> Cc: stable@vger.kernel.org
> Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
FTR, there is an AI-=generated review of this patch on sashiko.dev.
However, I think that the issues raised there can be treated
as possible follow-up rather than impeding the progress of this patch.
^ permalink raw reply
* [PATCH net] cxgb4: consider EtherType when validating filter priority ordering
From: Harshita V Rajput @ 2026-07-08 13:16 UTC (permalink / raw)
To: netdev; +Cc: davem, kuba, edumazet, pabeni, andrew+netdev, bharat,
harshitha.vr
cxgb4_filter_prio_in_range() currently validates the priority
ordering of adjacent filters based only on tc_prio. This can
incorrectly reject insertion of a new filter when an existing
filter with a higher priority matches a different EtherType.
For example:
- An LLDP filter (pref 4) blocks IPv4 (pref 2) and IPv6 (pref 3)
filters from being added.
- An IPv6 filter (pref 3) blocks an IPv4 (pref 2) filter from being
added.
In both cases the filters match different EtherTypes, so they could
never have matched the same packet anyway.
Fix this by considering both tc_prio and the matched EtherType. A
neighbouring filter only blocks the new filter if it has no specific
EtherType set, or its EtherType is the same as the new filter's.
Filters with different EtherTypes are now allowed regardless of
priority order. Filters with the same EtherType still follow the
original strict priority check, since they really can overlap.
Fixes: 41ec03e534ca ("cxgb4: check rule prio conflicts before offload")
Signed-off-by: Harshita V Rajput <harshitha.vr@chelsio.com>
Signed-off-by: Potnuri Bharat Teja <bharat@chelsio.com>
---
.../net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 19 ++++++++++++++-----
.../ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 4 ++--
.../chelsio/cxgb4/cxgb4_tc_matchall.c | 2 +-
.../net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c | 2 +-
.../net/ethernet/chelsio/cxgb4/cxgb4_uld.h | 2 +-
5 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index 657d96b9e2f6..8462455d9330 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -443,7 +443,7 @@ int cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx,
}
static bool cxgb4_filter_prio_in_range(struct tid_info *t, u32 idx, u8 nslots,
- u32 prio)
+ u32 prio, u32 ethtype)
{
struct filter_entry *prev_tab, *next_tab, *prev_fe, *next_fe;
u32 prev_ftid, next_ftid;
@@ -536,15 +536,24 @@ static bool cxgb4_filter_prio_in_range(struct tid_info *t, u32 idx, u8 nslots,
if (!prev_fe->fs.type)
prev_fe = &prev_tab[prev_ftid];
- if ((prev_fe->valid && prev_fe->fs.tc_prio > prio) ||
- (next_fe->valid && next_fe->fs.tc_prio < prio))
+ /* Filters with different EtherTypes can never match the same
+ * packet, so skip the priority check between them.
+ */
+ if (prev_fe->valid && prev_fe->fs.tc_prio > prio &&
+ (!prev_fe->fs.mask.ethtype || !ethtype ||
+ prev_fe->fs.val.ethtype == ethtype))
+ return false;
+
+ if (next_fe->valid && next_fe->fs.tc_prio < prio &&
+ (!next_fe->fs.mask.ethtype || !ethtype ||
+ next_fe->fs.val.ethtype == ethtype))
return false;
return true;
}
int cxgb4_get_free_ftid(struct net_device *dev, u8 family, bool hash_en,
- u32 tc_prio)
+ u32 tc_prio, u32 ethtype)
{
struct adapter *adap = netdev2adap(dev);
struct tid_info *t = &adap->tids;
@@ -671,7 +680,7 @@ int cxgb4_get_free_ftid(struct net_device *dev, u8 family, bool hash_en,
* with existing rules.
*/
if (cxgb4_filter_prio_in_range(t, ftid, n,
- tc_prio)) {
+ tc_prio, ethtype)) {
ftid &= ~(n - 1);
found = true;
break;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 41a2998ee2a0..754d9f5f0fe0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -911,8 +911,8 @@ int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
* rule. Only insert rule if its prio doesn't conflict with
* existing rules.
*/
- fidx = cxgb4_get_free_ftid(dev, inet_family, fs->hash,
- tc_prio);
+ fidx = cxgb4_get_free_ftid(dev, inet_family, fs->hash, tc_prio,
+ fs->mask.ethtype ? fs->val.ethtype : 0);
if (fidx < 0) {
NL_SET_ERR_MSG_MOD(extack,
"No free LETCAM index available");
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
index bc290430245e..bab263785082 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
@@ -312,7 +312,7 @@ static int cxgb4_matchall_add_filter(struct net_device *dev,
* existing rules.
*/
fidx = cxgb4_get_free_ftid(dev, filter_type ? PF_INET6 : PF_INET,
- false, cls->common.prio);
+ false, cls->common.prio, 0);
if (fidx < 0) {
NL_SET_ERR_MSG_MOD(extack,
"No free LETCAM index available");
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
index 1c1a7bc5a896..37a878f07f91 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c
@@ -174,7 +174,7 @@ int cxgb4_config_knode(struct net_device *dev, struct tc_cls_u32_offload *cls)
* existing rules.
*/
filter_id = cxgb4_get_free_ftid(dev, inet_family, false,
- TC_U32_NODE(cls->knode.handle));
+ TC_U32_NODE(cls->knode.handle), 0);
if (filter_id < 0) {
NL_SET_ERR_MSG_MOD(extack,
"No free LETCAM index available");
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index d7713038386c..42efc239df88 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -282,7 +282,7 @@ struct chcr_ktls {
struct ch_filter_specification;
int cxgb4_get_free_ftid(struct net_device *dev, u8 family, bool hash_en,
- u32 tc_prio);
+ u32 tc_prio, u32 ethtype);
int __cxgb4_set_filter(struct net_device *dev, int filter_id,
struct ch_filter_specification *fs,
struct filter_ctx *ctx);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net-next 0/3] mlxsw: Make the driver ops-locked
From: Eric Dumazet @ 2026-07-08 13:24 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, davem, kuba, pabeni, petrm, andrew+netdev
In-Reply-To: <20260708123933.1303291-1-idosch@nvidia.com>
On Wed, Jul 8, 2026 at 2:41 PM Ido Schimmel <idosch@nvidia.com> wrote:
>
> Make the driver ops-locked in order to allow ethtool operations to be
> invoked without RTNL being held.
>
> An ops-locked driver has most of its NDOs, all of its ethtool operations
> and some net device notifications run with the netdev instance lock
> held.
>
> In the specific case of mlxsw, the driver is not using any functions
> that acquire this lock nor functions that expect the lock to be held for
> an ops-locked driver. Therefore, converting its NDOs to run with the
> lock being held is trivial except for a small quirk which is handled in
> patch #1.
>
> The driver does not generate any net device notifications, so there is
> no risk of nested notifications of the ops-locked types. For the
> notifications that run under the instance lock, RTNL is also held, and
> the driver does not acquire the instance lock itself, so no changes are
> required in its notifier handling.
>
> Ethtool operations can be invoked without RTNL except for two operations
> that are annotated in patch #2.
>
> Lastly, patch #3 converts the driver to be ops-locked.
>
> A probe on rtnl_lock() shows it is no longer taken when dumping
> statistics:
>
> # perf probe --add rtnl_lock
>
> Before:
>
> # perf stat -e probe:rtnl_lock -- ethtool -S swp1 --all-groups
> [...]
> 1 probe:rtnl_lock
>
> After:
>
> # perf stat -e probe:rtnl_lock -- ethtool -S swp1 --all-groups
> [...]
> 0 probe:rtnl_lock
>
We probably want to add noinline_for_tracing to rtnl_lock() and friends...
^ permalink raw reply
* Re: [PATCH net-next v3] net: skb: isolate skb data area allocations into a separate bucket
From: Harry Yoo @ 2026-07-08 13:27 UTC (permalink / raw)
To: Pedro Falcato, Paolo Abeni
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Simon Horman,
Jason Xing, Kuniyuki Iwashima, netdev, linux-kernel,
linux-hardening, Kees Cook, linux-mm, Vlastimil Babka
In-Reply-To: <ak4w2k4Woj55E0On@pedro-suse>
On 7/8/26 8:16 PM, Pedro Falcato wrote:
> On Wed, Jul 08, 2026 at 10:30:50AM +0200, Paolo Abeni wrote:
>> On 7/2/26 7:07 PM, Pedro Falcato wrote:> @@ -586,6 +586,8 @@ struct
>> sk_buff *napi_build_skb(void *data, unsigned int frag_size)
>>> }
>>> EXPORT_SYMBOL(napi_build_skb);
>>>
>>> +static kmem_buckets *skb_data_buckets __ro_after_init;
>>> +
>>> static void *kmalloc_pfmemalloc(size_t obj_size, gfp_t flags, int node)
>>> {
>>> if (!gfp_pfmemalloc_allowed(flags))
>>> @@ -593,7 +595,8 @@ static void *kmalloc_pfmemalloc(size_t obj_size, gfp_t flags, int node)
>>> if (!obj_size)
>>> return kmem_cache_alloc_node(net_hotdata.skb_small_head_cache,
>>> flags, node);
>>> - return kmalloc_node_track_caller(obj_size, flags, node);
>>> + return kmem_buckets_alloc_node_track_caller(skb_data_buckets, obj_size,
>>> + flags, node);
>>
>> Sashiko noted that some drivers may require GFP_DMA buckets, and the
>> above may break them:
>>
>> https://sashiko.dev/#/patchset/20260702170728.168755-1-pfalcato%40suse.de
>
> Oh, this is really awkward. Adding linux-mm and slab maintainers for input here.
>
> Considering the current slab bucketing does not seem to duplicate DMA or
> CGROUP caches, could it make sense to duplicate those as well?
Could we specify what kmalloc types the user needs when creating
kmem_buckets and duplicate caches for the requested kmalloc types only?
> Otherwise we could add a branch like:
>
> if (gfp_flags & __GFP_DMA)
> /* use the global dma kmalloc caches */
--
Cheers,
Harry / Hyeonggon
^ permalink raw reply
* Re: [PATCH bpf-next 1/1] selftests: drv-net: add XDP RX checksum metadata tests
From: bot+bpf-ci @ 2026-07-08 13:28 UTC (permalink / raw)
To: deliran, lorenzo
Cc: sdf, kuba, andrii, ast, daniel, hawk, john.fastabend, martin.lau,
sdf.kernel, bpf, netdev, deliran, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
In-Reply-To: <6c7a059057d309e999b706b5b547be9c620ce544.1783514455.git.deliran@verdict.gg>
[-- Attachment #1: Type: text/plain, Size: 1216 bytes --]
> diff --git a/tools/testing/selftests/drivers/net/hw/xdp_metadata.py b/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
> index 33a1985356d9..687c43a1797a 100644
> --- a/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
> +++ b/tools/testing/selftests/drivers/net/hw/xdp_metadata.py
[ ... ]
> @@ -81,8 +83,22 @@ _RSS_KEY_TYPE = 1
> _RSS_KEY_PKT_CNT = 2
> _RSS_KEY_ERR_CNT = 3
>
> +_CSUM_KEY_IP_SUMMED = 0
> +_CSUM_KEY_CKSUM = 1
> +_CSUM_KEY_LEVEL = 2
> +_CSUM_KEY_PKT_CNT = 3
> +_CSUM_KEY_ERR_CNT = 4
> +
> XDP_RSS_L4 = 0x8 # BIT(3) from enum xdp_rss_hash_type
>
> +# Mirror of enum xdp_checksum from include/net/xdp.h
> +XDP_CHECKSUM_NONE = 0x1
> +XDP_CHECKSUM_UNNECESSARY = 0x2
> +XDP_CHECKSUM_COMPLETE = 0x4
This isn't a bug, but XDP_CHECKSUM_NONE does not seem to be used anywhere
in the test; was it intended to mirror the full enum for documentation, or
could it be dropped to match the nearby XDP_RSS_L4 which defines only the
bit it uses?
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/28945032378
^ permalink raw reply
* Re: [PATCH net v3] nfc: nci: Fix conn_info use-after-free
From: Simon Horman @ 2026-07-08 13:28 UTC (permalink / raw)
To: sanghyun.park.cnu
Cc: Simon Horman, david+nfc, krzk, davem, edumazet, kuba, pabeni,
ian.ray, joe, kuniyu, kees, ashutoshdesai993, vadim.fedorenko,
deepak.sharma.472935, michael.thalmeier, christophe.ricard, sameo,
oe-linux-nfc, netdev, linux-kernel
In-Reply-To: <20260630071717.3618185-2-sanghyun.park.cnu@gmail.com>
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
---
nfc: nci: Fix conn_info use-after-free
This commit fixes a use-after-free in nci_tx_work() by introducing a dedicated
spinlock (conn_info_lock) to protect the conn_info_list and conn_info aliases
during lookup, insertion, and removal.
> diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
> --- a/net/nfc/nci/core.c
> +++ b/net/nfc/nci/core.c
> @@ -1333,11 +1367,16 @@ void nci_unregister_device(struct nci_dev *ndev)
> destroy_workqueue(ndev->rx_wq);
> destroy_workqueue(ndev->tx_wq);
>
> + spin_lock_bh(&ndev->conn_info_lock);
> list_for_each_entry_safe(conn_info, n, &ndev->conn_info_list, list) {
> list_del(&conn_info->list);
> + if (conn_info == ndev->rf_conn_info)
> + ndev->rf_conn_info = NULL;
> + if (conn_info == ndev->hci_dev->conn_info)
> + ndev->hci_dev->conn_info = NULL;
[Severity: Critical]
Can this cause a NULL pointer dereference for devices without HCI support?
For NCI devices without HCI support (like nfcmrvl or s3fwrn5), ndev->hci_dev
is NULL. Because all NCI devices add at least the static RF connection to
conn_info_list during discovery, this loop will always execute.
Evaluating conn_info == ndev->hci_dev->conn_info will crash when
ndev->hci_dev is NULL.
Should this check ndev->hci_dev before accessing its conn_info field? The
same issue appears in nci_core_conn_close_rsp_packet() in net/nfc/nci/rsp.c.
> diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
> --- a/net/nfc/nci/data.c
> +++ b/net/nfc/nci/data.c
> @@ -171,40 +174,47 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
[ ... ]
> + spin_lock_bh(&ndev->conn_info_lock);
> ndev->cur_conn_id = conn_id;
> - queue_work(ndev->tx_wq, &ndev->tx_work);
[Severity: High]
This is a pre-existing issue, but does ndev->cur_conn_id suffer from
concurrent overwrites?
If a logical connection is being closed, nci_core_conn_close() sets
ndev->cur_conn_id and waits for the response.
If nci_send_data() is called concurrently, it overwrites ndev->cur_conn_id
without holding req_lock.
When the close response arrives, nci_core_conn_close_rsp_packet() will free
the conn_info for the actively transmitting connection instead of the closed
one. Does cur_conn_id need better protection or a different tracking
mechanism?
> @@ -282,11 +292,15 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
[ ... ]
> /* strip the nci data header */
> skb_pull(skb, NCI_DATA_HDR_SIZE);
[Severity: High]
This is a pre-existing issue, but can this lead to an out-of-bounds read
if the packet is empty?
If a target sends an empty packet (skb->len == 0), the skb_pull() just above
fails gracefully leaving skb->len at 0.
Then in nci_rx_data_packet(), the code accesses skb->data[skb->len - 1] to
read the status byte, reading out-of-bounds memory.
Does this need an skb->len > 0 check before accessing the status byte?
> diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
> --- a/net/nfc/nci/hci.c
> +++ b/net/nfc/nci/hci.c
> @@ -599,10 +632,20 @@ int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx,
[ ... ]
> + message = (struct nci_hcp_message *)rx_skb->data;
> r = nci_hci_result_to_errno(
> NCI_HCP_MSG_GET_CMD(message->header));
> - skb_pull(conn_info->rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
> + skb_pull(rx_skb, NCI_HCI_HCP_MESSAGE_HEADER_LEN);
> + spin_unlock_bh(&ndev->conn_info_lock);
> }
[Severity: High]
This is a pre-existing issue, but does this leak the response skb?
After pulling the header to check the result, nci_hci_set_param() returns
without consuming the skb or calling kfree_skb().
The buffer remains in conn_info->rx_skb, and the next time an HCI response
is received, nci_hci_resp_received() unconditionally overwrites the pointer,
permanently leaking the memory.
Should the skb be freed if it's not being passed back to the caller?
> diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c
> --- a/net/nfc/nci/rsp.c
> +++ b/net/nfc/nci/rsp.c
> @@ -298,20 +313,20 @@ static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev,
> conn_info->dest_params->id = ndev->cur_params.id;
> conn_info->dest_params->protocol = ndev->cur_params.protocol;
> conn_info->conn_id = rsp->conn_id;
> + conn_info->max_pkt_payload_len = rsp->max_ctrl_pkt_payload_len;
> + atomic_set(&conn_info->credits_cnt, rsp->credits_cnt);
[Severity: High]
This is a pre-existing issue, but does this properly validate the length
of the response packet?
The skb->data is cast to struct nci_core_conn_create_rsp, but if the
hardware sends a truncated response (e.g., just the status byte), the code
blindly accesses the connection parameters and credit count from
uninitialized adjacent memory.
Does this need an skb->len check before parsing the structure?
^ permalink raw reply
* [PATCH] net: use sync wakeups for socket error reports
From: Usama Arif @ 2026-07-08 13:38 UTC (permalink / raw)
To: davem, edumazet, horms, kuba, kuniyu, linux-kernel, netdev,
pabeni, willemb, shakeel.butt, hannes, riel, kernel-team
Cc: Usama Arif
sock_def_readable() and sock_def_write_space() pass WF_SYNC to their
waitqueue wakeups, switch sock_def_error_report() to
wake_up_interruptible_sync_poll() so EPOLLERR waiters get the same hint.
ep_poll_callback() forwards it through to
try_to_wake_up() / select_task_rq_fair(), where wake_affine() can
prefer the waker CPU and skip a cross-CPU wakelist IPI when its
heuristics agree.
WF_SYNC matches the choice already made for readable/write_space. Some
error reports have the same producer/consumer shape: the waker has queued
an skb on sk->sk_error_queue, and the wakee is about to dequeue and copy
it out. Other reports publish sk_err/socket state directly, but still wake
a task likely to consume that socket state immediately.
Measured on a 176-core EPYC 9D64 host running a Meta production
workload, bpftrace on tracepoint:ipi:ipi_send_cpu with a kstack filter
attributed the sock_def_error_report -> ep_poll_callback ->
try_to_wake_up -> ttwu_queue_wakelist -> __smp_call_single_queue
chain to 16,326 IPIs/min. Switching to wake_up_interruptible_sync_poll()
will help reduce those IPIs.
Signed-off-by: Usama Arif <usama.arif@linux.dev>
---
net/core/sock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/sock.c b/net/core/sock.c
index 8a59bfaa8096..c724f1442987 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3639,7 +3639,7 @@ static void sock_def_error_report(struct sock *sk)
rcu_read_lock();
wq = rcu_dereference(sk->sk_wq);
if (skwq_has_sleeper(wq))
- wake_up_interruptible_poll(&wq->wait, EPOLLERR);
+ wake_up_interruptible_sync_poll(&wq->wait, EPOLLERR);
sk_wake_async_rcu(sk, SOCK_WAKE_IO, POLL_ERR);
rcu_read_unlock();
}
--
2.53.0-Meta
^ permalink raw reply related
* [PATCH iproute2-next v4] rdma: display resource limits in curr/max format
From: Tao Cui @ 2026-07-08 13:40 UTC (permalink / raw)
To: dsahern, leonro; +Cc: linux-rdma, netdev, cui.tao, cuitao
From: Tao Cui <cuitao@kylinos.cn>
Parse the new RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX netlink attribute
to show resource limits alongside current counts in curr/max format:
Before: 0: mlx5_0: qp 123 cq 45 mr 200 pd 10
After: 0: mlx5_0: qp 123/131072 cq 45/65536 mr 200/1000000 pd 10/32768
JSON output provides both current and max fields per resource type
(e.g. "qp": 123, "qp-max": 131072). Backward compatible: no output
change when kernel lacks the new attribute.
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
Link: https://lore.kernel.org/all/20260615003646.168704-1-cui.tao@linux.dev/
---
Changes in v4:
- Add Link to the kernel patch that introduces the new uapi attribute.
---
rdma/include/uapi/rdma/rdma_netlink.h | 5 +++++
rdma/res.c | 21 ++++++++++++++++++++-
rdma/utils.c | 1 +
3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/rdma/include/uapi/rdma/rdma_netlink.h b/rdma/include/uapi/rdma/rdma_netlink.h
index 4356ec4a..e5b8b065 100644
--- a/rdma/include/uapi/rdma/rdma_netlink.h
+++ b/rdma/include/uapi/rdma/rdma_netlink.h
@@ -604,6 +604,11 @@ enum rdma_nldev_attr {
RDMA_NLDEV_ATTR_FRMR_POOL_PINNED_HANDLES, /* u32 */
RDMA_NLDEV_ATTR_FRMR_POOL_KEY_KERNEL_VENDOR_KEY, /* u64 */
+ /*
+ * Resource summary entry maximum value.
+ */
+ RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX, /* u64 */
+
/*
* Always the end
*/
diff --git a/rdma/res.c b/rdma/res.c
index 062f0007..046935e2 100644
--- a/rdma/res.c
+++ b/rdma/res.c
@@ -55,7 +55,26 @@ static int res_print_summary(struct nlattr **tb)
name = mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME]);
curr = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
- res_print_u64(name, curr, nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
+ if (nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX]) {
+ uint64_t max;
+ char max_name[64];
+
+ max = mnl_attr_get_u64(
+ nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX]);
+ snprintf(max_name, sizeof(max_name), "%s-max", name);
+ print_u64(PRINT_JSON, name, NULL, curr);
+ print_u64(PRINT_JSON, max_name, NULL, max);
+ if (!is_json_context()) {
+ char buf[64];
+
+ snprintf(buf, sizeof(buf), "%s %" PRIu64 "/%" PRIu64 " ",
+ name, curr, max);
+ pr_out("%s", buf);
+ }
+ } else {
+ res_print_u64(name, curr,
+ nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]);
+ }
}
return 0;
}
diff --git a/rdma/utils.c b/rdma/utils.c
index 87003b2c..90ea1c55 100644
--- a/rdma/utils.c
+++ b/rdma/utils.c
@@ -480,6 +480,7 @@ static const enum mnl_attr_data_type nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
[RDMA_NLDEV_ATTR_EVENT_TYPE] = MNL_TYPE_U8,
[RDMA_NLDEV_SYS_ATTR_MONITOR_MODE] = MNL_TYPE_U8,
[RDMA_NLDEV_ATTR_STAT_OPCOUNTER_ENABLED] = MNL_TYPE_U8,
+ [RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_MAX] = MNL_TYPE_U64,
};
static int rd_attr_check(const struct nlattr *attr, int *typep)
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox