From: Tariq Toukan <tariqt@nvidia.com>
To: Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, <netdev@vger.kernel.org>,
Paolo Abeni <pabeni@redhat.com>
Cc: Akiva Goldberger <agoldberger@nvidia.com>,
Cosmin Ratiu <cratiu@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>,
Saeed Mahameed <saeedm@nvidia.com>, Shay Drory <shayd@nvidia.com>,
Tariq Toukan <tariqt@nvidia.com>
Subject: [PATCH net-next 08/13] net/mlx5e: TC, track peer flows in a vhca_id xarray
Date: Wed, 23 Sep 2026 13:38:25 +0300 [thread overview]
Message-ID: <20260923103830.1183-9-tariqt@nvidia.com> (raw)
In-Reply-To: <20260923103830.1183-1-tariqt@nvidia.com>
From: Shay Drory <shayd@nvidia.com>
The per-peer reverse index lived in a fixed esw->offloads.peer_flows[]
array of list heads indexed by the peer's LAG sequence number, capping a
shared FDB at MLX5_MAX_PORTS members.
Replace the array with an xarray keyed by the peer vhca_id. Each entry
is a heap-allocated list head that chains the flows duplicated to that
peer via their peer node. This lifts the MLX5_MAX_PORTS cap: the number
of peers is bounded only by the number of distinct vhca_ids.
The lifetime of the duplicated peer flows list_head follows the devcom
pairing of the two eswitches:
- pair (mlx5_esw_offloads_pair): kzalloc_obj + INIT_LIST_HEAD +
xa_store the dup_peer_flows under the peer's vhca_id.
- add (mlx5e_tc_add_fdb_peer_flow): xa_load the dup_peer_flows and
list_add the duplicated flow's peer node.
- del (mlx5e_tc_del_fdb_peer_flow): list_del that node.
- flush (mlx5e_tc_clean_fdb_peer_flows): xa_for_each dup_peer_flows,
drop every duplicated flow on it; called from unpair.
- unpair (mlx5_esw_offloads_unpair): xa_erase + kfree the
dup_peer_flows.
So a dup_peer_flows is created when the local eswitch pairs with a peer
over devcom and freed when they unpair.
No functional change.
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 22 +++++++---------
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 2 +-
.../mellanox/mlx5/core/eswitch_offloads.c | 26 ++++++++++++++++---
3 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index fae4f8625da4..c99e824b4c6d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -4596,12 +4596,13 @@ static int mlx5e_tc_add_fdb_peer_flow(struct flow_cls_offload *f,
unsigned long flow_flags,
struct mlx5_eswitch *peer_esw)
{
+ u16 peer_vhca_id = MLX5_CAP_GEN(peer_esw->dev, vhca_id);
struct mlx5e_priv *priv = flow->priv, *peer_priv;
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5_esw_flow_attr *attr = flow->attr->esw_attr;
struct mlx5e_tc_flow_parse_attr *parse_attr;
- int i = mlx5_lag_get_dev_seq(peer_esw->dev);
struct mlx5e_rep_priv *peer_urpriv;
+ struct list_head *dup_peer_flows;
struct mlx5e_tc_flow *peer_flow;
struct mlx5_core_dev *in_mdev;
int err = 0;
@@ -4634,8 +4635,11 @@ static int mlx5e_tc_add_fdb_peer_flow(struct flow_cls_offload *f,
peer_flow->peer_orig = flow;
list_add_tail(&peer_flow->peer_flows, &flow->peer_flows);
flow_flag_set(flow, DUP);
+ dup_peer_flows = xa_load(&esw->offloads.peer_flows, peer_vhca_id);
+ if (!dup_peer_flows)
+ return -ENODEV;
mutex_lock(&esw->offloads.peer_mutex);
- list_add_tail(&peer_flow->peer, &esw->offloads.peer_flows[i]);
+ list_add_tail(&peer_flow->peer, dup_peer_flows);
mutex_unlock(&esw->offloads.peer_mutex);
out:
@@ -5530,20 +5534,14 @@ int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags)
void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw)
{
- struct mlx5_devcom_comp_dev *devcom = esw->devcom, *pos;
struct mlx5e_tc_flow *peer_flow, *tmp_peer_flow;
- struct mlx5_eswitch *peer_esw;
- int i;
-
- mlx5_devcom_for_each_peer_entry(devcom, peer_esw, pos) {
- i = mlx5_lag_get_dev_seq(peer_esw->dev);
- if (i < 0)
- continue;
+ struct list_head *dup_peer_flows;
+ unsigned long index;
+ xa_for_each(&esw->offloads.peer_flows, index, dup_peer_flows)
list_for_each_entry_safe(peer_flow, tmp_peer_flow,
- &esw->offloads.peer_flows[i], peer)
+ dup_peer_flows, peer)
mlx5e_tc_del_fdb_peer_flow(peer_flow);
- }
}
void mlx5e_tc_reoffload_flows_work(struct work_struct *work)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 8b1f93b13ea9..e9cbcd73b23f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -319,7 +319,7 @@ struct mlx5_esw_offload {
struct mlx5_flow_handle *vport_rx_drop_rule;
struct mlx5_flow_table *ft_ipsec_tx_pol;
struct xarray vport_reps;
- struct list_head peer_flows[MLX5_MAX_PORTS];
+ struct xarray peer_flows;
struct mutex peer_mutex;
struct mutex encap_tbl_lock; /* protects encap_tbl */
DECLARE_HASHTABLE(encap_tbl, 8);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index e7d92d9bde16..c712848b202d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -3383,10 +3383,15 @@ static void mlx5_esw_offloads_rep_event_unpair(struct mlx5_eswitch *esw,
static void mlx5_esw_offloads_unpair(struct mlx5_eswitch *esw,
struct mlx5_eswitch *peer_esw)
{
+ struct list_head *dup_peer_flows;
+
#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
mlx5e_tc_clean_fdb_peer_flows(esw);
#endif
mlx5_esw_offloads_rep_event_unpair(esw, peer_esw);
+ dup_peer_flows = xa_erase(&esw->offloads.peer_flows,
+ MLX5_CAP_GEN(peer_esw->dev, vhca_id));
+ kfree(dup_peer_flows);
esw_del_fdb_peer_miss_rules(esw, peer_esw->dev);
}
@@ -3394,6 +3399,7 @@ static int mlx5_esw_offloads_pair(struct mlx5_eswitch *esw,
struct mlx5_eswitch *peer_esw)
{
const struct mlx5_eswitch_rep_ops *ops;
+ struct list_head *dup_peer_flows;
struct mlx5_eswitch_rep *rep;
unsigned long i;
u8 rep_type;
@@ -3403,6 +3409,20 @@ static int mlx5_esw_offloads_pair(struct mlx5_eswitch *esw,
if (err)
return err;
+ dup_peer_flows = kzalloc_obj(*dup_peer_flows);
+ if (!dup_peer_flows) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ INIT_LIST_HEAD(dup_peer_flows);
+ err = xa_err(xa_store(&esw->offloads.peer_flows,
+ MLX5_CAP_GEN(peer_esw->dev, vhca_id),
+ dup_peer_flows, GFP_KERNEL));
+ if (err) {
+ kfree(dup_peer_flows);
+ goto err_out;
+ }
+
mlx5_esw_for_each_rep(esw, i, rep) {
for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
ops = esw->offloads.rep_ops[rep_type];
@@ -3549,10 +3569,8 @@ void mlx5_esw_offloads_devcom_init(struct mlx5_eswitch *esw,
const struct mlx5_devcom_match_attr *attr)
{
int err;
- int i;
- for (i = 0; i < MLX5_MAX_PORTS; i++)
- INIT_LIST_HEAD(&esw->offloads.peer_flows[i]);
+ xa_init(&esw->offloads.peer_flows);
mutex_init(&esw->offloads.peer_mutex);
if (!MLX5_CAP_ESW(esw->dev, merged_eswitch))
@@ -3595,6 +3613,8 @@ void mlx5_esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw)
xa_destroy(&esw->paired);
xa_destroy(&esw->fdb_table.offloads.peer_miss_rules);
esw->devcom = NULL;
+ WARN_ON_ONCE(!xa_empty(&esw->offloads.peer_flows));
+ xa_destroy(&esw->offloads.peer_flows);
}
bool mlx5_esw_offloads_devcom_is_ready(struct mlx5_eswitch *esw)
--
2.44.0
next prev parent reply other threads:[~2026-09-23 10:41 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 10:38 [PATCH net-next 00/13] net/mlx5: Preparations for nested E-switch Tariq Toukan
2026-09-23 10:38 ` [PATCH net-next 01/13] net/mlx5e: Assign a random MAC to any netdev with a zero MAC address Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:45 ` netdev-bot+sashiko
2026-09-23 10:38 ` [PATCH net-next 02/13] net/mlx5: E-switch, do not leave an unpaired devcom registered Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:45 ` netdev-bot+sashiko
2026-09-23 10:38 ` [PATCH net-next 03/13] net/mlx5: LAG, allocate v2p_map dynamically Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:45 ` netdev-bot+sashiko
2026-09-28 14:56 ` Shay Drori
2026-09-23 10:38 ` [PATCH net-next 04/13] net/mlx5: LAG, allocate port-indexed scratch buffers dynamically Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:45 ` netdev-bot+sashiko
2026-09-28 14:57 ` Shay Drori
2026-09-23 10:38 ` [PATCH net-next 05/13] net/mlx5: LAG, drop per-port scratch array in drop-rule setup Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-23 10:38 ` [PATCH net-next 06/13] net/mlx5: LAG, size debugfs buffers by port count Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:45 ` netdev-bot+sashiko
2026-09-23 10:38 ` [PATCH net-next 07/13] net/mlx5e: TC, anchor peer-flow reverse index on the duplicated flow Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:45 ` netdev-bot+sashiko
2026-09-23 10:38 ` Tariq Toukan [this message]
2026-09-24 10:41 ` [PATCH net-next 08/13] net/mlx5e: TC, track peer flows in a vhca_id xarray sashiko-bot
2026-09-24 17:46 ` netdev-bot+sashiko
2026-09-23 10:38 ` [PATCH net-next 09/13] net/mlx5: E-switch, derive manager vport from device capability Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-24 17:46 ` netdev-bot+sashiko
2026-09-28 15:13 ` Shay Drori
2026-09-23 10:38 ` [PATCH net-next 10/13] net/mlx5: LAG, don't print port mapping to debugfs in MPESW mode Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-23 10:38 ` [PATCH net-next 11/13] net/mlx5: LAG, drop stale esw_shared_ingress_acl gate from shared FDB Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-23 10:38 ` [PATCH net-next 12/13] net/mlx5: E-switch, correct stale VF/PF wording in esw-allowed comments Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-23 10:38 ` [PATCH net-next 13/13] net/mlx5: E-switch, disable host functions for a non PF e-switch manager Tariq Toukan
2026-09-24 10:41 ` sashiko-bot
2026-09-29 0:20 ` [PATCH net-next 00/13] net/mlx5: Preparations for nested E-switch patchwork-bot+netdevbpf
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=20260923103830.1183-9-tariqt@nvidia.com \
--to=tariqt@nvidia.com \
--cc=agoldberger@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=cratiu@nvidia.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.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=saeedm@nvidia.com \
--cc=shayd@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.