]> www.infradead.org Git - users/willy/xarray.git/commitdiff
net/mlx5: E-Switch, Cache vport vhca id on first cap query
authorSaeed Mahameed <saeedm@nvidia.com>
Sat, 14 Jun 2025 09:29:41 +0000 (02:29 -0700)
committerSaeed Mahameed <saeedm@nvidia.com>
Fri, 15 Aug 2025 19:17:47 +0000 (12:17 -0700)
We need vhca_id to set up the vhca_id to vport mapping for every vport,
for that we query the firmware in mlx5_esw_vport_vhca_id_set, and it is
redundant since in esw_vport_setup, we already query hca caps which has
the vhca_id, cache it there and save 2 extra fw queries per vport.

Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Reviewed-by: Parav Pandit <parav@nvidia.com>
Signed-off-by: Alexei Lazar <alazar@nvidia.com>
Reviewed-by: Feng Liu <feliu@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

index 4917d185d0c352ceba9b94095dc8f8b5954f0a8c..eeffe9c4aa56206e0379df2a85461ad8bfd5273f 100644 (file)
@@ -820,6 +820,7 @@ static int mlx5_esw_vport_caps_get(struct mlx5_eswitch *esw, struct mlx5_vport *
 
        hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
        vport->info.roce_enabled = MLX5_GET(cmd_hca_cap, hca_caps, roce);
+       vport->vhca_id = MLX5_GET(cmd_hca_cap, hca_caps, vhca_id);
 
        if (!MLX5_CAP_GEN_MAX(esw->dev, hca_cap_2))
                goto out_free;
@@ -929,7 +930,7 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, struct mlx5_vport *vport,
 
        if (!mlx5_esw_is_manager_vport(esw, vport_num) &&
            MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) {
-               ret = mlx5_esw_vport_vhca_id_set(esw, vport_num);
+               ret = mlx5_esw_vport_vhca_id_map(esw, vport);
                if (ret)
                        goto err_vhca_mapping;
        }
@@ -973,7 +974,7 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
 
        if (!mlx5_esw_is_manager_vport(esw, vport_num) &&
            MLX5_CAP_GEN(esw->dev, vhca_resource_manager))
-               mlx5_esw_vport_vhca_id_clear(esw, vport_num);
+               mlx5_esw_vport_vhca_id_unmap(esw, vport);
 
        if (vport->vport != MLX5_VPORT_PF &&
            (vport->info.ipsec_crypto_enabled || vport->info.ipsec_packet_enabled))
@@ -1710,6 +1711,7 @@ static int mlx5_esw_vport_alloc(struct mlx5_eswitch *esw,
        vport->vport = vport_num;
        vport->index = index;
        vport->info.link_state = MLX5_VPORT_ADMIN_STATE_AUTO;
+       vport->vhca_id = MLX5_VHCA_ID_INVALID;
        INIT_WORK(&vport->vport_change_handler, esw_vport_change_handler);
        err = xa_insert(&esw->vports, vport_num, vport, GFP_KERNEL);
        if (err)
index b0b8ef3ec3c47499947531e707cae36ad45f32a0..7f6bfaae5f5f707426e2b7c470624494b3d07e42 100644 (file)
@@ -197,6 +197,11 @@ static inline struct mlx5_vport *mlx5_devlink_port_vport_get(struct devlink_port
        return mlx5_devlink_port_get(dl_port)->vport;
 }
 
+#define MLX5_VHCA_ID_INVALID (-1)
+
+#define MLX5_VPORT_INVAL_VHCA_ID(vport) \
+       ((vport)->vhca_id == MLX5_VHCA_ID_INVALID)
+
 struct mlx5_vport {
        struct mlx5_core_dev    *dev;
        struct hlist_head       uc_list[MLX5_L2_ADDR_HASH_SIZE];
@@ -209,6 +214,7 @@ struct mlx5_vport {
        struct vport_egress     egress;
        u32                     default_metadata;
        u32                     metadata;
+       int                     vhca_id;
 
        struct mlx5_vport_info  info;
 
@@ -822,8 +828,10 @@ struct devlink_port *mlx5_esw_offloads_devlink_port(struct mlx5_eswitch *esw, u1
 
 int mlx5_esw_sf_max_hpf_functions(struct mlx5_core_dev *dev, u16 *max_sfs, u16 *sf_base_id);
 
-int mlx5_esw_vport_vhca_id_set(struct mlx5_eswitch *esw, u16 vport_num);
-void mlx5_esw_vport_vhca_id_clear(struct mlx5_eswitch *esw, u16 vport_num);
+int mlx5_esw_vport_vhca_id_map(struct mlx5_eswitch *esw,
+                              struct mlx5_vport *vport);
+void mlx5_esw_vport_vhca_id_unmap(struct mlx5_eswitch *esw,
+                                 struct mlx5_vport *vport);
 int mlx5_eswitch_vhca_id_to_vport(struct mlx5_eswitch *esw, u16 vhca_id, u16 *vport_num);
 
 /**
index bee906661282aa2e5c7a83afc82ceb2be5ce691b..19decaa8a96efbae345967a711f3f5359ba938a0 100644 (file)
@@ -4161,23 +4161,28 @@ u32 mlx5_eswitch_get_vport_metadata_for_match(struct mlx5_eswitch *esw,
 }
 EXPORT_SYMBOL(mlx5_eswitch_get_vport_metadata_for_match);
 
-int mlx5_esw_vport_vhca_id_set(struct mlx5_eswitch *esw, u16 vport_num)
+int mlx5_esw_vport_vhca_id_map(struct mlx5_eswitch *esw,
+                              struct mlx5_vport *vport)
 {
        u16 *old_entry, *vhca_map_entry, vhca_id;
-       int err;
 
-       err = mlx5_vport_get_vhca_id(esw->dev, vport_num, &vhca_id);
-       if (err) {
-               esw_warn(esw->dev, "Getting vhca_id for vport failed (vport=%u,err=%d)\n",
-                        vport_num, err);
-               return err;
+       if (WARN_ONCE(MLX5_VPORT_INVAL_VHCA_ID(vport),
+                     "vport %d vhca_id is not set", vport->vport)) {
+               int err;
+
+               err = mlx5_vport_get_vhca_id(vport->dev, vport->vport,
+                                            &vhca_id);
+               if (err)
+                       return err;
+               vport->vhca_id = vhca_id;
        }
 
+       vhca_id = vport->vhca_id;
        vhca_map_entry = kmalloc(sizeof(*vhca_map_entry), GFP_KERNEL);
        if (!vhca_map_entry)
                return -ENOMEM;
 
-       *vhca_map_entry = vport_num;
+       *vhca_map_entry = vport->vport;
        old_entry = xa_store(&esw->offloads.vhca_map, vhca_id, vhca_map_entry, GFP_KERNEL);
        if (xa_is_err(old_entry)) {
                kfree(vhca_map_entry);
@@ -4187,17 +4192,12 @@ int mlx5_esw_vport_vhca_id_set(struct mlx5_eswitch *esw, u16 vport_num)
        return 0;
 }
 
-void mlx5_esw_vport_vhca_id_clear(struct mlx5_eswitch *esw, u16 vport_num)
+void mlx5_esw_vport_vhca_id_unmap(struct mlx5_eswitch *esw,
+                                 struct mlx5_vport *vport)
 {
-       u16 *vhca_map_entry, vhca_id;
-       int err;
-
-       err = mlx5_vport_get_vhca_id(esw->dev, vport_num, &vhca_id);
-       if (err)
-               esw_warn(esw->dev, "Getting vhca_id for vport failed (vport=%hu,err=%d)\n",
-                        vport_num, err);
+       u16 *vhca_map_entry;
 
-       vhca_map_entry = xa_erase(&esw->offloads.vhca_map, vhca_id);
+       vhca_map_entry = xa_erase(&esw->offloads.vhca_map, vport->vhca_id);
        kfree(vhca_map_entry);
 }