]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net/mlx5: SD, expend vport metadata for SD secondary devices
authorShay Drory <shayd@nvidia.com>
Fri, 12 Jun 2026 11:38:55 +0000 (14:38 +0300)
committerJakub Kicinski <kuba@kernel.org>
Mon, 15 Jun 2026 18:40:50 +0000 (11:40 -0700)
In Socket Direct configurations the primary and secondary PFs share the
same native_port_num. The eswitch vport metadata encodes pf_num in its
upper bits to distinguish vports across PFs. Without SD-awareness, both
PFs generate identical metadata, causing FDB rules to steer traffic to
the wrong representor.

Add mlx5_sd_pf_num_get() which remaps the pf_num for SD devices.
Use it so each PF in an SD group produces unique vport metadata.

Signed-off-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260612113904.537595-7-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c
drivers/net/ethernet/mellanox/mlx5/core/lib/sd.h

index 12805e80ce57d9db4f03fd6b73d13f0061b02baf..366531d8ef023c28e9425d818a37055743029602 100644 (file)
@@ -3472,12 +3472,12 @@ u32 mlx5_esw_match_metadata_alloc(struct mlx5_eswitch *esw)
        u32 vport_end_ida = (1 << ESW_VPORT_BITS) - 1;
        /* Reserve 0xf for internal port offload */
        u32 max_pf_num = (1 << ESW_PFNUM_BITS) - 2;
-       u32 pf_num;
+       int pf_num;
        int id;
 
        /* Only 4 bits of pf_num */
-       pf_num = mlx5_get_dev_index(esw->dev);
-       if (pf_num > max_pf_num)
+       pf_num = mlx5_sd_pf_num_get(esw->dev);
+       if (pf_num < 0 || pf_num > max_pf_num)
                return 0;
 
        /* Metadata is 4 bits of PFNUM and 12 bits of unique id */
index 6b007b038f8b7f6106948cd35080fb70019a39e9..c670ed1dd63cfbdaa6404556721359f407e0eb9d 100644 (file)
@@ -85,6 +85,27 @@ bool mlx5_sd_is_primary(struct mlx5_core_dev *dev)
        return sd->primary;
 }
 
+int mlx5_sd_pf_num_get(struct mlx5_core_dev *dev)
+{
+       struct mlx5_sd *sd = mlx5_get_sd(dev);
+       int pf_num = mlx5_get_dev_index(dev);
+       struct mlx5_core_dev *pos;
+       int i;
+
+       if (!sd)
+               return pf_num;
+
+       mlx5_devcom_comp_assert_locked(sd->devcom);
+       if (!mlx5_devcom_comp_is_ready(sd->devcom))
+               return -ENODEV;
+
+       mlx5_sd_for_each_dev(i, mlx5_sd_get_primary(dev), pos)
+               if (pos == dev)
+                       break;
+
+       return pf_num * sd->host_buses + i;
+}
+
 struct mlx5_core_dev *
 mlx5_sd_primary_get_peer(struct mlx5_core_dev *primary, int idx)
 {
index 011702ff6f0272733e4b7009a7ea22c72aaccdb1..7a41adbcee71b84ae43c4509f017d05388ee5781 100644 (file)
@@ -12,6 +12,7 @@ struct mlx5_sd;
 
 struct mlx5_core_dev *mlx5_sd_get_primary(struct mlx5_core_dev *dev);
 bool mlx5_sd_is_primary(struct mlx5_core_dev *dev);
+int mlx5_sd_pf_num_get(struct mlx5_core_dev *dev);
 struct mlx5_core_dev *mlx5_sd_primary_get_peer(struct mlx5_core_dev *primary, int idx);
 int mlx5_sd_ch_ix_get_dev_ix(struct mlx5_core_dev *dev, int ch_ix);
 int mlx5_sd_ch_ix_get_vec_ix(struct mlx5_core_dev *dev, int ch_ix);