Skip to content

Commit 84ae9c1

Browse files
w1ldptrSaeed Mahameed
authored andcommitted
net/mlx5e: E-Switch, Maintain vhca_id to vport_num mapping
Following patches in the series need to be able to map VF netdev to vport. Since it is trivial to obtain vhca_id from netdev, maintain mapping from vhca_id to vport_num inside eswitch offloads using xarray. Provide function mlx5_eswitch_vhca_id_to_vport() to be used by TC code in following patches to obtain the mapping. Signed-off-by: Vlad Buslov <[email protected]> Signed-off-by: Dmytro Linkin <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent b055ecf commit 84ae9c1

File tree

5 files changed

+119
-0
lines changed

5 files changed

+119
-0
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,13 +1300,25 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num,
13001300
(!vport_num && mlx5_core_is_ecpf(esw->dev)))
13011301
vport->info.trusted = true;
13021302

1303+
if (!mlx5_esw_is_manager_vport(esw, vport->vport) &&
1304+
MLX5_CAP_GEN(esw->dev, vhca_resource_manager)) {
1305+
ret = mlx5_esw_vport_vhca_id_set(esw, vport_num);
1306+
if (ret)
1307+
goto err_vhca_mapping;
1308+
}
1309+
13031310
esw_vport_change_handle_locked(vport);
13041311

13051312
esw->enabled_vports++;
13061313
esw_debug(esw->dev, "Enabled VPORT(%d)\n", vport_num);
13071314
done:
13081315
mutex_unlock(&esw->state_lock);
13091316
return ret;
1317+
1318+
err_vhca_mapping:
1319+
esw_vport_cleanup(esw, vport);
1320+
mutex_unlock(&esw->state_lock);
1321+
return ret;
13101322
}
13111323

13121324
void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num)
@@ -1325,6 +1337,11 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, u16 vport_num)
13251337

13261338
/* Disable events from this vport */
13271339
arm_vport_context_events_cmd(esw->dev, vport->vport, 0);
1340+
1341+
if (!mlx5_esw_is_manager_vport(esw, vport->vport) &&
1342+
MLX5_CAP_GEN(esw->dev, vhca_resource_manager))
1343+
mlx5_esw_vport_vhca_id_clear(esw, vport_num);
1344+
13281345
/* We don't assume VFs will cleanup after themselves.
13291346
* Calling vport change handler while vport is disabled will cleanup
13301347
* the vport resources.
@@ -1815,6 +1832,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
18151832
mlx5e_mod_hdr_tbl_init(&esw->offloads.mod_hdr);
18161833
atomic64_set(&esw->offloads.num_flows, 0);
18171834
ida_init(&esw->offloads.vport_metadata_ida);
1835+
xa_init_flags(&esw->offloads.vhca_map, XA_FLAGS_ALLOC);
18181836
mutex_init(&esw->state_lock);
18191837
mutex_init(&esw->mode_lock);
18201838

@@ -1854,6 +1872,8 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw)
18541872
esw_offloads_cleanup_reps(esw);
18551873
mutex_destroy(&esw->mode_lock);
18561874
mutex_destroy(&esw->state_lock);
1875+
WARN_ON(!xa_empty(&esw->offloads.vhca_map));
1876+
xa_destroy(&esw->offloads.vhca_map);
18571877
ida_destroy(&esw->offloads.vport_metadata_ida);
18581878
mlx5e_mod_hdr_tbl_destroy(&esw->offloads.mod_hdr);
18591879
mutex_destroy(&esw->offloads.encap_tbl_lock);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <linux/if_ether.h>
3737
#include <linux/if_link.h>
3838
#include <linux/atomic.h>
39+
#include <linux/xarray.h>
3940
#include <net/devlink.h>
4041
#include <linux/mlx5/device.h>
4142
#include <linux/mlx5/eswitch.h>
@@ -212,6 +213,7 @@ struct mlx5_esw_offload {
212213
struct mod_hdr_tbl mod_hdr;
213214
DECLARE_HASHTABLE(termtbl_tbl, 8);
214215
struct mutex termtbl_mutex; /* protects termtbl hash */
216+
struct xarray vhca_map;
215217
const struct mlx5_eswitch_rep_ops *rep_ops[NUM_REP_TYPES];
216218
u8 inline_mode;
217219
atomic64_t num_flows;
@@ -734,6 +736,10 @@ int mlx5_esw_offloads_sf_vport_enable(struct mlx5_eswitch *esw, struct devlink_p
734736
u16 vport_num, u32 sfnum);
735737
void mlx5_esw_offloads_sf_vport_disable(struct mlx5_eswitch *esw, u16 vport_num);
736738

739+
int mlx5_esw_vport_vhca_id_set(struct mlx5_eswitch *esw, u16 vport_num);
740+
void mlx5_esw_vport_vhca_id_clear(struct mlx5_eswitch *esw, u16 vport_num);
741+
int mlx5_eswitch_vhca_id_to_vport(struct mlx5_eswitch *esw, u16 vhca_id, u16 *vport_num);
742+
737743
/**
738744
* mlx5_esw_event_info - Indicates eswitch mode changed/changing.
739745
*

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

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2872,3 +2872,82 @@ void mlx5_esw_offloads_sf_vport_disable(struct mlx5_eswitch *esw, u16 vport_num)
28722872
mlx5_esw_devlink_sf_port_unregister(esw, vport_num);
28732873
mlx5_esw_vport_disable(esw, vport_num);
28742874
}
2875+
2876+
static int mlx5_esw_query_vport_vhca_id(struct mlx5_eswitch *esw, u16 vport_num, u16 *vhca_id)
2877+
{
2878+
int query_out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out);
2879+
void *query_ctx;
2880+
void *hca_caps;
2881+
int err;
2882+
2883+
*vhca_id = 0;
2884+
if (mlx5_esw_is_manager_vport(esw, vport_num) ||
2885+
!MLX5_CAP_GEN(esw->dev, vhca_resource_manager))
2886+
return -EPERM;
2887+
2888+
query_ctx = kzalloc(query_out_sz, GFP_KERNEL);
2889+
if (!query_ctx)
2890+
return -ENOMEM;
2891+
2892+
err = mlx5_vport_get_other_func_cap(esw->dev, vport_num, query_ctx);
2893+
if (err)
2894+
goto out_free;
2895+
2896+
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
2897+
*vhca_id = MLX5_GET(cmd_hca_cap, hca_caps, vhca_id);
2898+
2899+
out_free:
2900+
kfree(query_ctx);
2901+
return err;
2902+
}
2903+
2904+
int mlx5_esw_vport_vhca_id_set(struct mlx5_eswitch *esw, u16 vport_num)
2905+
{
2906+
u16 *old_entry, *vhca_map_entry, vhca_id;
2907+
int err;
2908+
2909+
err = mlx5_esw_query_vport_vhca_id(esw, vport_num, &vhca_id);
2910+
if (err) {
2911+
esw_warn(esw->dev, "Getting vhca_id for vport failed (vport=%u,err=%d)\n",
2912+
vport_num, err);
2913+
return err;
2914+
}
2915+
2916+
vhca_map_entry = kmalloc(sizeof(*vhca_map_entry), GFP_KERNEL);
2917+
if (!vhca_map_entry)
2918+
return -ENOMEM;
2919+
2920+
*vhca_map_entry = vport_num;
2921+
old_entry = xa_store(&esw->offloads.vhca_map, vhca_id, vhca_map_entry, GFP_KERNEL);
2922+
if (xa_is_err(old_entry)) {
2923+
kfree(vhca_map_entry);
2924+
return xa_err(old_entry);
2925+
}
2926+
kfree(old_entry);
2927+
return 0;
2928+
}
2929+
2930+
void mlx5_esw_vport_vhca_id_clear(struct mlx5_eswitch *esw, u16 vport_num)
2931+
{
2932+
u16 *vhca_map_entry, vhca_id;
2933+
int err;
2934+
2935+
err = mlx5_esw_query_vport_vhca_id(esw, vport_num, &vhca_id);
2936+
if (err)
2937+
esw_warn(esw->dev, "Getting vhca_id for vport failed (vport=%hu,err=%d)\n",
2938+
vport_num, err);
2939+
2940+
vhca_map_entry = xa_erase(&esw->offloads.vhca_map, vhca_id);
2941+
kfree(vhca_map_entry);
2942+
}
2943+
2944+
int mlx5_eswitch_vhca_id_to_vport(struct mlx5_eswitch *esw, u16 vhca_id, u16 *vport_num)
2945+
{
2946+
u16 *res = xa_load(&esw->offloads.vhca_map, vhca_id);
2947+
2948+
if (!res)
2949+
return -ENOENT;
2950+
2951+
*vport_num = *res;
2952+
return 0;
2953+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,5 +270,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev);
270270
void mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup);
271271
int mlx5_load_one(struct mlx5_core_dev *dev, bool boot);
272272

273+
int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out);
274+
273275
void mlx5_events_work_enqueue(struct mlx5_core_dev *dev, struct work_struct *work);
274276
#endif /* __MLX5_CORE_H__ */

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,3 +1164,15 @@ u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev)
11641164
return MLX5_SPECIAL_VPORTS(dev) + mlx5_core_max_vfs(dev) + mlx5_sf_max_functions(dev);
11651165
}
11661166
EXPORT_SYMBOL_GPL(mlx5_eswitch_get_total_vports);
1167+
1168+
int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out)
1169+
{
1170+
u16 opmod = (MLX5_CAP_GENERAL << 1) | (HCA_CAP_OPMOD_GET_MAX & 0x01);
1171+
u8 in[MLX5_ST_SZ_BYTES(query_hca_cap_in)] = {};
1172+
1173+
MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
1174+
MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
1175+
MLX5_SET(query_hca_cap_in, in, function_id, function_id);
1176+
MLX5_SET(query_hca_cap_in, in, other_function, true);
1177+
return mlx5_cmd_exec_inout(dev, query_hca_cap, in, out);
1178+
}

0 commit comments

Comments
 (0)