From: Tariq Toukan <tariqt@nvidia.com>
To: 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: Andrea Parri <parri.andrea@gmail.com>,
Boris Pismenny <borisp@nvidia.com>,
Cosmin Ratiu <cratiu@nvidia.com>,
Dragos Tatulea <dtatulea@nvidia.com>,
"Gal Pressman" <gal@nvidia.com>,
Jeroen Massar <jmassar@nvidia.com>,
Jianbo Liu <jianbol@nvidia.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
Leon Romanovsky <leon@kernel.org>,
open list <linux-kernel@vger.kernel.org>,
<linux-rdma@vger.kernel.org>, Mark Bloch <mbloch@nvidia.com>,
"Patrisious Haddad" <phaddad@nvidia.com>,
Prathamesh Deshpande <prathameshdeshpande7@gmail.com>,
Raed Salem <raeds@nvidia.com>, Roi Dayan <roid@nvidia.com>,
Saeed Mahameed <saeedm@nvidia.com>, Shay Drory <shayd@nvidia.com>,
Simon Horman <horms@kernel.org>,
Steffen Klassert <steffen.klassert@secunet.com>,
Tariq Toukan <tariqt@nvidia.com>
Subject: [PATCH net V3 6/8] net/mlx5e: Block E-Switch mode changes during IPsec policy creation
Date: Thu, 5 Nov 2026 23:16:34 +0200 [thread overview]
Message-ID: <20261105211637.1083978-7-tariqt@nvidia.com> (raw)
In-Reply-To: <20261105211637.1083978-1-tariqt@nvidia.com>
From: Cosmin Ratiu <cratiu@nvidia.com>
Eswitch mode changes can tear down the IPsec context while policy
creation is accessing it. The mode-blocking reference acquired when
creating a flow table comes too late: the table lookup already accesses
the IPsec context before taking that reference.
Take a temporary mode-blocking reference before checking the IPsec
context and validating the policy. This gets dropped after successful
setup, when the flow table holds its own reference.
The temporary reservation must allow reuse of existing IPsec tables.
For example:
1. An offloaded inbound IPsec policy is added on the uplink.
2. A TC flower rule is added on a VF representor.
3. Another uplink policy is added using the same RX tables.
The third policy reuses the first policy's tables, so it must not be
rejected merely because esw->user_count is nonzero. Add a check_users
argument to mlx5_eswitch_block_mode(). Pass false for temporary policy
reservations and true when creating the first table (rx_get()/tx_get()).
Temporary reservations take mode_lock and check operation ownership
without requiring eswitch user_count to be zero.
mlx5e_xfrm_add_state() needs the same early mode reservation and is
handled in the next patch.
This was found by Sashiko, during review of the last patch in the
series. No reproduction attempted, as it seems quite a tricky race to
successfully trigger.
Fixes: a5b8ca9471d3 ("net/mlx5e: Add XFRM policy offload logic")
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
.../mellanox/mlx5/core/en_accel/ipsec.c | 23 +++++++++++++++----
.../mellanox/mlx5/core/en_accel/ipsec_fs.c | 4 ++--
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 8 +++++--
.../mellanox/mlx5/core/eswitch_offloads.c | 9 +++++---
4 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
index 33a7434a7bb9..3cd0b36a02e7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -814,7 +814,7 @@ static int mlx5e_xfrm_add_state(struct net_device *dev,
goto err_xfrm;
}
- err = mlx5_eswitch_block_mode(mdev);
+ err = mlx5_eswitch_block_mode(mdev, true);
if (err)
goto unblock_ipsec;
@@ -1288,18 +1288,28 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
return -EBUSY;
}
+ /* Block esw mode changes until the policy holds its own block. */
+ err = mlx5_eswitch_block_mode(mdev, false);
+ if (err) {
+ NL_SET_ERR_MSG_MOD(extack, "Eswitch busy, can't add policy");
+ return err;
+ }
+
if (!priv->ipsec) {
NL_SET_ERR_MSG_MOD(extack, "Device doesn't support IPsec packet offload");
- return -EOPNOTSUPP;
+ err = -EOPNOTSUPP;
+ goto unblock_mode;
}
err = mlx5e_xfrm_validate_policy(mdev, x, extack);
if (err)
- return err;
+ goto unblock_mode;
pol_entry = kzalloc_obj(*pol_entry);
- if (!pol_entry)
- return -ENOMEM;
+ if (!pol_entry) {
+ err = -ENOMEM;
+ goto unblock_mode;
+ }
pol_entry->x = x;
pol_entry->ipsec = priv->ipsec;
@@ -1315,6 +1325,7 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
goto err_fs;
x->xdo.offload_handle = (unsigned long)pol_entry;
+ mlx5_eswitch_unblock_mode(mdev);
return 0;
err_fs:
@@ -1322,6 +1333,8 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
ipsec_busy:
kfree(pol_entry);
NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy");
+unblock_mode:
+ mlx5_eswitch_unblock_mode(mdev);
return err;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
index 1529d4730323..dbe5547d7a49 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
@@ -1134,7 +1134,7 @@ static int rx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
if (rx->ft.refcnt)
goto skip;
- err = mlx5_eswitch_block_mode(mdev);
+ err = mlx5_eswitch_block_mode(mdev, true);
if (err)
return err;
@@ -1427,7 +1427,7 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
if (tx->ft.refcnt)
goto skip;
- err = mlx5_eswitch_block_mode(mdev);
+ err = mlx5_eswitch_block_mode(mdev, true);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 1fb67fc6d49a..48eb6acc1e87 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -971,7 +971,7 @@ bool mlx5_eswitch_is_peer(struct mlx5_eswitch *esw,
int mlx5_eswitch_block_encap(struct mlx5_core_dev *dev, bool from_fdb);
void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev);
-int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev);
+int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev, bool check_users);
void mlx5_eswitch_unblock_mode(struct mlx5_core_dev *dev);
static inline int mlx5_eswitch_num_vfs(struct mlx5_eswitch *esw)
@@ -1082,7 +1082,11 @@ static inline void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev)
{
}
-static inline int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev) { return 0; }
+static inline int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev,
+ bool check_users)
+{
+ return 0;
+}
static inline void mlx5_eswitch_unblock_mode(struct mlx5_core_dev *dev) {}
static inline bool mlx5_eswitch_block_ipsec(struct mlx5_core_dev *dev)
{
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 4da89fcf215b..474784131091 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -4365,7 +4365,7 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode)
return 0;
}
-int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev)
+int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev, bool check_users)
{
struct mlx5_eswitch *esw = dev->priv.eswitch;
int err;
@@ -4373,8 +4373,11 @@ int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev)
if (!mlx5_esw_allowed(esw))
return 0;
- /* Take TC into account */
- err = mlx5_esw_try_lock(esw);
+ /* Temporary reservations may reuse tables while TC users exist. */
+ if (check_users)
+ err = mlx5_esw_try_lock(esw);
+ else
+ err = mlx5_esw_lock(esw);
if (err < 0)
return err;
--
2.44.0
next prev parent reply other threads:[~2026-11-05 21:18 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-05 21:16 [PATCH net V3 0/8] net/mlx5e: Fix offload lifetime and exclusion bugs Tariq Toukan
2026-11-05 21:16 ` [PATCH net V3 1/8] net/mlx5e: Release IPsec root table reference on RX setup failure Tariq Toukan
2026-11-05 21:16 ` [PATCH net V3 2/8] net/mlx5e: Serialize ipsec encap reservations with eswitch operations Tariq Toukan
2026-11-05 21:16 ` [PATCH net V3 3/8] net/mlx5e: Take HCA devcom lock before esw->mode_lock Tariq Toukan
2026-11-05 21:16 ` [PATCH net V3 4/8] net/mlx5e: Fix E-Switch races in uplink unbind Tariq Toukan
2026-11-05 21:16 ` [PATCH net V3 5/8] net/mlx5e: Fix ipsec core device access during profile changes Tariq Toukan
2026-11-05 21:16 ` Tariq Toukan [this message]
2026-11-05 21:16 ` [PATCH net V3 7/8] net/mlx5e: Block E-Switch mode changes during IPsec state creation Tariq Toukan
2026-11-05 21:16 ` [PATCH net V3 8/8] net/mlx5e: Serialize TC and IPsec offload exclusion counters 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=20261105211637.1083978-7-tariqt@nvidia.com \
--to=tariqt@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=borisp@nvidia.com \
--cc=cratiu@nvidia.com \
--cc=davem@davemloft.net \
--cc=dtatulea@nvidia.com \
--cc=edumazet@kernel.org \
--cc=gal@nvidia.com \
--cc=horms@kernel.org \
--cc=jianbol@nvidia.com \
--cc=jmassar@nvidia.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mbloch@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=parri.andrea@gmail.com \
--cc=phaddad@nvidia.com \
--cc=prathameshdeshpande7@gmail.com \
--cc=raeds@nvidia.com \
--cc=roid@nvidia.com \
--cc=saeedm@nvidia.com \
--cc=shayd@nvidia.com \
--cc=steffen.klassert@secunet.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®