Commit 5281a0c9 authored by Paul Blakey's avatar Paul Blakey Committed by Saeed Mahameed

net/mlx5: fs_core: Introduce unmanaged flow tables

Currently, Most of the steering tree is statically declared ahead of time,
with steering prios instances allocated for each fdb chain to assign max
number of levels for each of them. This allows fs_core to manage the
connections and  levels of the flow tables hierarcy to prevent loops, but
restricts us with the number of supported chains and priorities.

Introduce unmananged flow tables, allowing the user to manage the flow
table connections. A unamanged table is detached from the fs_core flow
table hierarcy, and is only connected back to the hierarchy by explicit
FTEs forward actions.

This will be used together with firmware that supports ignoring the flow
table levels to increase the number of supported chains and prios.
Signed-off-by: default avatarPaul Blakey <paulb@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Reviewed-by: default avatarOz Shlomo <ozsh@mellanox.com>
Reviewed-by: default avatarMark Bloch <markb@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 12e9e0d0
...@@ -1006,7 +1006,8 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa ...@@ -1006,7 +1006,8 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
u16 vport) u16 vport)
{ {
struct mlx5_flow_root_namespace *root = find_root(&ns->node); struct mlx5_flow_root_namespace *root = find_root(&ns->node);
struct mlx5_flow_table *next_ft = NULL; bool unmanaged = ft_attr->flags & MLX5_FLOW_TABLE_UNMANAGED;
struct mlx5_flow_table *next_ft;
struct fs_prio *fs_prio = NULL; struct fs_prio *fs_prio = NULL;
struct mlx5_flow_table *ft; struct mlx5_flow_table *ft;
int log_table_sz; int log_table_sz;
...@@ -1023,14 +1024,21 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa ...@@ -1023,14 +1024,21 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
err = -EINVAL; err = -EINVAL;
goto unlock_root; goto unlock_root;
} }
if (ft_attr->level >= fs_prio->num_levels) { if (!unmanaged) {
err = -ENOSPC; /* The level is related to the
goto unlock_root; * priority level range.
*/
if (ft_attr->level >= fs_prio->num_levels) {
err = -ENOSPC;
goto unlock_root;
}
ft_attr->level += fs_prio->start_level;
} }
/* The level is related to the /* The level is related to the
* priority level range. * priority level range.
*/ */
ft_attr->level += fs_prio->start_level;
ft = alloc_flow_table(ft_attr->level, ft = alloc_flow_table(ft_attr->level,
vport, vport,
ft_attr->max_fte ? roundup_pow_of_two(ft_attr->max_fte) : 0, ft_attr->max_fte ? roundup_pow_of_two(ft_attr->max_fte) : 0,
...@@ -1043,19 +1051,27 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa ...@@ -1043,19 +1051,27 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table); tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table);
log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0; log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0;
next_ft = find_next_chained_ft(fs_prio); next_ft = unmanaged ? ft_attr->next_ft :
find_next_chained_ft(fs_prio);
ft->def_miss_action = ns->def_miss_action; ft->def_miss_action = ns->def_miss_action;
err = root->cmds->create_flow_table(root, ft, log_table_sz, next_ft); err = root->cmds->create_flow_table(root, ft, log_table_sz, next_ft);
if (err) if (err)
goto free_ft; goto free_ft;
err = connect_flow_table(root->dev, ft, fs_prio); if (!unmanaged) {
if (err) err = connect_flow_table(root->dev, ft, fs_prio);
goto destroy_ft; if (err)
goto destroy_ft;
}
ft->node.active = true; ft->node.active = true;
down_write_ref_node(&fs_prio->node, false); down_write_ref_node(&fs_prio->node, false);
tree_add_node(&ft->node, &fs_prio->node); if (!unmanaged) {
list_add_flow_table(ft, fs_prio); tree_add_node(&ft->node, &fs_prio->node);
list_add_flow_table(ft, fs_prio);
} else {
ft->node.root = fs_prio->node.root;
}
fs_prio->num_ft++; fs_prio->num_ft++;
up_write_ref_node(&fs_prio->node, false); up_write_ref_node(&fs_prio->node, false);
mutex_unlock(&root->chain_lock); mutex_unlock(&root->chain_lock);
...@@ -2024,7 +2040,8 @@ int mlx5_destroy_flow_table(struct mlx5_flow_table *ft) ...@@ -2024,7 +2040,8 @@ int mlx5_destroy_flow_table(struct mlx5_flow_table *ft)
int err = 0; int err = 0;
mutex_lock(&root->chain_lock); mutex_lock(&root->chain_lock);
err = disconnect_flow_table(ft); if (!(ft->flags & MLX5_FLOW_TABLE_UNMANAGED))
err = disconnect_flow_table(ft);
if (err) { if (err) {
mutex_unlock(&root->chain_lock); mutex_unlock(&root->chain_lock);
return err; return err;
......
...@@ -48,6 +48,7 @@ enum { ...@@ -48,6 +48,7 @@ enum {
MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT = BIT(0), MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT = BIT(0),
MLX5_FLOW_TABLE_TUNNEL_EN_DECAP = BIT(1), MLX5_FLOW_TABLE_TUNNEL_EN_DECAP = BIT(1),
MLX5_FLOW_TABLE_TERMINATION = BIT(2), MLX5_FLOW_TABLE_TERMINATION = BIT(2),
MLX5_FLOW_TABLE_UNMANAGED = BIT(3),
}; };
#define LEFTOVERS_RULE_NUM 2 #define LEFTOVERS_RULE_NUM 2
...@@ -150,6 +151,7 @@ struct mlx5_flow_table_attr { ...@@ -150,6 +151,7 @@ struct mlx5_flow_table_attr {
int max_fte; int max_fte;
u32 level; u32 level;
u32 flags; u32 flags;
struct mlx5_flow_table *next_ft;
struct { struct {
int max_num_groups; int max_num_groups;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment