From: Shay Drori <shayd@nvidia.com>
To: Tariq Toukan <tariqt@nvidia.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, <netdev@vger.kernel.org>,
Paolo Abeni <pabeni@redhat.com>
Cc: Akiva Goldberger <agoldberger@nvidia.com>,
Carolina Jubran <cjubran@nvidia.com>,
Cosmin Ratiu <cratiu@nvidia.com>,
Edward Srouji <edwards@nvidia.com>, Gal Pressman <gal@nvidia.com>,
Leon Romanovsky <leon@kernel.org>,
open list <linux-kernel@vger.kernel.org>,
<linux-rdma@vger.kernel.org>, Mark Bloch <mbloch@nvidia.com>,
Moshe Shemesh <moshe@nvidia.com>,
Or Har-Toov <ohartoov@nvidia.com>,
Patrisious Haddad <phaddad@nvidia.com>,
Saeed Mahameed <saeedm@nvidia.com>
Subject: Re: [PATCH net-next 10/15] net/mlx5: LAG, do not add a device to an already-active LAG
Date: Mon, 9 Nov 2026 20:31:01 +0200 [thread overview]
Message-ID: <8a521a4d-2b05-4c9a-a8d7-ddd0ea465f81@nvidia.com> (raw)
In-Reply-To: <20261103171009.563034-11-tariqt@nvidia.com>
On 03/11/2026 19:10, Tariq Toukan wrote:
> From: Shay Drory <shayd@nvidia.com>
>
> mlx5_ldev_add_mdev() would add a newly probed device to the LAG even
> when the LAG is already active, mutating membership while getters may be
> iterating it and while the active mapping assumes a fixed member set.
>
> Reject the join when the group's LAG is active:
> __mlx5_lag_dev_add_mdev() returns -EOPNOTSUPP, and mlx5_lag_add_mdev()
> treats that as terminal - unregister the HCA devcom component and leave
> the device standalone, rather than the -EAGAIN retry used for the
> bounded mode-change window.
> The device stays out of the LAG until it is reprobed.
>
> This keeps LAG membership stable while active. It is a no-op for
> existing configurations, where no device is added to a LAG once it is
> active.
>
answers to net-dev sashiko
Sashiko (Low):
This isn't a bug, but the commit message describes a broader rule than
the code implements. The subject says "do not add a device to an
already-active LAG", and the body says:
"Reject the join when the group's LAG is active"
"This keeps LAG membership stable while active."
The check here only fires when mlx5_virt_lag_is_supported(dev) is true,
which means multi_uplink_eswitch and lag_master are set and
num_lag_ports < 2. A device that is not virt LAG capable can still join
an active ldev through this path.
sd_lag_init() in lib/sd.c, the other caller of mlx5_ldev_add_mdev(),
also adds SD secondaries to the primary's ldev without checking
__mlx5_lag_is_active():
err = mlx5_ldev_add_mdev(ldev, pos, sd->group_id);
Could the commit message say that the rejection applies only to virt
LAG capable functions, or explain why the other join paths are safe?
[SD] The other join paths are safe. A LAG of PFs is activated only
once all the PFs of the card are members, so there is no further PF that
could join it, and SD secondaries join at load, before MPESW can be
enabled. A LAG of VFs/SFs is the only one whose members come and go
independently of the activation, which is why the check is for virt LAG
capable functions only.
In case of v2, The commit message will be fixed.
> In addition, do not register the eswitch devcom component of such a
> device, so it does not pair with the eswitches of the LAG members.
>
> Signed-off-by: Shay Drory <shayd@nvidia.com>
> Reviewed-by: Mark Bloch <mbloch@nvidia.com>
> Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
> Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
> ---
> .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 4 ++++
> drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 9 +++++++++
> drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h | 5 +++++
> 3 files changed, 18 insertions(+)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
> index c712848b202d..70e6dd9561a6 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
> @@ -3573,6 +3573,10 @@ void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw,
> xa_init(&esw->offloads.peer_flows);
> mutex_init(&esw->offloads.peer_mutex);
>
> + /* do not pair a virt LAG capable VF/SF that is not part of a LAG */
> + if (!mlx5_core_is_pf(esw->dev) && mlx5_virt_lag_nonmember(esw->dev))
> + return;
> +
> if (!MLX5_CAP_ESW(esw->dev, merged_eswitch))
> return;
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> index 9bc4a929cef3..d73bac8441f7 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> @@ -2449,6 +2449,11 @@ static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
> mutex_unlock(&ldev->lock);
> return -EAGAIN;
> }
> +
> + if (mlx5_virt_lag_is_supported(dev) && __mlx5_lag_is_active(ldev)) {
> + mutex_unlock(&ldev->lock);
> + return -EOPNOTSUPP;
> + }
> mlx5_ldev_get(ldev);
> err = mlx5_ldev_add_mdev(ldev, dev, 0);
> if (err) {
> @@ -2537,6 +2542,10 @@ void mlx5_lag_add_mdev(struct mlx5_core_dev *dev)
> err = __mlx5_lag_dev_add_mdev(dev);
> mlx5_devcom_comp_unlock(dev->priv.hca_devcom_comp);
>
> + if (err == -EOPNOTSUPP) {
> + mlx5_lag_unregister_hca_devcom_comp(dev);
> + return;
> + }
> if (err) {
> msleep(100);
> goto recheck;
Sashiko (Medium):
After this change only -EOPNOTSUPP is final. Every other error from
__mlx5_lag_dev_add_mdev() is retried with no limit. Can this loop
forever on an error that waiting will not clear?
__mlx5_lag_dev_add_mdev() returns the mlx5_ldev_add_mdev() error
unchanged, and mlx5_ldev_add_mdev() does:
err = xa_alloc(&ldev->fns, &idx, fn, XA_LIMIT(0, U8_MAX - 1),
GFP_KERNEL);
if (err) {
kfree(fn);
return err;
}
xa_alloc() returns -EBUSY once all 255 slots are in use. Two earlier
commits in this series make that reachable:
"net/mlx5: LAG, decouple iteration end-of-walk from MLX5_MAX_PORTS"
raised the limit from MLX5_MAX_PORTS - 1.
"net/mlx5: LAG, enable LAG over functions that do not represent a
physical port" lets virt LAG capable VFs and SFs join.
mlx5_sw_guid_sf() and mlx5_sw_guid_vf() return a constant marker. So
all such SFs (and likewise all such VFs) on the same HW share one
devcom key, and they end up in the same ldev when they share a netns.
With 255 members already present and the LAG inactive, the next probe
would see:
mlx5_load()
mlx5_lag_add_mdev()
__mlx5_lag_dev_add_mdev()
mlx5_ldev_add_mdev()
xa_alloc() returns -EBUSY
msleep(100); goto recheck;
Membership does not change while it waits, so mlx5_load() would never
return. Because the thread sleeps in 100ms steps, the hung task detector
would not report it, and unbinding that device would block behind the
probe thread. The final state of the series still has this loop.
It is not clear whether firmware actually exposes that many virt LAG
capable functions in one group. Would it make sense to retry only on
-EAGAIN and give up on other errors?
[SD] This is pre-existing: mlx5_lag_add_mdev() retried every error
before this series as well. for example future HW can return -EBUSY.
The fix will be sent as a separate patch.
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
> index cbe380ae8bf9..385c767e24ae 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
> @@ -280,6 +280,11 @@ static inline bool mlx5_virt_lag_is_supported(const struct mlx5_core_dev *dev)
> return true;
> }
>
> +static inline bool mlx5_virt_lag_nonmember(struct mlx5_core_dev *dev)
> +{
> + return mlx5_virt_lag_is_supported(dev) && !mlx5_lag_dev(dev);
> +}
> +
> static inline bool mlx5_lag_is_supported(struct mlx5_core_dev *dev)
> {
> if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
next prev parent reply other threads:[~2026-11-09 18:31 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 17:09 [PATCH net-next 00/15] net/mlx5: LAG over VFs/SFs (virtual LAG) Tariq Toukan
2026-11-03 17:09 ` [PATCH net-next 01/15] net/mlx5: Distinguish VFs/SFs in the SW system image GUID for LAG grouping Tariq Toukan
2026-11-09 17:22 ` Shay Drori
2026-11-03 17:09 ` [PATCH net-next 02/15] net/mlx5: LAG, select the MPESW master from the live member snapshot Tariq Toukan
2026-11-03 17:09 ` [PATCH net-next 03/15] net/mlx5: LAG, skip phys LAG prerequisites for a virt LAG Tariq Toukan
2026-11-03 17:09 ` [PATCH net-next 04/15] net/mlx5: LAG, treat virt LAG as a software managed LAG Tariq Toukan
2026-11-03 17:09 ` [PATCH net-next 05/15] net/mlx5: LAG, decouple iteration end-of-walk from MLX5_MAX_PORTS Tariq Toukan
2026-11-09 18:21 ` Shay Drori
2026-11-03 17:10 ` [PATCH net-next 06/15] net/mlx5: LAG, rename PF naming to fn Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 07/15] net/mlx5: LAG, resolve affinity indices only in queue-affinity mode Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 08/15] net/mlx5: LAG: replace fixed MLX5_MAX_PORTS arrays with dynamic allocation Tariq Toukan
2026-11-09 18:26 ` Shay Drori
2026-11-03 17:10 ` [PATCH net-next 09/15] net/mlx5: LAG, drop MLX5_MAX_PORTS scratch array from device rescan Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 10/15] net/mlx5: LAG, do not add a device to an already-active LAG Tariq Toukan
2026-11-09 18:31 ` Shay Drori [this message]
2026-11-03 17:10 ` [PATCH net-next 11/15] net/mlx5: E-switch, add match-metadata allocator for nested VF/SF eswitches Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 12/15] net/mlx5: E-switch, match master egress rule by vport metadata Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 13/15] net/mlx5: E-switch, drop master egress rule under a SW vport LAG Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 14/15] net/mlx5e: Register eswitch-manager VF/SF self-port with switch-id Tariq Toukan
2026-11-03 17:10 ` [PATCH net-next 15/15] net/mlx5: LAG, enable LAG over functions that do not represent a physical port Tariq Toukan
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=8a521a4d-2b05-4c9a-a8d7-ddd0ea465f81@nvidia.com \
--to=shayd@nvidia.com \
--cc=agoldberger@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=cjubran@nvidia.com \
--cc=cratiu@nvidia.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=edwards@nvidia.com \
--cc=gal@nvidia.com \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mbloch@nvidia.com \
--cc=moshe@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=ohartoov@nvidia.com \
--cc=pabeni@redhat.com \
--cc=phaddad@nvidia.com \
--cc=saeedm@nvidia.com \
--cc=tariqt@nvidia.com \
/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
all inboxes | Powered by JetHome®