net/mlx5: LAG, block RoCE and VF LAG for SD devices

Socket Direct devices manage their own LAG via SD LAG infrastructure.
Block the standard netdev-event-driven LAG path (RoCE LAG and VF LAG)
for SD devices to prevent conflicting LAG configurations.

Expose mlx5_sd_is_supported() as a public helper that encapsulates all
SD eligibility checks. Use it in mlx5_lag_dev_alloc() to skip netdev
notifier registration for SD-capable devices at alloc time. Some sd
code is reordered to expose the new function, no logic is changed.

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-9-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Shay Drory 2026-05-31 14:39:48 +03:00 committed by Jakub Kicinski
parent 3c10311083
commit 8b9fffb6d3
3 changed files with 63 additions and 21 deletions

View File

@ -293,11 +293,14 @@ static struct mlx5_lag *mlx5_lag_dev_alloc(struct mlx5_core_dev *dev)
INIT_DELAYED_WORK(&ldev->bond_work, mlx5_do_bond_work);
INIT_WORK(&ldev->speed_update_work, mlx5_mpesw_speed_update_work);
ldev->nb.notifier_call = mlx5_lag_netdev_event;
write_pnet(&ldev->net, mlx5_core_net(dev));
if (register_netdevice_notifier_net(read_pnet(&ldev->net), &ldev->nb)) {
ldev->nb.notifier_call = NULL;
mlx5_core_err(dev, "Failed to register LAG netdev notifier\n");
if (!mlx5_sd_is_supported(dev)) {
ldev->nb.notifier_call = mlx5_lag_netdev_event;
write_pnet(&ldev->net, mlx5_core_net(dev));
if (register_netdevice_notifier_net(read_pnet(&ldev->net),
&ldev->nb)) {
ldev->nb.notifier_call = NULL;
mlx5_core_err(dev, "Failed to register LAG netdev notifier\n");
}
}
ldev->mode = MLX5_LAG_MODE_NONE;

View File

@ -115,7 +115,28 @@ static bool ft_create_alias_supported(struct mlx5_core_dev *dev)
return true;
}
static bool mlx5_sd_is_supported(struct mlx5_core_dev *dev, u8 host_buses)
static int mlx5_query_sd(struct mlx5_core_dev *dev, bool *sdm,
u8 *host_buses)
{
u32 out[MLX5_ST_SZ_DW(mpir_reg)];
int err;
err = mlx5_query_mpir_reg(dev, out);
if (err)
return err;
*sdm = MLX5_GET(mpir_reg, out, sdm);
*host_buses = MLX5_GET(mpir_reg, out, host_buses);
return 0;
}
static u32 mlx5_sd_group_id(struct mlx5_core_dev *dev, u8 sd_group)
{
return (u32)((MLX5_CAP_GEN(dev, native_port_num) << 8) | sd_group);
}
static bool mlx5_sd_caps_supported(struct mlx5_core_dev *dev, u8 host_buses)
{
/* Honor the SW implementation limit */
if (host_buses > MLX5_SD_MAX_GROUP_SZ)
@ -142,25 +163,32 @@ static bool mlx5_sd_is_supported(struct mlx5_core_dev *dev, u8 host_buses)
return true;
}
static int mlx5_query_sd(struct mlx5_core_dev *dev, bool *sdm,
u8 *host_buses)
bool mlx5_sd_is_supported(struct mlx5_core_dev *dev)
{
u32 out[MLX5_ST_SZ_DW(mpir_reg)];
u8 host_buses, sd_group;
bool sdm;
int err;
err = mlx5_query_mpir_reg(dev, out);
if (err)
return err;
/* Feature is currently implemented for PFs only */
if (!mlx5_core_is_pf(dev))
return false;
*sdm = MLX5_GET(mpir_reg, out, sdm);
*host_buses = MLX5_GET(mpir_reg, out, host_buses);
/* Block on embedded CPU PFs */
if (mlx5_core_is_ecpf(dev))
return false;
return 0;
}
err = mlx5_query_nic_vport_sd_group(dev, &sd_group);
if (err || !sd_group)
return false;
static u32 mlx5_sd_group_id(struct mlx5_core_dev *dev, u8 sd_group)
{
return (u32)((MLX5_CAP_GEN(dev, native_port_num) << 8) | sd_group);
if (!MLX5_CAP_MCAM_REG(dev, mpir))
return false;
err = mlx5_query_sd(dev, &sdm, &host_buses);
if (err || !sdm)
return false;
return mlx5_sd_caps_supported(dev, host_buses);
}
static int sd_init(struct mlx5_core_dev *dev)
@ -198,8 +226,8 @@ static int sd_init(struct mlx5_core_dev *dev)
group_id = mlx5_sd_group_id(dev, sd_group);
if (!mlx5_sd_is_supported(dev, host_buses)) {
sd_warn(dev, "can't support requested netdev combining for group id 0x%x), skipping\n",
if (!mlx5_sd_caps_supported(dev, host_buses)) {
sd_warn(dev, "can't support requested netdev combining for group id 0x%x, skipping\n",
group_id);
return 0;
}

View File

@ -4,6 +4,8 @@
#ifndef __MLX5_LIB_SD_H__
#define __MLX5_LIB_SD_H__
#include <linux/types.h>
#define MLX5_SD_MAX_GROUP_SZ 2
struct mlx5_sd;
@ -18,6 +20,15 @@ struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
void mlx5_sd_put_adev(struct auxiliary_device *actual_adev,
struct auxiliary_device *adev);
#ifdef CONFIG_MLX5_CORE_EN
bool mlx5_sd_is_supported(struct mlx5_core_dev *dev);
#else
static inline bool mlx5_sd_is_supported(struct mlx5_core_dev *dev)
{
return false;
}
#endif
int mlx5_sd_init(struct mlx5_core_dev *dev);
void mlx5_sd_cleanup(struct mlx5_core_dev *dev);