From: Cosmin Ratiu <cratiu@nvidia.com>
To: Tariq Toukan <tariqt@nvidia.com>,
"netdev-bot+sashiko@kernel.org" <netdev-bot+sashiko@kernel.org>
Cc: Boris Pismenny <borisp@nvidia.com>,
"andrew+netdev@lunn.ch" <andrew+netdev@lunn.ch>,
"daniel.zahka@gmail.com" <daniel.zahka@gmail.com>,
"davem@davemloft.net" <davem@davemloft.net>,
Jianbo Liu <jianbol@nvidia.com>,
"sd@queasysnail.net" <sd@queasysnail.net>,
Emeel Hakim <ehakim@nvidia.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"edumazet@google.com" <edumazet@google.com>,
"pabeni@redhat.com" <pabeni@redhat.com>,
"linux-rdma@vger.kernel.org" <linux-rdma@vger.kernel.org>,
Raed Salem <raeds@nvidia.com>,
"leon@kernel.org" <leon@kernel.org>,
Dragos Tatulea <dtatulea@nvidia.com>,
Carolina Jubran <cjubran@nvidia.com>, Roi Dayan <roid@nvidia.com>,
"kuba@kernel.org" <kuba@kernel.org>,
Mark Bloch <mbloch@nvidia.com>,
Lior Nahmanson <liorna@nvidia.com>,
Parav Pandit <parav@nvidia.com>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
Rahul Rameshbabu <rrameshbabu@nvidia.com>,
Gal Pressman <gal@nvidia.com>,
"steffen.klassert@secunet.com" <steffen.klassert@secunet.com>,
Saeed Mahameed <saeedm@nvidia.com>
Subject: Re: [PATCH net 2/7] net/mlx5e: ipsec: Block eswitch mode changes before accessing priv->ipsec
Date: Wed, 23 Sep 2026 07:52:17 +0000 [thread overview]
Message-ID: <45ca577eaacdd5a76a50a361840aba0e0e389658.camel@nvidia.com> (raw)
In-Reply-To: <179001654385.2160803.10690827205473996376@kernel.org>
On Mon, 2026-09-21 at 18:49 +0000, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential
> issue(s) to consider.
>
> Critical: 0 · High: 1 · Medium: 1 (2) · Low: 1
>
> If you believe none of the issues are legitimate, please reply to
> each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let
> patchwork
> know by including "pw-bot: cr" as a separate line at the end of your
> reply
> (one such reply per series is enough).
>
> - [High] By moving mlx5_eswitch_block_mode(priv->mdev, true) to the
> top
> of mlx5e_xfrm_add_state(), the first profile-owned field touched
> is…
> - [Medium] mlx5e_xfrm_add_state() now calls
> mlx5_eswitch_block_mode(priv->mdev, true) *before* checking
> whether…
> - [Low] mlx5e_xfrm_add_state() now emits the generic extack message
> "mlx5_core: Device failed to offload this state" on paths that
> report…
>
> Pre-existing issues:
> - [Medium] The two sibling xfrmdev_ops add callbacks take the same
> temporary eswitch-mode block for the same stated purpose (protect…
> - [Medium] The CONFIG_MLX5_ESWITCH=n stub of
> mlx5_eswitch_block_ipsec()
> (eswitch.h:1090-1093) returns false, i.e. "blocked/busy", whereas
> the…
>
> --
>
> net/mlx5e: ipsec: Block eswitch mode changes before accessing priv-
> >ipsec
>
> This moves the mlx5_eswitch_block_mode() call in
> mlx5e_xfrm_add_state()
> ahead of the first priv->ipsec access so a concurrent profile change
> cannot free the context under it, and releases the block on all error
> paths. The acquire-placeholder path is kept exempt from the block.
>
> A few questions about the reordering below.
>
> > 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 841ecdc2c4d9e..1488faece80eb 100644
> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
> > @@ -771,6 +771,7 @@ static int mlx5e_xfrm_add_state(struct
> > net_device *dev,
> > struct xfrm_state *x,
> > struct netlink_ext_ack *extack)
> > {
> > + bool is_acq = x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ;
> > struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
> > bool allow_tunnel_mode = false;
> > struct mlx5e_ipsec *ipsec;
> > @@ -779,20 +780,30 @@ static int mlx5e_xfrm_add_state(struct
> > net_device *dev,
> > int err;
> >
> > priv = netdev_priv(dev);
> > - if (!priv->ipsec)
> > - return -EOPNOTSUPP;
> > + if (!is_acq) {
> > + err = mlx5_eswitch_block_mode(priv->mdev, true);
> > + if (err)
> > + return err;
> > + }
>
> [Severity: High]
> Can this dereference a NULL priv->mdev? After this change the first
> profile-owned field touched is priv->mdev rather than priv->ipsec,
> and
> mlx5e_priv_cleanup() ends with:
>
> drivers/net/ethernet/mellanox/mlx5/core/en_main.c:mlx5e_priv_cleanup(
> ) {
> ...
> memset(priv, 0, sizeof(*priv));
> }
>
> so priv->mdev can be observed as NULL while the netdev is still
> registered. Besides the transient window between
> mlx5e_priv_cleanup()
> and mlx5e_netdev_init_profile() during a profile change, it also
> stays
> NULL indefinitely when both the new attach and the rollback fail:
>
> drivers/net/ethernet/mellanox/mlx5/core/en_main.c:mlx5e_netdev_change
> _profile() {
> ...
> rollback:
> if (!orig_profile) {
> netdev_warn(netdev, "no original profile to rollback
> to\n");
> priv->profile = NULL;
> return err;
> }
>
> rollback_err = mlx5e_netdev_attach_profile(netdev, mdev,
> orig_profile, orig_ppriv);
> if (rollback_err) {
> netdev_err(netdev, "failed to rollback to orig
> profile, %d\n", rollback_err);
> priv->profile = NULL;
> }
> }
>
> mlx5e_priv_cleanup() itself documents that state with an early
> "if (!priv->mdev) return;". mlx5_eswitch_block_mode() then
> dereferences
> its argument right away:
>
> drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c:mlx5_eswit
> ch_block_mode() {
> struct mlx5_eswitch *esw = dev->priv.eswitch;
> ...
> }
>
> The previous first access, "if (!priv->ipsec) return -EOPNOTSUPP;",
> handled a zeroed priv gracefully. Would a priv->mdev check (or
> keeping
> the priv->ipsec test first) be worth adding here?
Good finding, will do.
>
> [Severity: Medium]
> Does this change the errno userspace sees for crypto-mode offload?
> mlx5_eswitch_block_mode() forwards mlx5_esw_try_lock()'s returns:
>
> drivers/net/ethernet/mellanox/mlx5/core/eswitch.c:mlx5_esw_try_lock()
> {
> if (down_write_trylock(&esw->mode_lock) == 0)
> return -EINVAL;
>
> if (esw->eswitch_operation_in_progress ||
> (check_users && atomic64_read(&esw->user_count) > 0)) {
> up_write(&esw->mode_lock);
> return -EBUSY;
> }
> }
>
> Those now preempt the -EOPNOTSUPP that this netdev used to return
> whenever priv->ipsec was NULL, and only -EOPNOTSUPP gets the software
> fallback in the core:
>
> net/xfrm/xfrm_device.c:xfrm_dev_state_add() {
> if ((err != -EOPNOTSUPP && !is_packet_offload) ||
> is_packet_offload) {
> NL_SET_ERR_MSG_WEAK(extack, "Device failed
> to offload this state");
> return err;
> }
> }
>
> priv->ipsec is NULL when mlx5e_ipsec_init() failed (it logs "IPSec
> initialization failed" and leaves the pointer unset while
> mlx5e_ipsec_build_netdev() has already installed xfrmdev_ops), or
> while
> the profile is detached. So "ip xfrm state add ... offload dev X" in
> crypto mode on such a netdev now fails hard with -EBUSY/-EINVAL
> instead
> of falling back to software. Should the priv->ipsec test stay ahead
> of
> the mode block, or the eswitch error be translated for that case?
Will address.
>
> [Severity: Medium]
> This isn't a bug introduced by this patch (the baseline already
> called
> mlx5_eswitch_block_mode(priv->mdev, true) for every non-acquire SA
> add,
> this only moves it earlier), but the two sibling add callbacks now
> sit
> side by side with opposite check_users arguments for the same stated
> purpose. mlx5e_xfrm_add_policy() uses:
>
> /* Block esw mode changes until the policy holds its own
> block. */
> err = mlx5_eswitch_block_mode(priv->mdev, false);
>
> while mlx5e_xfrm_add_state() passes true, which makes
> mlx5_esw_try_lock() return -EBUSY whenever esw->user_count > 0, i.e.
> whenever any tc flower rule exists on a VF representor - the case the
> preceding commit added check_users to avoid. Was check_users=true
> intentional for the state path?
>
> >
> > ipsec = priv->ipsec;
> > - gfp = (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ) ?
> > GFP_ATOMIC : GFP_KERNEL;
> > + if (!ipsec) {
> > + err = -EOPNOTSUPP;
> > + goto unblock_mode;
> > + }
> > +
> > + gfp = is_acq ? GFP_ATOMIC : GFP_KERNEL;
> > sa_entry = kzalloc_obj(*sa_entry, gfp);
> > - if (!sa_entry)
> > - return -ENOMEM;
> > + if (!sa_entry) {
> > + err = -ENOMEM;
> > + goto unblock_mode;
> > + }
> >
> > sa_entry->x = x;
> > sa_entry->dev = dev;
> > sa_entry->ipsec = ipsec;
> > /* Check if this SA is originated from acquire flow
> > temporary SA */
> > - if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ) {
> > + if (is_acq) {
> > x->xso.offload_handle = (unsigned long)sa_entry;
> > return 0;
> > }
> > @@ -806,10 +817,6 @@ static int mlx5e_xfrm_add_state(struct
> > net_device *dev,
> > goto err_xfrm;
> > }
> >
> > - err = mlx5_eswitch_block_mode(priv->mdev, true);
> > - if (err)
> > - goto unblock_ipsec;
> > -
Will fix.
>
> [Severity: Medium]
> This is a pre-existing issue and not introduced here (git blame
> points
> at 8efd7b17a3b032 from 2023), but while the goto labels on this error
> path are being reshuffled it may be worth noting: the
> CONFIG_MLX5_ESWITCH=n stub has the opposite polarity from the real
> function.
>
> drivers/net/ethernet/mellanox/mlx5/core/eswitch.h:
> static inline bool mlx5_eswitch_block_ipsec(struct mlx5_core_dev
> *dev)
> {
> return false;
> }
>
> drivers/net/ethernet/mellanox/mlx5/core/eswitch.c:mlx5_eswitch_block_
> ipsec() {
> if (!mlx5_esw_allowed(esw))
> return true;
> ...
> }
>
> The caller just above this hunk maps false to -EBUSY:
>
> if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
> err = -EBUSY;
> goto err_xfrm;
> }
>
> so with CONFIG_MLX5_EN_IPSEC=y and CONFIG_MLX5_ESWITCH=n, does every
> SA
> and policy offload fail with -EBUSY? The sibling stubs follow the
> "allow" convention (mlx5_eswitch_block_encap() returns true,
> mlx5_eswitch_block_mode() returns 0).
>
> > if (x->props.mode == XFRM_MODE_TUNNEL &&
> > x->xso.type == XFRM_DEV_OFFLOAD_PACKET) {
> > allow_tunnel_mode =
> > mlx5e_ipsec_fs_tunnel_allowed(sa_entry);
> > @@ -817,7 +824,7 @@ static int mlx5e_xfrm_add_state(struct
> > net_device *dev,
> > NL_SET_ERR_MSG_MOD(extack,
> > "Packet offload tunnel
> > mode is disabled due to encap settings");
> > err = -EINVAL;
> > - goto unblock_mode;
> > + goto unblock_ipsec;
> > }
> > }
> >
> > @@ -893,12 +900,13 @@ static int mlx5e_xfrm_add_state(struct
> > net_device *dev,
> > unblock_encap:
> > if (allow_tunnel_mode)
> > mlx5_eswitch_unblock_encap(priv->mdev);
> > -unblock_mode:
> > - mlx5_eswitch_unblock_mode(priv->mdev);
> > unblock_ipsec:
> > mlx5_eswitch_unblock_ipsec(priv->mdev);
> > err_xfrm:
> > kfree(sa_entry);
> > +unblock_mode:
> > + if (!is_acq)
> > + mlx5_eswitch_unblock_mode(priv->mdev);
> > NL_SET_ERR_MSG_WEAK_MOD(extack, "Device failed to offload
> > this state");
> > return err;
> > }
>
> [Severity: Low]
> Placing unblock_mode above the NL_SET_ERR_MSG_WEAK_MOD() means the
> -EOPNOTSUPP (priv->ipsec == NULL) and -ENOMEM paths now attach
> "mlx5_core: Device failed to offload this state" to the extack, where
> they previously returned silently.
>
> For crypto-mode requests the core swallows -EOPNOTSUPP and returns 0:
>
> net/xfrm/xfrm_device.c:xfrm_dev_state_add() {
> if ((err != -EOPNOTSUPP && !is_packet_offload) ||
> is_packet_offload) {
> NL_SET_ERR_MSG_WEAK(extack, "Device failed
> to offload this state");
> return err;
> }
> }
>
> return 0;
> }
>
> but the message is still delivered:
>
> net/netlink/af_netlink.c:netlink_ack_tlv_len() {
> if (extack->_msg)
> tlvlen += nla_total_size(strlen(extack->_msg) + 1);
> ...
> /* Following attributes are only reported as error (not
> warning) */
> if (!err)
> return tlvlen;
> }
>
> So does a successful "ip xfrm state add ... offload dev X" now print
> "Warning: mlx5_core: Device failed to offload this state"? The
> sibling
> mlx5e_xfrm_add_policy() keeps its generic message above the label:
>
> NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this
> policy");
> unblock_mode:
> mlx5_eswitch_unblock_mode(priv->mdev);
>
> Would the same layout work here?
>
It would, will fix.
Cosmin.
next prev parent reply other threads:[~2026-09-23 7:52 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-17 17:54 [PATCH net 0/7] net/mlx5e: Fix offload lifetime, cleanup and exclusion bugs Tariq Toukan
2026-09-17 17:54 ` [PATCH net 1/7] net/mlx5e: ipsec: Block eswitch mode changes during policy creation Tariq Toukan
2026-09-21 18:49 ` netdev-bot+sashiko
2026-09-23 7:27 ` Cosmin Ratiu
2026-09-17 17:54 ` [PATCH net 2/7] net/mlx5e: ipsec: Block eswitch mode changes before accessing priv->ipsec Tariq Toukan
2026-09-21 18:49 ` netdev-bot+sashiko
2026-09-23 7:52 ` Cosmin Ratiu [this message]
2026-09-17 17:54 ` [PATCH net 3/7] net/mlx5e: tc: Tie esw & accel blocking refs to the flow's lifetime Tariq Toukan
2026-09-21 18:49 ` netdev-bot+sashiko
2026-09-23 7:59 ` Cosmin Ratiu
2026-09-17 17:54 ` [PATCH net 4/7] net/mlx5e: macsec: Track hardware object ownership for SA teardown Tariq Toukan
2026-09-21 18:49 ` netdev-bot+sashiko
2026-09-23 8:32 ` Cosmin Ratiu
2026-09-17 17:54 ` [PATCH net 5/7] net/mlx5e: macsec: Delete remaining SecYs during cleanup Tariq Toukan
2026-09-21 18:49 ` netdev-bot+sashiko
2026-09-23 8:49 ` Cosmin Ratiu
2026-09-17 17:54 ` [PATCH net 6/7] net/mlx5e: Serialize TC and IPsec offload exclusion counters Tariq Toukan
2026-09-17 17:54 ` [PATCH net 7/7] net/mlx5e: shampo: Do not merge PSP packets Tariq Toukan
2026-09-21 18:49 ` netdev-bot+sashiko
2026-09-23 8:50 ` Cosmin Ratiu
2026-09-22 10:44 ` [PATCH net 0/7] net/mlx5e: Fix offload lifetime, cleanup and exclusion bugs Paolo Abeni
2026-09-23 10:47 ` Cosmin Ratiu
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=45ca577eaacdd5a76a50a361840aba0e0e389658.camel@nvidia.com \
--to=cratiu@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=borisp@nvidia.com \
--cc=cjubran@nvidia.com \
--cc=daniel.zahka@gmail.com \
--cc=davem@davemloft.net \
--cc=dtatulea@nvidia.com \
--cc=edumazet@google.com \
--cc=ehakim@nvidia.com \
--cc=gal@nvidia.com \
--cc=jianbol@nvidia.com \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=liorna@nvidia.com \
--cc=mbloch@nvidia.com \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=parav@nvidia.com \
--cc=raeds@nvidia.com \
--cc=roid@nvidia.com \
--cc=rrameshbabu@nvidia.com \
--cc=saeedm@nvidia.com \
--cc=sd@queasysnail.net \
--cc=steffen.klassert@secunet.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®