mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
net/mlx5: LAG, factor out shared FDB code into dedicated file
Refactor shared FDB LAG logic into a new lag/shared_fdb.c file to improve code organization and enable reuse. Move shared FDB specific functions from lag.c and introduce consolidated APIs: - mlx5_lag_shared_fdb_create() handles LAG activation with shared FDB - mlx5_lag_shared_fdb_destroy() handles LAG deactivation with shared FDB Update mlx5_do_bond(), mlx5_disable_lag() and mpesw.c to use the new APIs, which simplifies the shared FDB code paths. Signed-off-by: Shay Drory <shayd@nvidia.com> Reviewed-by: Mark Bloch <mbloch@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20260531113954.395443-2-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
dfcc2ff129
commit
cf6c4c0508
|
|
@ -41,7 +41,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_EN_DCB) += en_dcbnl.o en/port_buffer.o
|
|||
mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += en/hv_vhca_stats.o
|
||||
mlx5_core-$(CONFIG_MLX5_ESWITCH) += lag/mp.o lag/port_sel.o lib/geneve.o lib/port_tun.o \
|
||||
en_rep.o en/rep/bond.o en/mod_hdr.o \
|
||||
en/mapping.o lag/mpesw.o
|
||||
en/mapping.o lag/mpesw.o lag/shared_fdb.o
|
||||
mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \
|
||||
lib/fs_chains.o en/tc_tun.o \
|
||||
esw/indir_table.o en/tc_tun_encap.o \
|
||||
|
|
|
|||
|
|
@ -817,43 +817,6 @@ char *mlx5_get_str_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
|
|||
}
|
||||
}
|
||||
|
||||
static int mlx5_lag_create_single_fdb(struct mlx5_lag *ldev)
|
||||
{
|
||||
int master_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
struct mlx5_eswitch *master_esw;
|
||||
struct mlx5_core_dev *dev0;
|
||||
int i, j;
|
||||
int err;
|
||||
|
||||
if (master_idx < 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev0 = mlx5_lag_pf(ldev, master_idx)->dev;
|
||||
master_esw = dev0->priv.eswitch;
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
struct mlx5_eswitch *slave_esw;
|
||||
|
||||
if (i == master_idx)
|
||||
continue;
|
||||
|
||||
slave_esw = mlx5_lag_pf(ldev, i)->dev->priv.eswitch;
|
||||
|
||||
err = mlx5_eswitch_offloads_single_fdb_add_one(master_esw,
|
||||
slave_esw, ldev->ports);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
mlx5_ldev_for_each_reverse(j, i, 0, ldev) {
|
||||
if (j == master_idx)
|
||||
continue;
|
||||
mlx5_eswitch_offloads_single_fdb_del_one(master_esw,
|
||||
mlx5_lag_pf(ldev, j)->dev->priv.eswitch);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlx5_create_lag(struct mlx5_lag *ldev,
|
||||
struct lag_tracker *tracker,
|
||||
enum mlx5_lag_mode mode,
|
||||
|
|
@ -1218,12 +1181,15 @@ void mlx5_disable_lag(struct mlx5_lag *ldev)
|
|||
if (idx < 0)
|
||||
return;
|
||||
|
||||
if (shared_fdb) {
|
||||
mlx5_lag_shared_fdb_destroy(ldev);
|
||||
return;
|
||||
}
|
||||
|
||||
dev0 = mlx5_lag_pf(ldev, idx)->dev;
|
||||
roce_lag = __mlx5_lag_is_roce(ldev);
|
||||
|
||||
if (shared_fdb) {
|
||||
mlx5_lag_remove_devices(ldev);
|
||||
} else if (roce_lag) {
|
||||
if (roce_lag) {
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, false);
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
if (i == idx)
|
||||
|
|
@ -1236,49 +1202,8 @@ void mlx5_disable_lag(struct mlx5_lag *ldev)
|
|||
if (err)
|
||||
return;
|
||||
|
||||
if (shared_fdb || roce_lag)
|
||||
if (roce_lag)
|
||||
mlx5_lag_add_devices(ldev);
|
||||
|
||||
if (shared_fdb)
|
||||
mlx5_lag_reload_ib_reps_from_locked(ldev,
|
||||
MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV,
|
||||
true);
|
||||
}
|
||||
|
||||
bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev)
|
||||
{
|
||||
struct mlx5_core_dev *dev;
|
||||
bool ret = false;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
if (idx < 0)
|
||||
return false;
|
||||
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
if (i == idx)
|
||||
continue;
|
||||
dev = mlx5_lag_pf(ldev, i)->dev;
|
||||
if (is_mdev_switchdev_mode(dev) &&
|
||||
mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch) &&
|
||||
MLX5_CAP_GEN(dev, lag_native_fdb_selection) &&
|
||||
MLX5_CAP_ESW(dev, root_ft_on_other_esw) &&
|
||||
mlx5_eswitch_get_npeers(dev->priv.eswitch) ==
|
||||
MLX5_CAP_GEN(dev, num_lag_ports) - 1)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
dev = mlx5_lag_pf(ldev, idx)->dev;
|
||||
if (is_mdev_switchdev_mode(dev) &&
|
||||
mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch) &&
|
||||
mlx5_esw_offloads_devcom_is_ready(dev->priv.eswitch) &&
|
||||
MLX5_CAP_ESW(dev, esw_shared_ingress_acl) &&
|
||||
mlx5_eswitch_get_npeers(dev->priv.eswitch) == MLX5_CAP_GEN(dev, num_lag_ports) - 1)
|
||||
ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool mlx5_lag_is_roce_lag(struct mlx5_lag *ldev)
|
||||
|
|
@ -1493,46 +1418,36 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
|
|||
|
||||
roce_lag = mlx5_lag_is_roce_lag(ldev);
|
||||
|
||||
if (shared_fdb || roce_lag)
|
||||
mlx5_lag_remove_devices(ldev);
|
||||
|
||||
err = mlx5_activate_lag(ldev, &tracker,
|
||||
roce_lag ? MLX5_LAG_MODE_ROCE :
|
||||
MLX5_LAG_MODE_SRIOV,
|
||||
shared_fdb);
|
||||
if (err) {
|
||||
if (shared_fdb || roce_lag)
|
||||
mlx5_lag_add_devices(ldev);
|
||||
if (shared_fdb)
|
||||
mlx5_lag_reload_ib_reps_from_locked(ldev, 0,
|
||||
true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (roce_lag) {
|
||||
struct mlx5_core_dev *dev;
|
||||
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, true);
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
if (i == idx)
|
||||
continue;
|
||||
dev = mlx5_lag_pf(ldev, i)->dev;
|
||||
if (mlx5_get_roce_state(dev))
|
||||
mlx5_nic_vport_enable_roce(dev);
|
||||
}
|
||||
} else if (shared_fdb) {
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, true);
|
||||
err = mlx5_lag_reload_ib_reps_from_locked(ldev, 0,
|
||||
false);
|
||||
if (err) {
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, false);
|
||||
mlx5_deactivate_lag(ldev);
|
||||
mlx5_lag_add_devices(ldev);
|
||||
mlx5_lag_reload_ib_reps_from_locked(ldev, 0,
|
||||
true);
|
||||
mlx5_core_err(dev0, "Failed to enable lag\n");
|
||||
if (shared_fdb) {
|
||||
err = mlx5_lag_shared_fdb_create(ldev, &tracker,
|
||||
MLX5_LAG_MODE_SRIOV);
|
||||
if (err)
|
||||
return;
|
||||
} else {
|
||||
if (roce_lag)
|
||||
mlx5_lag_remove_devices(ldev);
|
||||
|
||||
err = mlx5_activate_lag(ldev, &tracker,
|
||||
roce_lag ? MLX5_LAG_MODE_ROCE :
|
||||
MLX5_LAG_MODE_SRIOV,
|
||||
false);
|
||||
if (err) {
|
||||
if (roce_lag)
|
||||
mlx5_lag_add_devices(ldev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (roce_lag) {
|
||||
struct mlx5_core_dev *dev;
|
||||
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, true);
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
if (i == idx)
|
||||
continue;
|
||||
dev = mlx5_lag_pf(ldev, i)->dev;
|
||||
if (mlx5_get_roce_state(dev))
|
||||
mlx5_nic_vport_enable_roce(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
|
||||
|
|
@ -1545,7 +1460,8 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
|
|||
ndev);
|
||||
dev_put(ndev);
|
||||
}
|
||||
mlx5_lag_set_vports_agg_speed(ldev);
|
||||
if (!shared_fdb)
|
||||
mlx5_lag_set_vports_agg_speed(ldev);
|
||||
} else if (mlx5_lag_should_modify_lag(ldev, do_bond)) {
|
||||
mlx5_modify_lag(ldev, &tracker);
|
||||
mlx5_lag_set_vports_agg_speed(ldev);
|
||||
|
|
|
|||
|
|
@ -137,7 +137,33 @@ mlx5_lag_is_ready(struct mlx5_lag *ldev)
|
|||
return test_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MLX5_ESWITCH
|
||||
int mlx5_lag_shared_fdb_create(struct mlx5_lag *ldev,
|
||||
struct lag_tracker *tracker,
|
||||
enum mlx5_lag_mode mode);
|
||||
void mlx5_lag_shared_fdb_destroy(struct mlx5_lag *ldev);
|
||||
int mlx5_lag_create_single_fdb(struct mlx5_lag *ldev);
|
||||
bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev);
|
||||
#else
|
||||
static inline int mlx5_lag_shared_fdb_create(struct mlx5_lag *ldev,
|
||||
struct lag_tracker *tracker,
|
||||
enum mlx5_lag_mode mode)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void mlx5_lag_shared_fdb_destroy(struct mlx5_lag *ldev) {}
|
||||
|
||||
static inline int mlx5_lag_create_single_fdb(struct mlx5_lag *ldev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
bool mlx5_lag_check_prereq(struct mlx5_lag *ldev);
|
||||
int mlx5_lag_demux_init(struct mlx5_core_dev *dev,
|
||||
struct mlx5_flow_table_attr *ft_attr);
|
||||
|
|
|
|||
|
|
@ -92,38 +92,21 @@ static int mlx5_lag_enable_mpesw(struct mlx5_lag *ldev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
mlx5_lag_remove_devices(ldev);
|
||||
|
||||
err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, true);
|
||||
err = mlx5_lag_shared_fdb_create(ldev, NULL, MLX5_LAG_MODE_MPESW);
|
||||
if (err) {
|
||||
mlx5_core_warn(dev0, "Failed to create LAG in MPESW mode (%d)\n", err);
|
||||
goto err_add_devices;
|
||||
mlx5_mpesw_metadata_cleanup(ldev);
|
||||
return err;
|
||||
}
|
||||
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, true);
|
||||
err = mlx5_lag_reload_ib_reps_from_locked(ldev, 0, false);
|
||||
if (err)
|
||||
goto err_rescan_drivers;
|
||||
|
||||
mlx5_lag_set_vports_agg_speed(ldev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_rescan_drivers:
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, false);
|
||||
mlx5_deactivate_lag(ldev);
|
||||
err_add_devices:
|
||||
mlx5_lag_add_devices(ldev);
|
||||
mlx5_lag_reload_ib_reps_from_locked(ldev, 0, true);
|
||||
mlx5_mpesw_metadata_cleanup(ldev);
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlx5_lag_disable_mpesw(struct mlx5_lag *ldev)
|
||||
{
|
||||
if (ldev->mode == MLX5_LAG_MODE_MPESW) {
|
||||
mlx5_mpesw_metadata_cleanup(ldev);
|
||||
mlx5_disable_lag(ldev);
|
||||
mlx5_lag_shared_fdb_destroy(ldev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
143
drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c
Normal file
143
drivers/net/ethernet/mellanox/mlx5/core/lag/shared_fdb.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include <linux/mlx5/eswitch.h>
|
||||
#include "mlx5_core.h"
|
||||
#include "lag.h"
|
||||
#include "eswitch.h"
|
||||
|
||||
bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev)
|
||||
{
|
||||
struct mlx5_core_dev *dev;
|
||||
bool ret = false;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
if (idx < 0)
|
||||
return false;
|
||||
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
if (i == idx)
|
||||
continue;
|
||||
dev = mlx5_lag_pf(ldev, i)->dev;
|
||||
if (is_mdev_switchdev_mode(dev) &&
|
||||
mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch) &&
|
||||
MLX5_CAP_GEN(dev, lag_native_fdb_selection) &&
|
||||
MLX5_CAP_ESW(dev, root_ft_on_other_esw) &&
|
||||
mlx5_eswitch_get_npeers(dev->priv.eswitch) ==
|
||||
MLX5_CAP_GEN(dev, num_lag_ports) - 1)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
dev = mlx5_lag_pf(ldev, idx)->dev;
|
||||
if (is_mdev_switchdev_mode(dev) &&
|
||||
mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch) &&
|
||||
mlx5_esw_offloads_devcom_is_ready(dev->priv.eswitch) &&
|
||||
MLX5_CAP_ESW(dev, esw_shared_ingress_acl) &&
|
||||
mlx5_eswitch_get_npeers(dev->priv.eswitch) ==
|
||||
MLX5_CAP_GEN(dev, num_lag_ports) - 1)
|
||||
ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mlx5_lag_create_single_fdb(struct mlx5_lag *ldev)
|
||||
{
|
||||
int master_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
struct mlx5_eswitch *master_esw;
|
||||
struct mlx5_core_dev *dev0;
|
||||
int i, j;
|
||||
int err;
|
||||
|
||||
if (master_idx < 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev0 = mlx5_lag_pf(ldev, master_idx)->dev;
|
||||
master_esw = dev0->priv.eswitch;
|
||||
mlx5_ldev_for_each(i, 0, ldev) {
|
||||
struct mlx5_eswitch *slave_esw;
|
||||
|
||||
if (i == master_idx)
|
||||
continue;
|
||||
|
||||
slave_esw = mlx5_lag_pf(ldev, i)->dev->priv.eswitch;
|
||||
|
||||
err = mlx5_eswitch_offloads_single_fdb_add_one(master_esw,
|
||||
slave_esw,
|
||||
ldev->ports);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
mlx5_ldev_for_each_reverse(j, i, 0, ldev) {
|
||||
struct mlx5_eswitch *slave_esw;
|
||||
|
||||
if (j == master_idx)
|
||||
continue;
|
||||
slave_esw = mlx5_lag_pf(ldev, j)->dev->priv.eswitch;
|
||||
mlx5_eswitch_offloads_single_fdb_del_one(master_esw, slave_esw);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_lag_shared_fdb_create(struct mlx5_lag *ldev,
|
||||
struct lag_tracker *tracker,
|
||||
enum mlx5_lag_mode mode)
|
||||
{
|
||||
int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
|
||||
struct mlx5_core_dev *dev0;
|
||||
int err;
|
||||
|
||||
if (idx < 0)
|
||||
return -EINVAL;
|
||||
|
||||
dev0 = mlx5_lag_pf(ldev, idx)->dev;
|
||||
|
||||
mlx5_lag_remove_devices(ldev);
|
||||
|
||||
err = mlx5_activate_lag(ldev, tracker, mode, true);
|
||||
if (err) {
|
||||
mlx5_core_warn(dev0, "Failed to create LAG in shared FDB mode (%d)\n",
|
||||
err);
|
||||
goto err_add_devices;
|
||||
}
|
||||
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, true);
|
||||
err = mlx5_lag_reload_ib_reps_from_locked(ldev, 0, false);
|
||||
if (err) {
|
||||
mlx5_core_err(dev0, "Failed to enable lag\n");
|
||||
goto err_rescan_drivers;
|
||||
}
|
||||
|
||||
mlx5_lag_set_vports_agg_speed(ldev);
|
||||
return 0;
|
||||
|
||||
err_rescan_drivers:
|
||||
mlx5_lag_rescan_dev_locked(ldev, dev0, false);
|
||||
mlx5_deactivate_lag(ldev);
|
||||
err_add_devices:
|
||||
mlx5_lag_add_devices(ldev);
|
||||
mlx5_lag_reload_ib_reps_from_locked(ldev, 0, true);
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlx5_lag_shared_fdb_destroy(struct mlx5_lag *ldev)
|
||||
{
|
||||
int err;
|
||||
|
||||
mlx5_lag_remove_devices(ldev);
|
||||
|
||||
err = mlx5_deactivate_lag(ldev);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
mlx5_lag_add_devices(ldev);
|
||||
mlx5_lag_reload_ib_reps_from_locked(ldev,
|
||||
MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV,
|
||||
true);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user