Commit d18296ff authored by Paul Blakey's avatar Paul Blakey Committed by David S. Miller

net/mlx5: E-Switch, Introduce global tables

Currently, flow tables are automatically connected according to their
<chain,prio,level> tuple.

Introduce global tables which are flow tables that are detached from the
eswitch chains processing, and will be connected by explicitly referencing
them from multiple chains.

Add this new table type, and allow connecting them by refenece.
Signed-off-by: default avatarPaul Blakey <paulb@mellanox.com>
Reviewed-by: default avatarOz Shlomo <ozsh@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent edd5861e
...@@ -421,6 +421,8 @@ struct mlx5_esw_flow_attr { ...@@ -421,6 +421,8 @@ struct mlx5_esw_flow_attr {
u16 prio; u16 prio;
u32 dest_chain; u32 dest_chain;
u32 flags; u32 flags;
struct mlx5_flow_table *fdb;
struct mlx5_flow_table *dest_ft;
struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5e_tc_flow_parse_attr *parse_attr;
}; };
......
...@@ -324,7 +324,12 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, ...@@ -324,7 +324,12 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
struct mlx5_flow_table *ft; struct mlx5_flow_table *ft;
if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) { if (attr->dest_ft) {
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest[i].ft = attr->dest_ft;
i++;
} else if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) {
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest[i].ft = mlx5_esw_chains_get_tc_end_ft(esw); dest[i].ft = mlx5_esw_chains_get_tc_end_ft(esw);
...@@ -378,8 +383,11 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, ...@@ -378,8 +383,11 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
if (split) { if (split) {
fdb = esw_vport_tbl_get(esw, attr); fdb = esw_vport_tbl_get(esw, attr);
} else { } else {
fdb = mlx5_esw_chains_get_table(esw, attr->chain, attr->prio, if (attr->chain || attr->prio)
0); fdb = mlx5_esw_chains_get_table(esw, attr->chain,
attr->prio, 0);
else
fdb = attr->fdb;
mlx5_eswitch_set_rule_source_port(esw, spec, attr); mlx5_eswitch_set_rule_source_port(esw, spec, attr);
} }
if (IS_ERR(fdb)) { if (IS_ERR(fdb)) {
...@@ -402,7 +410,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, ...@@ -402,7 +410,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
err_add_rule: err_add_rule:
if (split) if (split)
esw_vport_tbl_put(esw, attr); esw_vport_tbl_put(esw, attr);
else else if (attr->chain || attr->prio)
mlx5_esw_chains_put_table(esw, attr->chain, attr->prio, 0); mlx5_esw_chains_put_table(esw, attr->chain, attr->prio, 0);
err_esw_get: err_esw_get:
if (!(attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) && attr->dest_chain) if (!(attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) && attr->dest_chain)
...@@ -499,7 +507,7 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw, ...@@ -499,7 +507,7 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw,
} else { } else {
if (split) if (split)
esw_vport_tbl_put(esw, attr); esw_vport_tbl_put(esw, attr);
else else if (attr->chain || attr->prio)
mlx5_esw_chains_put_table(esw, attr->chain, attr->prio, mlx5_esw_chains_put_table(esw, attr->chain, attr->prio,
0); 0);
if (attr->dest_chain) if (attr->dest_chain)
......
...@@ -722,6 +722,36 @@ mlx5_esw_chains_get_tc_end_ft(struct mlx5_eswitch *esw) ...@@ -722,6 +722,36 @@ mlx5_esw_chains_get_tc_end_ft(struct mlx5_eswitch *esw)
return tc_end_fdb(esw); return tc_end_fdb(esw);
} }
struct mlx5_flow_table *
mlx5_esw_chains_create_global_table(struct mlx5_eswitch *esw)
{
int chain, prio, level, err;
if (!fdb_ignore_flow_level_supported(esw)) {
err = -EOPNOTSUPP;
esw_warn(esw->dev,
"Couldn't create global flow table, ignore_flow_level not supported.");
goto err_ignore;
}
chain = mlx5_esw_chains_get_chain_range(esw),
prio = mlx5_esw_chains_get_prio_range(esw);
level = mlx5_esw_chains_get_level_range(esw);
return mlx5_esw_chains_create_fdb_table(esw, chain, prio, level);
err_ignore:
return ERR_PTR(err);
}
void
mlx5_esw_chains_destroy_global_table(struct mlx5_eswitch *esw,
struct mlx5_flow_table *ft)
{
mlx5_esw_chains_destroy_fdb_table(esw, ft);
}
static int static int
mlx5_esw_chains_init(struct mlx5_eswitch *esw) mlx5_esw_chains_init(struct mlx5_eswitch *esw)
{ {
......
...@@ -25,6 +25,12 @@ mlx5_esw_chains_put_table(struct mlx5_eswitch *esw, u32 chain, u32 prio, ...@@ -25,6 +25,12 @@ mlx5_esw_chains_put_table(struct mlx5_eswitch *esw, u32 chain, u32 prio,
struct mlx5_flow_table * struct mlx5_flow_table *
mlx5_esw_chains_get_tc_end_ft(struct mlx5_eswitch *esw); mlx5_esw_chains_get_tc_end_ft(struct mlx5_eswitch *esw);
struct mlx5_flow_table *
mlx5_esw_chains_create_global_table(struct mlx5_eswitch *esw);
void
mlx5_esw_chains_destroy_global_table(struct mlx5_eswitch *esw,
struct mlx5_flow_table *ft);
int mlx5_esw_chains_create(struct mlx5_eswitch *esw); int mlx5_esw_chains_create(struct mlx5_eswitch *esw);
void mlx5_esw_chains_destroy(struct mlx5_eswitch *esw); void mlx5_esw_chains_destroy(struct mlx5_eswitch *esw);
......
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