mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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.


  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®