FAILED: patch "[PATCH] mlxsw: fix refcount leak in mlxsw_sp_port_lag_join()" failed to apply to 6.1-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 41c8c1d65b32beacd8d916a22457b4f6e47f45af
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026072025-willpower-discolor-ccfb@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 41c8c1d65b32beacd8d916a22457b4f6e47f45af Mon Sep 17 00:00:00 2001
From: Wentao Liang <[email protected]>
Date: Tue, 9 Jun 2026 08:37:09 +0000
Subject: [PATCH] mlxsw: fix refcount leak in mlxsw_sp_port_lag_join()
When mlxsw_sp_port_lag_index_get() fails, mlxsw_sp_port_lag_join() returns an error without releasing the lag reference obtained by the earlier mlxsw_sp_lag_get(). All other error paths in the function jump to the cleanup label that ends with mlxsw_sp_lag_put(), so this is a single missed release.
Fix the leak by replacing the bare 'return err' with a goto to the existing error cleanup label, which will drop the reference safely.
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +1 -1
@@ -4360,7 +4360,7 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port, lag_id = lag->lag_id; err =mlxsw_sp_port_lag_index_get (mlxsw_sp, lag_id, &port_index);if (err) -return err; + goto err_lag_uppers_bridge_join; err =mlxsw_sp_lag_uppers_bridge_join (mlxsw_sp_port, lag_dev, extack);
Sasha Levin
maintainerPATCH 1/2 mlxsw: spectrum: On port enslavement to a LAG, join upper's bridges
From: Petr Machata <[email protected]>
[ Upstream commit 987c7782f0627e1c87617458806a7e6c1995678a ]
Currently it never happens that a netdevice that is already a bridge slave would suddenly become mlxsw upper. The only case where this might be possible as far as mlxsw is concerned, is with LAG netdevices. But if a LAG already has an upper, enslaving mlxsw port to that LAG is forbidden. Thus the only way to install a LAG between a bridge and a mlxsw port is by first enslaving the port to the LAG, and then enslaving that LAG to a bridge.
However in the following patches, the requirement that ports be only enslaved to masters without uppers, is going to be relaxed. It will therefore be necessary to join bridges of LAG uppers. Without this replay, the mlxsw bridge_port objects are not instantiated, which causes issues later, as a lot of code relies on their presence.
Therefore in this patch, when the first mlxsw physical netdevice is enslaved to a LAG, consider bridges upper to the LAG (both the direct master, if any, and any bridge masters of VLAN uppers), and have the relevant netdevices join their bridges.
Stable-dep-of: 41c8c1d65b32 ("mlxsw: fix refcount leak in mlxsw_sp_port_lag_join()")
--- .../net/ethernet/mellanox/mlxsw/spectrum.c | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +90 -0
@@ -4357,6 +4357,88 @@ static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,return -EBUSY ; } +static int mlxsw_sp_lag_uppers_bridge_join (struct mlxsw_sp_port *mlxsw_sp_port, +struct net_device *lag_dev, +struct netlink_ext_ack *extack) +{ +struct net_device *upper_dev; +struct net_device *master; +struct list_head *iter; +int done =0 ; +int err; + + master =netdev_master_upper_dev_get (lag_dev); +if (master &&netif_is_bridge_master (master)) { + err =mlxsw_sp_port_bridge_join (mlxsw_sp_port, lag_dev, master, + extack); +if (err) +return err; + } + +netdev_for_each_upper_dev_rcu (lag_dev, upper_dev, iter) { +if (!is_vlan_dev (upper_dev)) +continue ; + + master =netdev_master_upper_dev_get (upper_dev); +if (master &&netif_is_bridge_master (master)) { + err =mlxsw_sp_port_bridge_join (mlxsw_sp_port, + upper_dev, master, + extack); +if (err) + goto err_port_bridge_join; + } + + ++done; + } + +return 0 ; + +err_port_bridge_join: +netdev_for_each_upper_dev_rcu (lag_dev, upper_dev, iter) { +if (!is_vlan_dev (upper_dev)) +continue ; + + master =netdev_master_upper_dev_get (upper_dev); +if (!master || !netif_is_bridge_master (master)) +continue ; + +if (!done--) +break ; + +mlxsw_sp_port_bridge_leave (mlxsw_sp_port, upper_dev, master); + } + + master =netdev_master_upper_dev_get (lag_dev); +if (master &&netif_is_bridge_master (master)) +mlxsw_sp_port_bridge_leave (mlxsw_sp_port, lag_dev, master); + +return err; +} + +static void +mlxsw_sp_lag_uppers_bridge_leave (struct mlxsw_sp_port *mlxsw_sp_port, +struct net_device *lag_dev) +{ +struct net_device *upper_dev; +struct net_device *master; +struct list_head *iter; + +netdev_for_each_upper_dev_rcu (lag_dev, upper_dev, iter) { +if (!is_vlan_dev (upper_dev)) +continue ; + + master =netdev_master_upper_dev_get (upper_dev); +if (!master) +continue ; + +mlxsw_sp_port_bridge_leave (mlxsw_sp_port, upper_dev, master); + } + + master =netdev_master_upper_dev_get (lag_dev); +if (master) +mlxsw_sp_port_bridge_leave (mlxsw_sp_port, lag_dev, master); +} +static int mlxsw_sp_port_lag_join (struct mlxsw_sp_port *mlxsw_sp_port,struct net_device *lag_dev,struct netlink_ext_ack *extack)
@@ -4381,6 +4463,12 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port, err =mlxsw_sp_port_lag_index_get (mlxsw_sp, lag_id, &port_index);if (err)return err; + + err =mlxsw_sp_lag_uppers_bridge_join (mlxsw_sp_port, lag_dev, + extack); +if (err) + goto err_lag_uppers_bridge_join; + err =mlxsw_sp_lag_col_port_add (mlxsw_sp_port, lag_id, port_index);if (err) goto err_col_port_add;
@@ -4410,6 +4498,8 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port, mlxsw_sp_port->local_port);mlxsw_sp_lag_col_port_remove (mlxsw_sp_port, lag_id); err_col_port_add: +mlxsw_sp_lag_uppers_bridge_leave (mlxsw_sp_port, lag_dev); +err_lag_uppers_bridge_join:if (!lag->ref_count)mlxsw_sp_lag_destroy (mlxsw_sp, lag_id);return err;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 mlxsw: fix refcount leak in mlxsw_sp_port_lag_join()
From: Wentao Liang <[email protected]>
[ Upstream commit 41c8c1d65b32beacd8d916a22457b4f6e47f45af ]
When mlxsw_sp_port_lag_index_get() fails, mlxsw_sp_port_lag_join() returns an error without releasing the lag reference obtained by the earlier mlxsw_sp_lag_get(). All other error paths in the function jump to the cleanup label that ends with mlxsw_sp_lag_put(), so this is a single missed release.
Fix the leak by replacing the bare 'return err' with a goto to the existing error cleanup label, which will drop the reference safely.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +1 -1
@@ -4462,7 +4462,7 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port, err =mlxsw_sp_port_lag_index_get (mlxsw_sp, lag_id, &port_index);if (err) -return err; + goto err_lag_uppers_bridge_join; err =mlxsw_sp_lag_uppers_bridge_join (mlxsw_sp_port, lag_dev, extack);
Signature · 1 line
2.53.0