net/mlx5e: Check netdev pointer before checking its net ns
authorGavin Li <gavinl@nvidia.com>
Thu, 31 Aug 2023 02:47:09 +0000 (05:47 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Dec 2023 16:01:45 +0000 (17:01 +0100)
[ Upstream commit 7aaf975238c47b710fcc4eca0da1e7902a53abe2 ]

Previously, when comparing the net namespaces, the case where the netdev
doesn't exist wasn't taken into account, and therefore can cause a crash.
In such a case, the comparing function should return false, as there is no
netdev->net to compare the devlink->net to.

Furthermore, this will result in an attempt to enter switchdev mode
without a netdev to fail, and which is the desired result as there is no
meaning in switchdev mode without a net device.

Fixes: 662404b24a4c ("net/mlx5e: Block entering switchdev mode with ns inconsistency")
Signed-off-by: Gavin Li <gavinl@nvidia.com>
Reviewed-by: Gavi Teitz <gavi@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

index bf78eeca401beaa0ac1101bef22324ebef3d38f0..bb8bcb448ae903c6bdb66e67722075c8073773bb 100644 (file)
@@ -3653,14 +3653,18 @@ static int esw_inline_mode_to_devlink(u8 mlx5_mode, u8 *mode)
 
 static bool esw_offloads_devlink_ns_eq_netdev_ns(struct devlink *devlink)
 {
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
        struct net *devl_net, *netdev_net;
-       struct mlx5_eswitch *esw;
-
-       esw = mlx5_devlink_eswitch_nocheck_get(devlink);
-       netdev_net = dev_net(esw->dev->mlx5e_res.uplink_netdev);
-       devl_net = devlink_net(devlink);
+       bool ret = false;
 
-       return net_eq(devl_net, netdev_net);
+       mutex_lock(&dev->mlx5e_res.uplink_netdev_lock);
+       if (dev->mlx5e_res.uplink_netdev) {
+               netdev_net = dev_net(dev->mlx5e_res.uplink_netdev);
+               devl_net = devlink_net(devlink);
+               ret = net_eq(devl_net, netdev_net);
+       }
+       mutex_unlock(&dev->mlx5e_res.uplink_netdev_lock);
+       return ret;
 }
 
 int mlx5_eswitch_block_mode(struct mlx5_core_dev *dev)