Skip to content

Commit ee75f1f

Browse files
Jiri Pirkokuba-moo
authored andcommitted
net/mlx5e: Create separate devlink instance for ethernet auxiliary device
The fact that devlink instance lock is held over mlx5 auxiliary devices probe and remove routines brought a need to conditionally take devlink instance lock there. The code is checking a MLX5E_LOCKED_FLOW flag in mlx5 priv struct. This is racy and may lead to access devlink objects without holding instance lock or deadlock. To avoid this, the only lock-wise sane solution is to make the devlink entities created by the auxiliary device independent on the original pci devlink instance. Create devlink instance for the auxiliary device and put the uplink port instance there alongside with the port health reporters. Signed-off-by: Jiri Pirko <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 3a10173 commit ee75f1f

File tree

4 files changed

+55
-23
lines changed

4 files changed

+55
-23
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,10 @@ struct mlx5e_priv {
971971
struct dentry *dfs_root;
972972
};
973973

974+
struct mlx5e_dev {
975+
struct mlx5e_priv *priv;
976+
};
977+
974978
struct mlx5e_rx_handlers {
975979
mlx5e_fp_handle_rx_cqe handle_rx_cqe;
976980
mlx5e_fp_handle_rx_cqe handle_rx_cqe_mpwqe;

drivers/net/ethernet/mellanox/mlx5/core/en/devlink.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
#include "en/devlink.h"
55
#include "eswitch.h"
66

7+
static const struct devlink_ops mlx5e_devlink_ops = {
8+
};
9+
10+
struct mlx5e_dev *mlx5e_create_devlink(struct device *dev)
11+
{
12+
struct mlx5e_dev *mlx5e_dev;
13+
struct devlink *devlink;
14+
15+
devlink = devlink_alloc(&mlx5e_devlink_ops, sizeof(*mlx5e_dev), dev);
16+
if (!devlink)
17+
return ERR_PTR(-ENOMEM);
18+
devlink_register(devlink);
19+
return devlink_priv(devlink);
20+
}
21+
22+
void mlx5e_destroy_devlink(struct mlx5e_dev *mlx5e_dev)
23+
{
24+
struct devlink *devlink = priv_to_devlink(mlx5e_dev);
25+
26+
devlink_unregister(devlink);
27+
devlink_free(devlink);
28+
}
29+
730
static void
831
mlx5e_devlink_get_port_parent_id(struct mlx5_core_dev *dev, struct netdev_phys_item_id *ppid)
932
{
@@ -14,14 +37,14 @@ mlx5e_devlink_get_port_parent_id(struct mlx5_core_dev *dev, struct netdev_phys_i
1437
memcpy(ppid->id, &parent_id, sizeof(parent_id));
1538
}
1639

17-
int mlx5e_devlink_port_register(struct mlx5e_priv *priv)
40+
int mlx5e_devlink_port_register(struct mlx5e_dev *mlx5e_dev,
41+
struct mlx5e_priv *priv)
1842
{
19-
struct devlink *devlink = priv_to_devlink(priv->mdev);
43+
struct devlink *devlink = priv_to_devlink(mlx5e_dev);
2044
struct devlink_port_attrs attrs = {};
2145
struct netdev_phys_item_id ppid = {};
2246
struct devlink_port *dl_port;
2347
unsigned int dl_port_index;
24-
int ret;
2548

2649
if (mlx5_core_is_pf(priv->mdev)) {
2750
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
@@ -42,23 +65,12 @@ int mlx5e_devlink_port_register(struct mlx5e_priv *priv)
4265
memset(dl_port, 0, sizeof(*dl_port));
4366
devlink_port_attrs_set(dl_port, &attrs);
4467

45-
if (!(priv->mdev->priv.flags & MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW))
46-
devl_lock(devlink);
47-
ret = devl_port_register(devlink, dl_port, dl_port_index);
48-
if (!(priv->mdev->priv.flags & MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW))
49-
devl_unlock(devlink);
50-
51-
return ret;
68+
return devlink_port_register(devlink, dl_port, dl_port_index);
5269
}
5370

5471
void mlx5e_devlink_port_unregister(struct mlx5e_priv *priv)
5572
{
5673
struct devlink_port *dl_port = mlx5e_devlink_get_dl_port(priv);
57-
struct devlink *devlink = priv_to_devlink(priv->mdev);
5874

59-
if (!(priv->mdev->priv.flags & MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW))
60-
devl_lock(devlink);
61-
devl_port_unregister(dl_port);
62-
if (!(priv->mdev->priv.flags & MLX5_PRIV_FLAGS_MLX5E_LOCKED_FLOW))
63-
devl_unlock(devlink);
75+
devlink_port_unregister(dl_port);
6476
}

drivers/net/ethernet/mellanox/mlx5/core/en/devlink.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
#include <net/devlink.h>
88
#include "en.h"
99

10-
int mlx5e_devlink_port_register(struct mlx5e_priv *priv);
10+
struct mlx5e_dev *mlx5e_create_devlink(struct device *dev);
11+
void mlx5e_destroy_devlink(struct mlx5e_dev *mlx5e_dev);
12+
int mlx5e_devlink_port_register(struct mlx5e_dev *mlx5e_dev,
13+
struct mlx5e_priv *priv);
1114
void mlx5e_devlink_port_unregister(struct mlx5e_priv *priv);
1215

1316
static inline struct devlink_port *

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5876,7 +5876,8 @@ void mlx5e_destroy_netdev(struct mlx5e_priv *priv)
58765876
static int mlx5e_resume(struct auxiliary_device *adev)
58775877
{
58785878
struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
5879-
struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
5879+
struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
5880+
struct mlx5e_priv *priv = mlx5e_dev->priv;
58805881
struct net_device *netdev = priv->netdev;
58815882
struct mlx5_core_dev *mdev = edev->mdev;
58825883
int err;
@@ -5899,7 +5900,8 @@ static int mlx5e_resume(struct auxiliary_device *adev)
58995900

59005901
static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
59015902
{
5902-
struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
5903+
struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
5904+
struct mlx5e_priv *priv = mlx5e_dev->priv;
59035905
struct net_device *netdev = priv->netdev;
59045906
struct mlx5_core_dev *mdev = priv->mdev;
59055907

@@ -5917,29 +5919,36 @@ static int mlx5e_probe(struct auxiliary_device *adev,
59175919
struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
59185920
const struct mlx5e_profile *profile = &mlx5e_nic_profile;
59195921
struct mlx5_core_dev *mdev = edev->mdev;
5922+
struct mlx5e_dev *mlx5e_dev;
59205923
struct net_device *netdev;
59215924
pm_message_t state = {};
59225925
struct mlx5e_priv *priv;
59235926
int err;
59245927

5928+
mlx5e_dev = mlx5e_create_devlink(&adev->dev);
5929+
if (IS_ERR(mlx5e_dev))
5930+
return PTR_ERR(mlx5e_dev);
5931+
auxiliary_set_drvdata(adev, mlx5e_dev);
5932+
59255933
netdev = mlx5e_create_netdev(mdev, profile);
59265934
if (!netdev) {
59275935
mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
5928-
return -ENOMEM;
5936+
err = -ENOMEM;
5937+
goto err_devlink_unregister;
59295938
}
59305939

59315940
mlx5e_build_nic_netdev(netdev);
59325941

59335942
priv = netdev_priv(netdev);
5934-
auxiliary_set_drvdata(adev, priv);
5943+
mlx5e_dev->priv = priv;
59355944

59365945
priv->profile = profile;
59375946
priv->ppriv = NULL;
59385947

59395948
priv->dfs_root = debugfs_create_dir("nic",
59405949
mlx5_debugfs_get_dev_root(priv->mdev));
59415950

5942-
err = mlx5e_devlink_port_register(priv);
5951+
err = mlx5e_devlink_port_register(mlx5e_dev, priv);
59435952
if (err) {
59445953
mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err);
59455954
goto err_destroy_netdev;
@@ -5978,12 +5987,15 @@ static int mlx5e_probe(struct auxiliary_device *adev,
59785987
err_destroy_netdev:
59795988
debugfs_remove_recursive(priv->dfs_root);
59805989
mlx5e_destroy_netdev(priv);
5990+
err_devlink_unregister:
5991+
mlx5e_destroy_devlink(mlx5e_dev);
59815992
return err;
59825993
}
59835994

59845995
static void mlx5e_remove(struct auxiliary_device *adev)
59855996
{
5986-
struct mlx5e_priv *priv = auxiliary_get_drvdata(adev);
5997+
struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
5998+
struct mlx5e_priv *priv = mlx5e_dev->priv;
59875999
pm_message_t state = {};
59886000

59896001
mlx5e_dcbnl_delete_app(priv);
@@ -5993,6 +6005,7 @@ static void mlx5e_remove(struct auxiliary_device *adev)
59936005
mlx5e_devlink_port_unregister(priv);
59946006
debugfs_remove_recursive(priv->dfs_root);
59956007
mlx5e_destroy_netdev(priv);
6008+
mlx5e_destroy_devlink(mlx5e_dev);
59966009
}
59976010

59986011
static const struct auxiliary_device_id mlx5e_id_table[] = {

0 commit comments

Comments
 (0)