From: Shay Drori <shayd@nvidia.com>
To: Tariq Toukan <tariqt@nvidia.com>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
"Andrew Lunn" <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>
Cc: Saeed Mahameed <saeedm@nvidia.com>,
Leon Romanovsky <leon@kernel.org>, Mark Bloch <mbloch@nvidia.com>,
Nimrod Oren <noren@nvidia.com>, Yael Chemla <ychemla@nvidia.com>,
Or Har-Toov <ohartoov@nvidia.com>,
Edward Srouji <edwards@nvidia.com>,
Maher Sanalla <msanalla@nvidia.com>,
Simon Horman <horms@kernel.org>, Parav Pandit <parav@nvidia.com>,
Patrisious Haddad <phaddad@nvidia.com>,
Kees Cook <kees@kernel.org>, Moshe Shemesh <moshe@nvidia.com>,
<linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>,
<linux-rdma@vger.kernel.org>, Gal Pressman <gal@nvidia.com>
Subject: Re: [PATCH net-next 05/13] net/mlx5: LAG, prepare for SD device integration
Date: Thu, 28 May 2026 21:56:13 +0300 [thread overview]
Message-ID: <ded7826e-ac60-4350-9e21-654344fb9c4c@nvidia.com> (raw)
In-Reply-To: <20260527125427.385976-6-tariqt@nvidia.com>
On 27/05/2026 15:54, Tariq Toukan wrote:
> From: Shay Drory <shayd@nvidia.com>
>
> Socket Direct (SD) secondaries devices will participate in LAG, even
> though they are silent. SD secondary devices share the same physical
> port as their primary but are separate PCI functions that need to be
> tracked alongside regular LAG ports.
>
> Extend lag_func with a group_id field to identify SD group membership
> and introduce a unified iterator that can filter by group. Add APIs
> for registering SD secondary devices in an existing LAG.
>
> Signed-off-by: Shay Drory <shayd@nvidia.com>
> Reviewed-by: Mark Bloch <mbloch@nvidia.com>
> Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
> ---
> .../net/ethernet/mellanox/mlx5/core/lag/lag.c | 59 ++++++++++++++-----
> .../net/ethernet/mellanox/mlx5/core/lag/lag.h | 53 +++++++++++++++--
> 2 files changed, 90 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> index 5dfdd799828f..03cb02c7000d 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
> @@ -242,7 +242,7 @@ static void mlx5_ldev_free(struct kref *ref)
> unregister_netdevice_notifier_net(net, &ldev->nb);
> }
>
> - mlx5_ldev_for_each(i, 0, ldev) {
> + mlx5_lag_for_each(i, 0, ldev, MLX5_LAG_FILTER_ALL) {
> pf = mlx5_lag_pf(ldev, i);
> if (pf->port_change_nb.nb.notifier_call) {
> struct mlx5_nb *nb = &pf->port_change_nb;
> @@ -391,7 +391,7 @@ int mlx5_lag_get_dev_seq(struct mlx5_core_dev *dev)
> if (pf && pf->dev == dev)
> return 0;
>
> - mlx5_ldev_for_each(i, 0, ldev) {
> + mlx5_lag_for_each(i, 0, ldev, MLX5_LAG_FILTER_ALL) {
> if (i == master_idx)
> continue;
> pf = mlx5_lag_pf(ldev, i);
> @@ -1034,7 +1034,7 @@ static void mlx5_lag_assert_locked_transition(struct mlx5_lag *ldev)
>
> lockdep_assert_held(&ldev->lock);
>
> - i = mlx5_get_next_ldev_func(ldev, 0);
> + i = mlx5_get_next_lag_func(ldev, 0, MLX5_LAG_FILTER_PORTS);
> if (i < MLX5_MAX_PORTS) {
> pf = mlx5_lag_pf(ldev, i);
> devcom = pf->dev->priv.hca_devcom_comp;
> @@ -1482,7 +1482,7 @@ struct mlx5_devcom_comp_dev *mlx5_lag_get_devcom_comp(struct mlx5_lag *ldev)
> int i;
>
> mutex_lock(&ldev->lock);
> - i = mlx5_get_next_ldev_func(ldev, 0);
> + i = mlx5_get_next_lag_func(ldev, 0, MLX5_LAG_FILTER_PORTS);
> if (i < MLX5_MAX_PORTS) {
> pf = mlx5_lag_pf(ldev, i);
> devcom = pf->dev->priv.hca_devcom_comp;
> @@ -1965,8 +1965,9 @@ static void mlx5_ldev_remove_netdev(struct mlx5_lag *ldev,
> spin_unlock_irqrestore(&lag_lock, flags);
> }
>
> -static int mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
> - struct mlx5_core_dev *dev)
> +int mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
> + struct mlx5_core_dev *dev,
> + u32 group_id)
> {
> struct lag_func *pf;
> u32 idx;
> @@ -1985,8 +1986,14 @@ static int mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
>
> pf->idx = idx;
> pf->dev = dev;
> + pf->group_id = group_id;
Sashiko.dev says:
"Since xa_alloc() was called earlier in this function to insert the
newly allocated pf into the XArray, does this publish the entry before
its fields (dev, group_id) are fully initialized?
Concurrently, if userspace adds a TC rule on the primary device,
mlx5e_tc_add_fdb_flow() iterates over all devcom peers. Because the
secondary
device is added to devcom before being added to LAG, the TC thread will
invoke
mlx5_lag_get_dev_seq() on the secondary device."
At mlx5_ldev_add_mdev() time the netdev hasn't been registered yet,
so userspace cannot reach this device — no TC rule add.
> dev->priv.lag = ldev;
>
> + if (group_id)
> + return 0;
> +
> + xa_set_mark(&ldev->pfs, idx, MLX5_LAG_XA_MARK_PORT);
> +
> MLX5_NB_INIT(&pf->port_change_nb,
> mlx5_lag_mpesw_port_change_event, PORT_CHANGE);
> mlx5_eq_notifier_register(dev, &pf->port_change_nb);
> @@ -1994,13 +2001,13 @@ static int mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
> return 0;
> }
>
> -static void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev,
> - struct mlx5_core_dev *dev)
> +void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev,
> + struct mlx5_core_dev *dev)
> {
> struct lag_func *pf;
> int i;
>
> - mlx5_ldev_for_each(i, 0, ldev) {
> + mlx5_lag_for_each(i, 0, ldev, MLX5_LAG_FILTER_ALL) {
> pf = mlx5_lag_pf(ldev, i);
> if (pf->dev == dev)
> break;
> @@ -2035,7 +2042,7 @@ static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
> mlx5_core_err(dev, "Failed to alloc lag dev\n");
> return 0;
> }
> - err = mlx5_ldev_add_mdev(ldev, dev);
> + err = mlx5_ldev_add_mdev(ldev, dev, 0);
> if (err) {
> mlx5_core_err(dev, "Failed to add mdev to lag dev\n");
> mlx5_ldev_put(ldev);
> @@ -2050,7 +2057,7 @@ static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
> return -EAGAIN;
> }
> mlx5_ldev_get(ldev);
> - err = mlx5_ldev_add_mdev(ldev, dev);
> + err = mlx5_ldev_add_mdev(ldev, dev, 0);
> if (err) {
> mlx5_ldev_put(ldev);
> mutex_unlock(&ldev->lock);
> @@ -2187,27 +2194,47 @@ void mlx5_lag_add_netdev(struct mlx5_core_dev *dev,
> mlx5_queue_bond_work(ldev, 0);
> }
>
> -int mlx5_get_pre_ldev_func(struct mlx5_lag *ldev, int start_idx, int end_idx)
> +int mlx5_get_pre_lag_func(struct mlx5_lag *ldev, int start_idx, int end_idx,
> + u32 filter)
> {
> struct lag_func *pf;
> int i;
>
> for (i = start_idx; i >= end_idx; i--) {
> pf = xa_load(&ldev->pfs, i);
> - if (pf && pf->dev)
> + if (!pf || !pf->dev)
> + continue;
> + if (filter == MLX5_LAG_FILTER_PORTS) {
> + if (xa_get_mark(&ldev->pfs, i, MLX5_LAG_XA_MARK_PORT))
> + return i;
> + } else if (filter == MLX5_LAG_FILTER_ALL ||
> + filter == pf->group_id) {
> return i;
> + }
> }
> return -1;
> }
>
> -int mlx5_get_next_ldev_func(struct mlx5_lag *ldev, int start_idx)
> +int mlx5_get_next_lag_func(struct mlx5_lag *ldev, int start_idx, u32 filter)
> {
> struct lag_func *pf;
> unsigned long idx;
>
> - xa_for_each_start(&ldev->pfs, idx, pf, start_idx)
> - if (pf->dev)
> + if (filter == MLX5_LAG_FILTER_PORTS) {
> + xa_for_each_marked_start(&ldev->pfs, idx, pf,
> + MLX5_LAG_XA_MARK_PORT, start_idx)
> + if (pf->dev)
> + return idx;
> + return MLX5_MAX_PORTS;
> + }
> +
> + xa_for_each_start(&ldev->pfs, idx, pf, start_idx) {
> + if (!pf->dev)
> + continue;
> + if (filter == MLX5_LAG_FILTER_ALL ||
> + filter == pf->group_id)
> return idx;
> + }
> return MLX5_MAX_PORTS;
> }
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
> index 23c0457ce799..70baa7997364 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
> @@ -15,6 +15,13 @@
> * Note: XA_MARK_0 is reserved by XA_FLAGS_ALLOC for free-slot tracking.
> */
> #define MLX5_LAG_XA_MARK_MASTER XA_MARK_1
> +/* XArray mark for port-level entries (excludes SD secondaries) */
> +#define MLX5_LAG_XA_MARK_PORT XA_MARK_2
> +
> +/* Like xa_for_each_marked but starting from a given index */
> +#define xa_for_each_marked_start(xa, index, entry, filter, start) \
> + for (index = start, entry = xa_find(xa, &index, ULONG_MAX, filter); \
> + entry; entry = xa_find_after(xa, &index, ULONG_MAX, filter))
>
> #include "mlx5_core.h"
> #include "mp.h"
> @@ -50,6 +57,8 @@ struct lag_func {
> bool has_drop;
> unsigned int idx; /* xarray index assigned by LAG */
> struct mlx5_nb port_change_nb;
> + u32 group_id; /* SD group ID, 0 = not SD */
> + bool sd_fdb_active; /* set on all SD group members */
> };
>
> /* Used for collection of netdev event info. */
> @@ -125,6 +134,20 @@ mlx5_lag_pf_by_dev_idx(struct mlx5_lag *ldev, int dev_idx)
> return NULL;
> }
>
> +/* Find lag_func by mlx5_core_dev pointer */
> +static inline struct lag_func *
> +mlx5_lag_pf_by_dev(struct mlx5_lag *ldev, struct mlx5_core_dev *dev)
> +{
> + struct lag_func *pf;
> + unsigned long idx;
> +
> + xa_for_each(&ldev->pfs, idx, pf) {
> + if (pf->dev == dev)
> + return pf;
> + }
> + return NULL;
> +}
> +
> static inline bool
> __mlx5_lag_is_active(struct mlx5_lag *ldev)
> {
> @@ -214,20 +237,38 @@ static inline bool mlx5_lag_is_supported(struct mlx5_core_dev *dev)
> return true;
> }
>
> -#define mlx5_ldev_for_each(i, start_index, ldev) \
> - for (int tmp = start_index; tmp = mlx5_get_next_ldev_func(ldev, tmp), \
> +/* Iterator filter constants for mlx5_lag_for_each() */
> +#define MLX5_LAG_FILTER_ALL 0 /* iterate ALL devices */
> +#define MLX5_LAG_FILTER_PORTS U32_MAX /* iterate ports only (XA_MARK_PORT) */
> +/* any other value = iterate devices with that specific group_id */
> +
> +#define mlx5_lag_for_each(i, start_index, ldev, filter) \
> + for (int tmp = start_index; \
> + tmp = mlx5_get_next_lag_func(ldev, tmp, filter), \
> i = tmp, tmp < MLX5_MAX_PORTS; tmp++)
>
> -#define mlx5_ldev_for_each_reverse(i, start_index, end_index, ldev) \
> +#define mlx5_lag_for_each_reverse(i, start_index, end_index, ldev, filter) \
> for (int tmp = start_index, tmp1 = end_index; \
> - tmp = mlx5_get_pre_ldev_func(ldev, tmp, tmp1), \
> + tmp = mlx5_get_pre_lag_func(ldev, tmp, tmp1, filter), \
> i = tmp, tmp >= tmp1; tmp--)
>
> -int mlx5_get_pre_ldev_func(struct mlx5_lag *ldev, int start_idx, int end_idx);
> -int mlx5_get_next_ldev_func(struct mlx5_lag *ldev, int start_idx);
> +/* Convenience wrappers - keeps existing behavior */
> +#define mlx5_ldev_for_each(i, start_index, ldev) \
> + mlx5_lag_for_each(i, start_index, ldev, MLX5_LAG_FILTER_PORTS)
> +
> +#define mlx5_ldev_for_each_reverse(i, start_index, end_index, ldev) \
> + mlx5_lag_for_each_reverse(i, start_index, end_index, ldev, \
> + MLX5_LAG_FILTER_PORTS)
> +
> +int mlx5_get_pre_lag_func(struct mlx5_lag *ldev, int start_idx, int end_idx,
> + u32 filter);
> +int mlx5_get_next_lag_func(struct mlx5_lag *ldev, int start_idx, u32 filter);
> int mlx5_lag_get_dev_index_by_seq(struct mlx5_lag *ldev, int seq);
> int mlx5_lag_num_devs(struct mlx5_lag *ldev);
> int mlx5_lag_num_netdevs(struct mlx5_lag *ldev);
> int mlx5_lag_reload_ib_reps_from_locked(struct mlx5_lag *ldev, u32 flags,
> bool cont_on_fail);
> +int mlx5_ldev_add_mdev(struct mlx5_lag *ldev, struct mlx5_core_dev *dev,
> + u32 group_id);
> +void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev, struct mlx5_core_dev *dev);
> #endif /* __MLX5_LAG_H__ */
next prev parent reply other threads:[~2026-05-28 18:56 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-27 12:54 [PATCH net-next 00/13] net/mlx5: Add switchdev mode support for Socket Direct single netdev, part 1/2 Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 01/13] net/mlx5: LAG, factor out shared FDB code into dedicated file Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 02/13] net/mlx5: E-Switch, align disable sequence with switchdev-to-legacy transition Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 03/13] net/mlx5: E-Switch, move devcom init from TC to eswitch layer Tariq Toukan
2026-05-28 18:48 ` Shay Drori
2026-05-27 12:54 ` [PATCH net-next 04/13] net/mlx5: LAG, replace peer count check with direct peer lookup Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 05/13] net/mlx5: LAG, prepare for SD device integration Tariq Toukan
2026-05-28 18:56 ` Shay Drori [this message]
2026-05-27 12:54 ` [PATCH net-next 06/13] net/mlx5: LAG, extend shared FDB API with group_id filter Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 07/13] net/mlx5: SD, introduce Socket Direct LAG Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 08/13] net/mlx5: LAG, block RoCE and VF LAG for SD devices Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 09/13] net/mlx5: LAG, block multipath " Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 10/13] net/mlx5: SD, keep netdev resources on same PF in switchdev mode Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 11/13] net/mlx5e: TC, track peer flow slots with bitmap Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 12/13] net/mlx5e: TC, enable steering for SD LAG Tariq Toukan
2026-05-27 12:54 ` [PATCH net-next 13/13] net/mlx5e: Verify unique vhca_id count instead of range Tariq Toukan
2026-05-27 22:08 ` [PATCH net-next 00/13] net/mlx5: Add switchdev mode support for Socket Direct single netdev, part 1/2 Jacob Keller
2026-05-28 9:18 ` Shay Drori
2026-05-28 17:59 ` Jacob Keller
2026-05-29 0:40 ` Jakub Kicinski
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=ded7826e-ac60-4350-9e21-654344fb9c4c@nvidia.com \
--to=shayd@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=edwards@nvidia.com \
--cc=gal@nvidia.com \
--cc=horms@kernel.org \
--cc=kees@kernel.org \
--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=msanalla@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=noren@nvidia.com \
--cc=ohartoov@nvidia.com \
--cc=pabeni@redhat.com \
--cc=parav@nvidia.com \
--cc=phaddad@nvidia.com \
--cc=saeedm@nvidia.com \
--cc=tariqt@nvidia.com \
--cc=ychemla@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®