Skip to content

Commit 328edb4

Browse files
Paul BlakeySaeed Mahameed
authored andcommitted
net/mlx5: Split FDB fast path prio to multiple namespaces
Towards supporting multi-chains and priorities, split the FDB fast path to multiple namespaces (sub namespaces), each with multiple priorities. This patch adds a new flow steering type, FS_TYPE_PRIO_CHAINS, which is like current FS_TYPE_PRIO, but may contain only namespaces, and those will be in parallel to one another in terms of managing of the flow tables connections inside them. Meaning, while searching for the next or previous flow table to connect for a new table inside such namespace we skip the parallel namespaces in the same level under the FS_TYPE_PRIO_CHAINS prio we originated from. We use this new type for splitting the fast path prio into multiple parallel namespaces, each containing normal prios. The prios inside them (and their tables) will be connected to one another, but not from one parallel namespace to another, instead the last prio in each namespace will be connected to the next prio in the containing FDB namespace, which is the slow path prio. Signed-off-by: Paul Blakey <[email protected]> Acked-by: Or Gerlitz <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent b9aa0ba commit 328edb4

File tree

5 files changed

+101
-11
lines changed

5 files changed

+101
-11
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw)
263263
esw_debug(dev, "Create FDB log_max_size(%d)\n",
264264
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
265265

266-
root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB);
266+
root_ns = mlx5_get_fdb_sub_ns(dev, 0);
267267
if (!root_ns) {
268268
esw_warn(dev, "Failed to get FDB flow namespace\n");
269269
return -EOPNOTSUPP;

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
#define mlx5_esw_has_fwd_fdb(dev) \
6060
MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_to_table)
6161

62+
#define FDB_MAX_CHAIN 3
63+
#define FDB_MAX_PRIO 16
64+
6265
struct vport_ingress {
6366
struct mlx5_flow_table *acl;
6467
struct mlx5_flow_group *allow_untagged_spoofchk_grp;
@@ -319,6 +322,10 @@ static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {}
319322
static inline void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe) {}
320323
static inline int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return 0; }
321324
static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {}
325+
326+
#define FDB_MAX_CHAIN 1
327+
#define FDB_MAX_PRIO 1
328+
322329
#endif /* CONFIG_MLX5_ESWITCH */
323330

324331
#endif /* __MLX5_ESWITCH_H__ */

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

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "diag/fs_tracepoint.h"
4141
#include "accel/ipsec.h"
4242
#include "fpga/ipsec.h"
43+
#include "eswitch.h"
4344

4445
#define INIT_TREE_NODE_ARRAY_SIZE(...) (sizeof((struct init_tree_node[]){__VA_ARGS__}) /\
4546
sizeof(struct init_tree_node))
@@ -713,7 +714,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
713714
struct fs_node *iter = list_entry(start, struct fs_node, list);
714715
struct mlx5_flow_table *ft = NULL;
715716

716-
if (!root)
717+
if (!root || root->type == FS_TYPE_PRIO_CHAINS)
717718
return NULL;
718719

719720
list_for_each_advance_continue(iter, &root->children, reverse) {
@@ -1973,6 +1974,18 @@ void mlx5_destroy_flow_group(struct mlx5_flow_group *fg)
19731974
fg->id);
19741975
}
19751976

1977+
struct mlx5_flow_namespace *mlx5_get_fdb_sub_ns(struct mlx5_core_dev *dev,
1978+
int n)
1979+
{
1980+
struct mlx5_flow_steering *steering = dev->priv.steering;
1981+
1982+
if (!steering || !steering->fdb_sub_ns)
1983+
return NULL;
1984+
1985+
return steering->fdb_sub_ns[n];
1986+
}
1987+
EXPORT_SYMBOL(mlx5_get_fdb_sub_ns);
1988+
19761989
struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
19771990
enum mlx5_flow_namespace_type type)
19781991
{
@@ -2051,16 +2064,18 @@ struct mlx5_flow_namespace *mlx5_get_flow_vport_acl_namespace(struct mlx5_core_d
20512064
}
20522065
}
20532066

2054-
static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns,
2055-
unsigned int prio, int num_levels)
2067+
static struct fs_prio *_fs_create_prio(struct mlx5_flow_namespace *ns,
2068+
unsigned int prio,
2069+
int num_levels,
2070+
enum fs_node_type type)
20562071
{
20572072
struct fs_prio *fs_prio;
20582073

20592074
fs_prio = kzalloc(sizeof(*fs_prio), GFP_KERNEL);
20602075
if (!fs_prio)
20612076
return ERR_PTR(-ENOMEM);
20622077

2063-
fs_prio->node.type = FS_TYPE_PRIO;
2078+
fs_prio->node.type = type;
20642079
tree_init_node(&fs_prio->node, NULL, del_sw_prio);
20652080
tree_add_node(&fs_prio->node, &ns->node);
20662081
fs_prio->num_levels = num_levels;
@@ -2070,6 +2085,19 @@ static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns,
20702085
return fs_prio;
20712086
}
20722087

2088+
static struct fs_prio *fs_create_prio_chained(struct mlx5_flow_namespace *ns,
2089+
unsigned int prio,
2090+
int num_levels)
2091+
{
2092+
return _fs_create_prio(ns, prio, num_levels, FS_TYPE_PRIO_CHAINS);
2093+
}
2094+
2095+
static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns,
2096+
unsigned int prio, int num_levels)
2097+
{
2098+
return _fs_create_prio(ns, prio, num_levels, FS_TYPE_PRIO);
2099+
}
2100+
20732101
static struct mlx5_flow_namespace *fs_init_namespace(struct mlx5_flow_namespace
20742102
*ns)
20752103
{
@@ -2374,6 +2402,9 @@ void mlx5_cleanup_fs(struct mlx5_core_dev *dev)
23742402
cleanup_egress_acls_root_ns(dev);
23752403
cleanup_ingress_acls_root_ns(dev);
23762404
cleanup_root_ns(steering->fdb_root_ns);
2405+
steering->fdb_root_ns = NULL;
2406+
kfree(steering->fdb_sub_ns);
2407+
steering->fdb_sub_ns = NULL;
23772408
cleanup_root_ns(steering->sniffer_rx_root_ns);
23782409
cleanup_root_ns(steering->sniffer_tx_root_ns);
23792410
cleanup_root_ns(steering->egress_root_ns);
@@ -2419,27 +2450,64 @@ static int init_sniffer_rx_root_ns(struct mlx5_flow_steering *steering)
24192450

24202451
static int init_fdb_root_ns(struct mlx5_flow_steering *steering)
24212452
{
2422-
struct fs_prio *prio;
2453+
struct mlx5_flow_namespace *ns;
2454+
struct fs_prio *maj_prio;
2455+
struct fs_prio *min_prio;
2456+
int levels;
2457+
int chain;
2458+
int prio;
2459+
int err;
24232460

24242461
steering->fdb_root_ns = create_root_ns(steering, FS_FT_FDB);
24252462
if (!steering->fdb_root_ns)
24262463
return -ENOMEM;
24272464

2428-
prio = fs_create_prio(&steering->fdb_root_ns->ns, 0, 2);
2429-
if (IS_ERR(prio))
2465+
steering->fdb_sub_ns = kzalloc(sizeof(steering->fdb_sub_ns) *
2466+
FDB_MAX_CHAIN + 1, GFP_KERNEL);
2467+
if (!steering->fdb_sub_ns)
2468+
return -ENOMEM;
2469+
2470+
levels = 2 * FDB_MAX_PRIO * (FDB_MAX_CHAIN + 1);
2471+
maj_prio = fs_create_prio_chained(&steering->fdb_root_ns->ns, 0,
2472+
levels);
2473+
if (IS_ERR(maj_prio)) {
2474+
err = PTR_ERR(maj_prio);
24302475
goto out_err;
2476+
}
24312477

2432-
prio = fs_create_prio(&steering->fdb_root_ns->ns, 1, 1);
2433-
if (IS_ERR(prio))
2478+
for (chain = 0; chain <= FDB_MAX_CHAIN; chain++) {
2479+
ns = fs_create_namespace(maj_prio);
2480+
if (IS_ERR(ns)) {
2481+
err = PTR_ERR(ns);
2482+
goto out_err;
2483+
}
2484+
2485+
for (prio = 0; prio < FDB_MAX_PRIO * (chain + 1); prio++) {
2486+
min_prio = fs_create_prio(ns, prio, 2);
2487+
if (IS_ERR(min_prio)) {
2488+
err = PTR_ERR(min_prio);
2489+
goto out_err;
2490+
}
2491+
}
2492+
2493+
steering->fdb_sub_ns[chain] = ns;
2494+
}
2495+
2496+
maj_prio = fs_create_prio(&steering->fdb_root_ns->ns, 1, 1);
2497+
if (IS_ERR(maj_prio)) {
2498+
err = PTR_ERR(maj_prio);
24342499
goto out_err;
2500+
}
24352501

24362502
set_prio_attrs(steering->fdb_root_ns);
24372503
return 0;
24382504

24392505
out_err:
24402506
cleanup_root_ns(steering->fdb_root_ns);
2507+
kfree(steering->fdb_sub_ns);
2508+
steering->fdb_sub_ns = NULL;
24412509
steering->fdb_root_ns = NULL;
2442-
return PTR_ERR(prio);
2510+
return err;
24432511
}
24442512

24452513
static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering, int vport)

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,21 @@
3838
#include <linux/rhashtable.h>
3939
#include <linux/llist.h>
4040

41+
/* FS_TYPE_PRIO_CHAINS is a PRIO that will have namespaces only,
42+
* and those are in parallel to one another when going over them to connect
43+
* a new flow table. Meaning the last flow table in a TYPE_PRIO prio in one
44+
* parallel namespace will not automatically connect to the first flow table
45+
* found in any prio in any next namespace, but skip the entire containing
46+
* TYPE_PRIO_CHAINS prio.
47+
*
48+
* This is used to implement tc chains, each chain of prios is a different
49+
* namespace inside a containing TYPE_PRIO_CHAINS prio.
50+
*/
51+
4152
enum fs_node_type {
4253
FS_TYPE_NAMESPACE,
4354
FS_TYPE_PRIO,
55+
FS_TYPE_PRIO_CHAINS,
4456
FS_TYPE_FLOW_TABLE,
4557
FS_TYPE_FLOW_GROUP,
4658
FS_TYPE_FLOW_ENTRY,
@@ -73,6 +85,7 @@ struct mlx5_flow_steering {
7385
struct kmem_cache *ftes_cache;
7486
struct mlx5_flow_root_namespace *root_ns;
7587
struct mlx5_flow_root_namespace *fdb_root_ns;
88+
struct mlx5_flow_namespace **fdb_sub_ns;
7689
struct mlx5_flow_root_namespace **esw_egress_root_ns;
7790
struct mlx5_flow_root_namespace **esw_ingress_root_ns;
7891
struct mlx5_flow_root_namespace *sniffer_tx_root_ns;

include/linux/mlx5/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ struct mlx5_flow_destination {
101101
};
102102
};
103103

104+
struct mlx5_flow_namespace *
105+
mlx5_get_fdb_sub_ns(struct mlx5_core_dev *dev, int n);
104106
struct mlx5_flow_namespace *
105107
mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
106108
enum mlx5_flow_namespace_type type);

0 commit comments

Comments
 (0)