Skip to content

Commit 7a9fb35

Browse files
roidayanSaeed Mahameed
authored andcommitted
net/mlx5e: Do not reload ethernet ports when changing eswitch mode
When switching modes between legacy and switchdev and back, do not reload ethernet interfaces. just change the profile from nic profile to uplink rep profile in switchdev mode. Signed-off-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent fec2b4b commit 7a9fb35

File tree

8 files changed

+116
-54
lines changed

8 files changed

+116
-54
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ static bool is_eth_supported(struct mlx5_core_dev *dev)
5858
if (!IS_ENABLED(CONFIG_MLX5_CORE_EN))
5959
return false;
6060

61-
if (is_eth_rep_supported(dev))
62-
return false;
63-
6461
if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
6562
return false;
6663

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,7 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv);
11731173
void mlx5e_destroy_netdev(struct mlx5e_priv *priv);
11741174
int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
11751175
const struct mlx5e_profile *new_profile, void *new_ppriv);
1176+
void mlx5e_netdev_attach_nic_profile(struct mlx5e_priv *priv);
11761177
void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv);
11771178
void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 mtu);
11781179
void mlx5e_build_rq_params(struct mlx5_core_dev *mdev,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,4 +635,5 @@ void mlx5e_reporter_rx_destroy(struct mlx5e_priv *priv)
635635
return;
636636

637637
devlink_port_health_reporter_destroy(priv->rx_reporter);
638+
priv->rx_reporter = NULL;
638639
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,4 +593,5 @@ void mlx5e_reporter_tx_destroy(struct mlx5e_priv *priv)
593593
return;
594594

595595
devlink_port_health_reporter_destroy(priv->tx_reporter);
596+
priv->tx_reporter = NULL;
596597
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5742,6 +5742,11 @@ int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
57425742
return err;
57435743
}
57445744

5745+
void mlx5e_netdev_attach_nic_profile(struct mlx5e_priv *priv)
5746+
{
5747+
mlx5e_netdev_change_profile(priv, &mlx5e_nic_profile, NULL);
5748+
}
5749+
57455750
void mlx5e_destroy_netdev(struct mlx5e_priv *priv)
57465751
{
57475752
struct net_device *netdev = priv->netdev;
@@ -5852,6 +5857,7 @@ static int mlx5e_probe(struct auxiliary_device *adev,
58525857
mlx5e_devlink_port_type_eth_set(priv);
58535858

58545859
mlx5e_dcbnl_init_app(priv);
5860+
mlx5_uplink_netdev_set(mdev, netdev);
58555861
return 0;
58565862

58575863
err_resume:

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

Lines changed: 97 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "en_tc.h"
4545
#include "en/rep/tc.h"
4646
#include "en/rep/neigh.h"
47+
#include "en/devlink.h"
4748
#include "fs_core.h"
4849
#include "lib/mlx5.h"
4950
#define CREATE_TRACE_POINTS
@@ -588,26 +589,15 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
588589
}
589590

590591
static void mlx5e_build_rep_netdev(struct net_device *netdev,
591-
struct mlx5_core_dev *mdev,
592-
struct mlx5_eswitch_rep *rep)
592+
struct mlx5_core_dev *mdev)
593593
{
594594
SET_NETDEV_DEV(netdev, mdev->device);
595-
if (rep->vport == MLX5_VPORT_UPLINK) {
596-
netdev->netdev_ops = &mlx5e_netdev_ops;
597-
/* we want a persistent mac for the uplink rep */
598-
mlx5_query_mac_address(mdev, netdev->dev_addr);
599-
netdev->ethtool_ops = &mlx5e_ethtool_ops;
600-
mlx5e_dcbnl_build_rep_netdev(netdev);
601-
} else {
602-
netdev->netdev_ops = &mlx5e_netdev_ops_rep;
603-
eth_hw_addr_random(netdev);
604-
netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
605-
}
595+
netdev->netdev_ops = &mlx5e_netdev_ops_rep;
596+
eth_hw_addr_random(netdev);
597+
netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
606598

607599
netdev->watchdog_timeo = 15 * HZ;
608600

609-
netdev->features |= NETIF_F_NETNS_LOCAL;
610-
611601
#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
612602
netdev->hw_features |= NETIF_F_HW_TC;
613603
#endif
@@ -619,12 +609,9 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev,
619609
netdev->hw_features |= NETIF_F_TSO6;
620610
netdev->hw_features |= NETIF_F_RXCSUM;
621611

622-
if (rep->vport == MLX5_VPORT_UPLINK)
623-
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
624-
else
625-
netdev->features |= NETIF_F_VLAN_CHALLENGED;
626-
627612
netdev->features |= netdev->hw_features;
613+
netdev->features |= NETIF_F_VLAN_CHALLENGED;
614+
netdev->features |= NETIF_F_NETNS_LOCAL;
628615
}
629616

630617
static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
@@ -990,13 +977,27 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
990977
mlx5e_dcbnl_initialize(priv);
991978
mlx5e_dcbnl_init_app(priv);
992979
mlx5e_rep_neigh_init(rpriv);
980+
981+
netdev->wanted_features |= NETIF_F_HW_TC;
982+
983+
rtnl_lock();
984+
if (netif_running(netdev))
985+
mlx5e_open(netdev);
986+
netif_device_attach(netdev);
987+
rtnl_unlock();
993988
}
994989

995990
static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
996991
{
997992
struct mlx5e_rep_priv *rpriv = priv->ppriv;
998993
struct mlx5_core_dev *mdev = priv->mdev;
999994

995+
rtnl_lock();
996+
if (netif_running(priv->netdev))
997+
mlx5e_close(priv->netdev);
998+
netif_device_detach(priv->netdev);
999+
rtnl_unlock();
1000+
10001001
mlx5e_rep_neigh_cleanup(rpriv);
10011002
mlx5e_dcbnl_delete_app(priv);
10021003
mlx5_notifier_unregister(mdev, &priv->events_nb);
@@ -1081,26 +1082,56 @@ static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
10811082

10821083
/* e-Switch vport representors */
10831084
static int
1084-
mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1085+
mlx5e_vport_uplink_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1086+
{
1087+
struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
1088+
struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1089+
struct devlink_port *dl_port;
1090+
int err;
1091+
1092+
rpriv->netdev = priv->netdev;
1093+
1094+
err = mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
1095+
rpriv);
1096+
if (err)
1097+
return err;
1098+
1099+
dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1100+
if (dl_port)
1101+
devlink_port_type_eth_set(dl_port, rpriv->netdev);
1102+
1103+
return 0;
1104+
}
1105+
1106+
static void
1107+
mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv)
1108+
{
1109+
struct net_device *netdev = rpriv->netdev;
1110+
struct devlink_port *dl_port;
1111+
struct mlx5_core_dev *dev;
1112+
struct mlx5e_priv *priv;
1113+
1114+
priv = netdev_priv(netdev);
1115+
dev = priv->mdev;
1116+
1117+
dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1118+
if (dl_port)
1119+
devlink_port_type_clear(dl_port);
1120+
mlx5e_netdev_attach_nic_profile(priv);
1121+
}
1122+
1123+
static int
1124+
mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
10851125
{
1126+
struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
10861127
const struct mlx5e_profile *profile;
1087-
struct mlx5e_rep_priv *rpriv;
10881128
struct devlink_port *dl_port;
10891129
struct net_device *netdev;
10901130
struct mlx5e_priv *priv;
10911131
unsigned int txqs, rxqs;
10921132
int nch, err;
10931133

1094-
rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1095-
if (!rpriv)
1096-
return -ENOMEM;
1097-
1098-
/* rpriv->rep to be looked up when profile->init() is called */
1099-
rpriv->rep = rep;
1100-
1101-
profile = (rep->vport == MLX5_VPORT_UPLINK) ?
1102-
&mlx5e_uplink_rep_profile : &mlx5e_rep_profile;
1103-
1134+
profile = &mlx5e_rep_profile;
11041135
nch = mlx5e_get_max_num_channels(dev);
11051136
txqs = nch * profile->max_tc;
11061137
rxqs = nch * profile->rq_groups;
@@ -1109,29 +1140,19 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
11091140
mlx5_core_warn(dev,
11101141
"Failed to create representor netdev for vport %d\n",
11111142
rep->vport);
1112-
kfree(rpriv);
11131143
return -EINVAL;
11141144
}
11151145

1116-
mlx5e_build_rep_netdev(netdev, dev, rep);
1117-
1146+
mlx5e_build_rep_netdev(netdev, dev);
11181147
rpriv->netdev = netdev;
1119-
rep->rep_data[REP_ETH].priv = rpriv;
1120-
INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1121-
1122-
if (rep->vport == MLX5_VPORT_UPLINK) {
1123-
err = mlx5e_create_mdev_resources(dev);
1124-
if (err)
1125-
goto err_destroy_netdev;
1126-
}
11271148

11281149
priv = netdev_priv(netdev);
11291150
priv->profile = profile;
11301151
priv->ppriv = rpriv;
11311152
err = profile->init(dev, netdev);
11321153
if (err) {
11331154
netdev_warn(netdev, "rep profile init failed, %d\n", err);
1134-
goto err_destroy_mdev_resources;
1155+
goto err_destroy_netdev;
11351156
}
11361157

11371158
err = mlx5e_attach_netdev(netdev_priv(netdev));
@@ -1161,13 +1182,34 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
11611182
err_cleanup_profile:
11621183
priv->profile->cleanup(priv);
11631184

1164-
err_destroy_mdev_resources:
1165-
if (rep->vport == MLX5_VPORT_UPLINK)
1166-
mlx5e_destroy_mdev_resources(dev);
1167-
11681185
err_destroy_netdev:
11691186
mlx5e_destroy_netdev(netdev_priv(netdev));
1170-
kfree(rpriv);
1187+
return err;
1188+
}
1189+
1190+
static int
1191+
mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1192+
{
1193+
struct mlx5e_rep_priv *rpriv;
1194+
int err;
1195+
1196+
rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1197+
if (!rpriv)
1198+
return -ENOMEM;
1199+
1200+
/* rpriv->rep to be looked up when profile->init() is called */
1201+
rpriv->rep = rep;
1202+
rep->rep_data[REP_ETH].priv = rpriv;
1203+
INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1204+
1205+
if (rep->vport == MLX5_VPORT_UPLINK)
1206+
err = mlx5e_vport_uplink_rep_load(dev, rep);
1207+
else
1208+
err = mlx5e_vport_vf_rep_load(dev, rep);
1209+
1210+
if (err)
1211+
kfree(rpriv);
1212+
11711213
return err;
11721214
}
11731215

@@ -1181,15 +1223,19 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
11811223
struct devlink_port *dl_port;
11821224
void *ppriv = priv->ppriv;
11831225

1226+
if (rep->vport == MLX5_VPORT_UPLINK) {
1227+
mlx5e_vport_uplink_rep_unload(rpriv);
1228+
goto free_ppriv;
1229+
}
1230+
11841231
dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
11851232
if (dl_port)
11861233
devlink_port_type_clear(dl_port);
11871234
unregister_netdev(netdev);
11881235
mlx5e_detach_netdev(priv);
11891236
priv->profile->cleanup(priv);
1190-
if (rep->vport == MLX5_VPORT_UPLINK)
1191-
mlx5e_destroy_mdev_resources(priv->mdev);
11921237
mlx5e_destroy_netdev(priv);
1238+
free_ppriv:
11931239
kfree(ppriv); /* mlx5e_rep_priv */
11941240
}
11951241

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,13 @@ static inline struct net *mlx5_core_net(struct mlx5_core_dev *dev)
9595
return devlink_net(priv_to_devlink(dev));
9696
}
9797

98+
static inline void mlx5_uplink_netdev_set(struct mlx5_core_dev *mdev, struct net_device *netdev)
99+
{
100+
mdev->mlx5e_res.uplink_netdev = netdev;
101+
}
102+
103+
static inline struct net_device *mlx5_uplink_netdev_get(struct mlx5_core_dev *mdev)
104+
{
105+
return mdev->mlx5e_res.uplink_netdev;
106+
}
98107
#endif

include/linux/mlx5/driver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ struct mlx5e_resources {
651651
struct mlx5_sq_bfreg bfreg;
652652
} hw_objs;
653653
struct devlink_port dl_port;
654+
struct net_device *uplink_netdev;
654655
};
655656

656657
enum mlx5_sw_icm_type {

0 commit comments

Comments
 (0)