|
@@ -67,13 +67,21 @@
|
|
|
#define FS_REQUIRED_CAPS(...) {.arr_sz = INIT_CAPS_ARRAY_SIZE(__VA_ARGS__), \
|
|
|
.caps = (long[]) {__VA_ARGS__} }
|
|
|
|
|
|
+#define FS_CHAINING_CAPS FS_REQUIRED_CAPS(FS_CAP(flow_table_properties_nic_receive.flow_modify_en), \
|
|
|
+ FS_CAP(flow_table_properties_nic_receive.modify_root), \
|
|
|
+ FS_CAP(flow_table_properties_nic_receive.identified_miss_table_mode), \
|
|
|
+ FS_CAP(flow_table_properties_nic_receive.flow_table_modify))
|
|
|
+
|
|
|
#define LEFTOVERS_NUM_LEVELS 1
|
|
|
#define LEFTOVERS_NUM_PRIOS 1
|
|
|
|
|
|
#define BY_PASS_PRIO_NUM_LEVELS 1
|
|
|
-#define BY_PASS_MIN_LEVEL (KERNEL_MIN_LEVEL + MLX5_BY_PASS_NUM_PRIOS +\
|
|
|
+#define BY_PASS_MIN_LEVEL (ETHTOOL_MIN_LEVEL + MLX5_BY_PASS_NUM_PRIOS +\
|
|
|
LEFTOVERS_NUM_PRIOS)
|
|
|
|
|
|
+#define ETHTOOL_PRIO_NUM_LEVELS 1
|
|
|
+#define ETHTOOL_NUM_PRIOS 10
|
|
|
+#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS)
|
|
|
/* Vlan, mac, ttc, aRFS */
|
|
|
#define KERNEL_NIC_PRIO_NUM_LEVELS 4
|
|
|
#define KERNEL_NIC_NUM_PRIOS 1
|
|
@@ -103,27 +111,24 @@ static struct init_tree_node {
|
|
|
int num_levels;
|
|
|
} root_fs = {
|
|
|
.type = FS_TYPE_NAMESPACE,
|
|
|
- .ar_size = 5,
|
|
|
+ .ar_size = 6,
|
|
|
.children = (struct init_tree_node[]) {
|
|
|
ADD_PRIO(0, BY_PASS_MIN_LEVEL, 0,
|
|
|
- FS_REQUIRED_CAPS(FS_CAP(flow_table_properties_nic_receive.flow_modify_en),
|
|
|
- FS_CAP(flow_table_properties_nic_receive.modify_root),
|
|
|
- FS_CAP(flow_table_properties_nic_receive.identified_miss_table_mode),
|
|
|
- FS_CAP(flow_table_properties_nic_receive.flow_table_modify)),
|
|
|
+ FS_CHAINING_CAPS,
|
|
|
ADD_NS(ADD_MULTIPLE_PRIO(MLX5_BY_PASS_NUM_PRIOS,
|
|
|
BY_PASS_PRIO_NUM_LEVELS))),
|
|
|
ADD_PRIO(0, OFFLOADS_MIN_LEVEL, 0, {},
|
|
|
ADD_NS(ADD_MULTIPLE_PRIO(OFFLOADS_NUM_PRIOS, OFFLOADS_MAX_FT))),
|
|
|
-
|
|
|
+ ADD_PRIO(0, ETHTOOL_MIN_LEVEL, 0,
|
|
|
+ FS_CHAINING_CAPS,
|
|
|
+ ADD_NS(ADD_MULTIPLE_PRIO(ETHTOOL_NUM_PRIOS,
|
|
|
+ ETHTOOL_PRIO_NUM_LEVELS))),
|
|
|
ADD_PRIO(0, KERNEL_MIN_LEVEL, 0, {},
|
|
|
ADD_NS(ADD_MULTIPLE_PRIO(1, 1),
|
|
|
ADD_MULTIPLE_PRIO(KERNEL_NIC_NUM_PRIOS,
|
|
|
KERNEL_NIC_PRIO_NUM_LEVELS))),
|
|
|
ADD_PRIO(0, BY_PASS_MIN_LEVEL, 0,
|
|
|
- FS_REQUIRED_CAPS(FS_CAP(flow_table_properties_nic_receive.flow_modify_en),
|
|
|
- FS_CAP(flow_table_properties_nic_receive.modify_root),
|
|
|
- FS_CAP(flow_table_properties_nic_receive.identified_miss_table_mode),
|
|
|
- FS_CAP(flow_table_properties_nic_receive.flow_table_modify)),
|
|
|
+ FS_CHAINING_CAPS,
|
|
|
ADD_NS(ADD_MULTIPLE_PRIO(LEFTOVERS_NUM_PRIOS, LEFTOVERS_NUM_LEVELS))),
|
|
|
ADD_PRIO(0, ANCHOR_MIN_LEVEL, 0, {},
|
|
|
ADD_NS(ADD_MULTIPLE_PRIO(ANCHOR_NUM_PRIOS, ANCHOR_NUM_LEVELS))),
|
|
@@ -1160,9 +1165,7 @@ static bool dest_is_valid(struct mlx5_flow_destination *dest,
|
|
|
|
|
|
static struct mlx5_flow_rule *
|
|
|
_mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
|
|
- u8 match_criteria_enable,
|
|
|
- u32 *match_criteria,
|
|
|
- u32 *match_value,
|
|
|
+ struct mlx5_flow_spec *spec,
|
|
|
u32 action,
|
|
|
u32 flow_tag,
|
|
|
struct mlx5_flow_destination *dest)
|
|
@@ -1176,22 +1179,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
|
|
nested_lock_ref_node(&ft->node, FS_MUTEX_GRANDPARENT);
|
|
|
fs_for_each_fg(g, ft)
|
|
|
if (compare_match_criteria(g->mask.match_criteria_enable,
|
|
|
- match_criteria_enable,
|
|
|
+ spec->match_criteria_enable,
|
|
|
g->mask.match_criteria,
|
|
|
- match_criteria)) {
|
|
|
- rule = add_rule_fg(g, match_value,
|
|
|
+ spec->match_criteria)) {
|
|
|
+ rule = add_rule_fg(g, spec->match_value,
|
|
|
action, flow_tag, dest);
|
|
|
if (!IS_ERR(rule) || PTR_ERR(rule) != -ENOSPC)
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- g = create_autogroup(ft, match_criteria_enable, match_criteria);
|
|
|
+ g = create_autogroup(ft, spec->match_criteria_enable,
|
|
|
+ spec->match_criteria);
|
|
|
if (IS_ERR(g)) {
|
|
|
rule = (void *)g;
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- rule = add_rule_fg(g, match_value,
|
|
|
+ rule = add_rule_fg(g, spec->match_value,
|
|
|
action, flow_tag, dest);
|
|
|
if (IS_ERR(rule)) {
|
|
|
/* Remove assumes refcount > 0 and autogroup creates a group
|
|
@@ -1215,9 +1219,7 @@ static bool fwd_next_prio_supported(struct mlx5_flow_table *ft)
|
|
|
|
|
|
struct mlx5_flow_rule *
|
|
|
mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
|
|
- u8 match_criteria_enable,
|
|
|
- u32 *match_criteria,
|
|
|
- u32 *match_value,
|
|
|
+ struct mlx5_flow_spec *spec,
|
|
|
u32 action,
|
|
|
u32 flow_tag,
|
|
|
struct mlx5_flow_destination *dest)
|
|
@@ -1248,8 +1250,7 @@ mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- rule = _mlx5_add_flow_rule(ft, match_criteria_enable, match_criteria,
|
|
|
- match_value, action, flow_tag, dest);
|
|
|
+ rule = _mlx5_add_flow_rule(ft, spec, action, flow_tag, dest);
|
|
|
|
|
|
if (sw_action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) {
|
|
|
if (!IS_ERR_OR_NULL(rule) &&
|
|
@@ -1367,41 +1368,47 @@ void mlx5_destroy_flow_group(struct mlx5_flow_group *fg)
|
|
|
struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
|
|
|
enum mlx5_flow_namespace_type type)
|
|
|
{
|
|
|
- struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns;
|
|
|
+ struct mlx5_flow_steering *steering = dev->priv.steering;
|
|
|
+ struct mlx5_flow_root_namespace *root_ns;
|
|
|
int prio;
|
|
|
struct fs_prio *fs_prio;
|
|
|
struct mlx5_flow_namespace *ns;
|
|
|
|
|
|
- if (!root_ns)
|
|
|
+ if (!steering)
|
|
|
return NULL;
|
|
|
|
|
|
switch (type) {
|
|
|
case MLX5_FLOW_NAMESPACE_BYPASS:
|
|
|
case MLX5_FLOW_NAMESPACE_OFFLOADS:
|
|
|
+ case MLX5_FLOW_NAMESPACE_ETHTOOL:
|
|
|
case MLX5_FLOW_NAMESPACE_KERNEL:
|
|
|
case MLX5_FLOW_NAMESPACE_LEFTOVERS:
|
|
|
case MLX5_FLOW_NAMESPACE_ANCHOR:
|
|
|
prio = type;
|
|
|
break;
|
|
|
case MLX5_FLOW_NAMESPACE_FDB:
|
|
|
- if (dev->priv.fdb_root_ns)
|
|
|
- return &dev->priv.fdb_root_ns->ns;
|
|
|
+ if (steering->fdb_root_ns)
|
|
|
+ return &steering->fdb_root_ns->ns;
|
|
|
else
|
|
|
return NULL;
|
|
|
case MLX5_FLOW_NAMESPACE_ESW_EGRESS:
|
|
|
- if (dev->priv.esw_egress_root_ns)
|
|
|
- return &dev->priv.esw_egress_root_ns->ns;
|
|
|
+ if (steering->esw_egress_root_ns)
|
|
|
+ return &steering->esw_egress_root_ns->ns;
|
|
|
else
|
|
|
return NULL;
|
|
|
case MLX5_FLOW_NAMESPACE_ESW_INGRESS:
|
|
|
- if (dev->priv.esw_ingress_root_ns)
|
|
|
- return &dev->priv.esw_ingress_root_ns->ns;
|
|
|
+ if (steering->esw_ingress_root_ns)
|
|
|
+ return &steering->esw_ingress_root_ns->ns;
|
|
|
else
|
|
|
return NULL;
|
|
|
default:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+ root_ns = steering->root_ns;
|
|
|
+ if (!root_ns)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
fs_prio = find_prio(&root_ns->ns, prio);
|
|
|
if (!fs_prio)
|
|
|
return NULL;
|
|
@@ -1487,13 +1494,13 @@ static bool has_required_caps(struct mlx5_core_dev *dev, struct node_caps *caps)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static int init_root_tree_recursive(struct mlx5_core_dev *dev,
|
|
|
+static int init_root_tree_recursive(struct mlx5_flow_steering *steering,
|
|
|
struct init_tree_node *init_node,
|
|
|
struct fs_node *fs_parent_node,
|
|
|
struct init_tree_node *init_parent_node,
|
|
|
int prio)
|
|
|
{
|
|
|
- int max_ft_level = MLX5_CAP_FLOWTABLE(dev,
|
|
|
+ int max_ft_level = MLX5_CAP_FLOWTABLE(steering->dev,
|
|
|
flow_table_properties_nic_receive.
|
|
|
max_ft_level);
|
|
|
struct mlx5_flow_namespace *fs_ns;
|
|
@@ -1504,7 +1511,7 @@ static int init_root_tree_recursive(struct mlx5_core_dev *dev,
|
|
|
|
|
|
if (init_node->type == FS_TYPE_PRIO) {
|
|
|
if ((init_node->min_ft_level > max_ft_level) ||
|
|
|
- !has_required_caps(dev, &init_node->caps))
|
|
|
+ !has_required_caps(steering->dev, &init_node->caps))
|
|
|
return 0;
|
|
|
|
|
|
fs_get_obj(fs_ns, fs_parent_node);
|
|
@@ -1525,7 +1532,7 @@ static int init_root_tree_recursive(struct mlx5_core_dev *dev,
|
|
|
}
|
|
|
prio = 0;
|
|
|
for (i = 0; i < init_node->ar_size; i++) {
|
|
|
- err = init_root_tree_recursive(dev, &init_node->children[i],
|
|
|
+ err = init_root_tree_recursive(steering, &init_node->children[i],
|
|
|
base, init_node, prio);
|
|
|
if (err)
|
|
|
return err;
|
|
@@ -1538,7 +1545,7 @@ static int init_root_tree_recursive(struct mlx5_core_dev *dev,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int init_root_tree(struct mlx5_core_dev *dev,
|
|
|
+static int init_root_tree(struct mlx5_flow_steering *steering,
|
|
|
struct init_tree_node *init_node,
|
|
|
struct fs_node *fs_parent_node)
|
|
|
{
|
|
@@ -1548,7 +1555,7 @@ static int init_root_tree(struct mlx5_core_dev *dev,
|
|
|
|
|
|
fs_get_obj(fs_ns, fs_parent_node);
|
|
|
for (i = 0; i < init_node->ar_size; i++) {
|
|
|
- err = init_root_tree_recursive(dev, &init_node->children[i],
|
|
|
+ err = init_root_tree_recursive(steering, &init_node->children[i],
|
|
|
&fs_ns->node,
|
|
|
init_node, i);
|
|
|
if (err)
|
|
@@ -1557,7 +1564,7 @@ static int init_root_tree(struct mlx5_core_dev *dev,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static struct mlx5_flow_root_namespace *create_root_ns(struct mlx5_core_dev *dev,
|
|
|
+static struct mlx5_flow_root_namespace *create_root_ns(struct mlx5_flow_steering *steering,
|
|
|
enum fs_flow_table_type
|
|
|
table_type)
|
|
|
{
|
|
@@ -1569,7 +1576,7 @@ static struct mlx5_flow_root_namespace *create_root_ns(struct mlx5_core_dev *dev
|
|
|
if (!root_ns)
|
|
|
return NULL;
|
|
|
|
|
|
- root_ns->dev = dev;
|
|
|
+ root_ns->dev = steering->dev;
|
|
|
root_ns->table_type = table_type;
|
|
|
|
|
|
ns = &root_ns->ns;
|
|
@@ -1624,212 +1631,126 @@ static void set_prio_attrs(struct mlx5_flow_root_namespace *root_ns)
|
|
|
#define ANCHOR_PRIO 0
|
|
|
#define ANCHOR_SIZE 1
|
|
|
#define ANCHOR_LEVEL 0
|
|
|
-static int create_anchor_flow_table(struct mlx5_core_dev
|
|
|
- *dev)
|
|
|
+static int create_anchor_flow_table(struct mlx5_flow_steering *steering)
|
|
|
{
|
|
|
struct mlx5_flow_namespace *ns = NULL;
|
|
|
struct mlx5_flow_table *ft;
|
|
|
|
|
|
- ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_ANCHOR);
|
|
|
+ ns = mlx5_get_flow_namespace(steering->dev, MLX5_FLOW_NAMESPACE_ANCHOR);
|
|
|
if (!ns)
|
|
|
return -EINVAL;
|
|
|
ft = mlx5_create_flow_table(ns, ANCHOR_PRIO, ANCHOR_SIZE, ANCHOR_LEVEL);
|
|
|
if (IS_ERR(ft)) {
|
|
|
- mlx5_core_err(dev, "Failed to create last anchor flow table");
|
|
|
+ mlx5_core_err(steering->dev, "Failed to create last anchor flow table");
|
|
|
return PTR_ERR(ft);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int init_root_ns(struct mlx5_core_dev *dev)
|
|
|
+static int init_root_ns(struct mlx5_flow_steering *steering)
|
|
|
{
|
|
|
|
|
|
- dev->priv.root_ns = create_root_ns(dev, FS_FT_NIC_RX);
|
|
|
- if (IS_ERR_OR_NULL(dev->priv.root_ns))
|
|
|
+ steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX);
|
|
|
+ if (IS_ERR_OR_NULL(steering->root_ns))
|
|
|
goto cleanup;
|
|
|
|
|
|
- if (init_root_tree(dev, &root_fs, &dev->priv.root_ns->ns.node))
|
|
|
+ if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node))
|
|
|
goto cleanup;
|
|
|
|
|
|
- set_prio_attrs(dev->priv.root_ns);
|
|
|
+ set_prio_attrs(steering->root_ns);
|
|
|
|
|
|
- if (create_anchor_flow_table(dev))
|
|
|
+ if (create_anchor_flow_table(steering))
|
|
|
goto cleanup;
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
cleanup:
|
|
|
- mlx5_cleanup_fs(dev);
|
|
|
+ mlx5_cleanup_fs(steering->dev);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
-static void cleanup_single_prio_root_ns(struct mlx5_core_dev *dev,
|
|
|
- struct mlx5_flow_root_namespace *root_ns)
|
|
|
+static void clean_tree(struct fs_node *node)
|
|
|
{
|
|
|
- struct fs_node *prio;
|
|
|
-
|
|
|
- if (!root_ns)
|
|
|
- return;
|
|
|
+ if (node) {
|
|
|
+ struct fs_node *iter;
|
|
|
+ struct fs_node *temp;
|
|
|
|
|
|
- if (!list_empty(&root_ns->ns.node.children)) {
|
|
|
- prio = list_first_entry(&root_ns->ns.node.children,
|
|
|
- struct fs_node,
|
|
|
- list);
|
|
|
- if (tree_remove_node(prio))
|
|
|
- mlx5_core_warn(dev,
|
|
|
- "Flow steering priority wasn't destroyed, refcount > 1\n");
|
|
|
+ list_for_each_entry_safe(iter, temp, &node->children, list)
|
|
|
+ clean_tree(iter);
|
|
|
+ tree_remove_node(node);
|
|
|
}
|
|
|
- if (tree_remove_node(&root_ns->ns.node))
|
|
|
- mlx5_core_warn(dev,
|
|
|
- "Flow steering namespace wasn't destroyed, refcount > 1\n");
|
|
|
- root_ns = NULL;
|
|
|
}
|
|
|
|
|
|
-static void destroy_flow_tables(struct fs_prio *prio)
|
|
|
+static void cleanup_root_ns(struct mlx5_flow_root_namespace *root_ns)
|
|
|
{
|
|
|
- struct mlx5_flow_table *iter;
|
|
|
- struct mlx5_flow_table *tmp;
|
|
|
-
|
|
|
- fs_for_each_ft_safe(iter, tmp, prio)
|
|
|
- mlx5_destroy_flow_table(iter);
|
|
|
-}
|
|
|
-
|
|
|
-static void cleanup_root_ns(struct mlx5_core_dev *dev)
|
|
|
-{
|
|
|
- struct mlx5_flow_root_namespace *root_ns = dev->priv.root_ns;
|
|
|
- struct fs_prio *iter_prio;
|
|
|
-
|
|
|
- if (!MLX5_CAP_GEN(dev, nic_flow_table))
|
|
|
- return;
|
|
|
-
|
|
|
if (!root_ns)
|
|
|
return;
|
|
|
|
|
|
- /* stage 1 */
|
|
|
- fs_for_each_prio(iter_prio, &root_ns->ns) {
|
|
|
- struct fs_node *node;
|
|
|
- struct mlx5_flow_namespace *iter_ns;
|
|
|
-
|
|
|
- fs_for_each_ns_or_ft(node, iter_prio) {
|
|
|
- if (node->type == FS_TYPE_FLOW_TABLE)
|
|
|
- continue;
|
|
|
- fs_get_obj(iter_ns, node);
|
|
|
- while (!list_empty(&iter_ns->node.children)) {
|
|
|
- struct fs_prio *obj_iter_prio2;
|
|
|
- struct fs_node *iter_prio2 =
|
|
|
- list_first_entry(&iter_ns->node.children,
|
|
|
- struct fs_node,
|
|
|
- list);
|
|
|
-
|
|
|
- fs_get_obj(obj_iter_prio2, iter_prio2);
|
|
|
- destroy_flow_tables(obj_iter_prio2);
|
|
|
- if (tree_remove_node(iter_prio2)) {
|
|
|
- mlx5_core_warn(dev,
|
|
|
- "Priority %d wasn't destroyed, refcount > 1\n",
|
|
|
- obj_iter_prio2->prio);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* stage 2 */
|
|
|
- fs_for_each_prio(iter_prio, &root_ns->ns) {
|
|
|
- while (!list_empty(&iter_prio->node.children)) {
|
|
|
- struct fs_node *iter_ns =
|
|
|
- list_first_entry(&iter_prio->node.children,
|
|
|
- struct fs_node,
|
|
|
- list);
|
|
|
- if (tree_remove_node(iter_ns)) {
|
|
|
- mlx5_core_warn(dev,
|
|
|
- "Namespace wasn't destroyed, refcount > 1\n");
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* stage 3 */
|
|
|
- while (!list_empty(&root_ns->ns.node.children)) {
|
|
|
- struct fs_prio *obj_prio_node;
|
|
|
- struct fs_node *prio_node =
|
|
|
- list_first_entry(&root_ns->ns.node.children,
|
|
|
- struct fs_node,
|
|
|
- list);
|
|
|
-
|
|
|
- fs_get_obj(obj_prio_node, prio_node);
|
|
|
- if (tree_remove_node(prio_node)) {
|
|
|
- mlx5_core_warn(dev,
|
|
|
- "Priority %d wasn't destroyed, refcount > 1\n",
|
|
|
- obj_prio_node->prio);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (tree_remove_node(&root_ns->ns.node)) {
|
|
|
- mlx5_core_warn(dev,
|
|
|
- "root namespace wasn't destroyed, refcount > 1\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- dev->priv.root_ns = NULL;
|
|
|
+ clean_tree(&root_ns->ns.node);
|
|
|
}
|
|
|
|
|
|
void mlx5_cleanup_fs(struct mlx5_core_dev *dev)
|
|
|
{
|
|
|
+ struct mlx5_flow_steering *steering = dev->priv.steering;
|
|
|
+
|
|
|
if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
|
|
|
return;
|
|
|
|
|
|
- cleanup_root_ns(dev);
|
|
|
- cleanup_single_prio_root_ns(dev, dev->priv.fdb_root_ns);
|
|
|
- cleanup_single_prio_root_ns(dev, dev->priv.esw_egress_root_ns);
|
|
|
- cleanup_single_prio_root_ns(dev, dev->priv.esw_ingress_root_ns);
|
|
|
+ cleanup_root_ns(steering->root_ns);
|
|
|
+ cleanup_root_ns(steering->esw_egress_root_ns);
|
|
|
+ cleanup_root_ns(steering->esw_ingress_root_ns);
|
|
|
+ cleanup_root_ns(steering->fdb_root_ns);
|
|
|
mlx5_cleanup_fc_stats(dev);
|
|
|
+ kfree(steering);
|
|
|
}
|
|
|
|
|
|
-static int init_fdb_root_ns(struct mlx5_core_dev *dev)
|
|
|
+static int init_fdb_root_ns(struct mlx5_flow_steering *steering)
|
|
|
{
|
|
|
struct fs_prio *prio;
|
|
|
|
|
|
- dev->priv.fdb_root_ns = create_root_ns(dev, FS_FT_FDB);
|
|
|
- if (!dev->priv.fdb_root_ns)
|
|
|
+ steering->fdb_root_ns = create_root_ns(steering, FS_FT_FDB);
|
|
|
+ if (!steering->fdb_root_ns)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
/* Create single prio */
|
|
|
- prio = fs_create_prio(&dev->priv.fdb_root_ns->ns, 0, 1);
|
|
|
+ prio = fs_create_prio(&steering->fdb_root_ns->ns, 0, 1);
|
|
|
if (IS_ERR(prio)) {
|
|
|
- cleanup_single_prio_root_ns(dev, dev->priv.fdb_root_ns);
|
|
|
+ cleanup_root_ns(steering->fdb_root_ns);
|
|
|
+ steering->fdb_root_ns = NULL;
|
|
|
return PTR_ERR(prio);
|
|
|
} else {
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static int init_egress_acl_root_ns(struct mlx5_core_dev *dev)
|
|
|
+static int init_ingress_acl_root_ns(struct mlx5_flow_steering *steering)
|
|
|
{
|
|
|
struct fs_prio *prio;
|
|
|
|
|
|
- dev->priv.esw_egress_root_ns = create_root_ns(dev, FS_FT_ESW_EGRESS_ACL);
|
|
|
- if (!dev->priv.esw_egress_root_ns)
|
|
|
+ steering->esw_egress_root_ns = create_root_ns(steering, FS_FT_ESW_EGRESS_ACL);
|
|
|
+ if (!steering->esw_egress_root_ns)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
/* create 1 prio*/
|
|
|
- prio = fs_create_prio(&dev->priv.esw_egress_root_ns->ns, 0, MLX5_TOTAL_VPORTS(dev));
|
|
|
+ prio = fs_create_prio(&steering->esw_egress_root_ns->ns, 0,
|
|
|
+ MLX5_TOTAL_VPORTS(steering->dev));
|
|
|
if (IS_ERR(prio))
|
|
|
return PTR_ERR(prio);
|
|
|
else
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int init_ingress_acl_root_ns(struct mlx5_core_dev *dev)
|
|
|
+static int init_egress_acl_root_ns(struct mlx5_flow_steering *steering)
|
|
|
{
|
|
|
struct fs_prio *prio;
|
|
|
|
|
|
- dev->priv.esw_ingress_root_ns = create_root_ns(dev, FS_FT_ESW_INGRESS_ACL);
|
|
|
- if (!dev->priv.esw_ingress_root_ns)
|
|
|
+ steering->esw_ingress_root_ns = create_root_ns(steering, FS_FT_ESW_INGRESS_ACL);
|
|
|
+ if (!steering->esw_ingress_root_ns)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
/* create 1 prio*/
|
|
|
- prio = fs_create_prio(&dev->priv.esw_ingress_root_ns->ns, 0, MLX5_TOTAL_VPORTS(dev));
|
|
|
+ prio = fs_create_prio(&steering->esw_ingress_root_ns->ns, 0,
|
|
|
+ MLX5_TOTAL_VPORTS(steering->dev));
|
|
|
if (IS_ERR(prio))
|
|
|
return PTR_ERR(prio);
|
|
|
else
|
|
@@ -1838,6 +1759,7 @@ static int init_ingress_acl_root_ns(struct mlx5_core_dev *dev)
|
|
|
|
|
|
int mlx5_init_fs(struct mlx5_core_dev *dev)
|
|
|
{
|
|
|
+ struct mlx5_flow_steering *steering;
|
|
|
int err = 0;
|
|
|
|
|
|
if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
|
|
@@ -1847,26 +1769,32 @@ int mlx5_init_fs(struct mlx5_core_dev *dev)
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
+ steering = kzalloc(sizeof(*steering), GFP_KERNEL);
|
|
|
+ if (!steering)
|
|
|
+ return -ENOMEM;
|
|
|
+ steering->dev = dev;
|
|
|
+ dev->priv.steering = steering;
|
|
|
+
|
|
|
if (MLX5_CAP_GEN(dev, nic_flow_table) &&
|
|
|
MLX5_CAP_FLOWTABLE_NIC_RX(dev, ft_support)) {
|
|
|
- err = init_root_ns(dev);
|
|
|
+ err = init_root_ns(steering);
|
|
|
if (err)
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
if (MLX5_CAP_GEN(dev, eswitch_flow_table)) {
|
|
|
if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, ft_support)) {
|
|
|
- err = init_fdb_root_ns(dev);
|
|
|
+ err = init_fdb_root_ns(steering);
|
|
|
if (err)
|
|
|
goto err;
|
|
|
}
|
|
|
if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) {
|
|
|
- err = init_egress_acl_root_ns(dev);
|
|
|
+ err = init_egress_acl_root_ns(steering);
|
|
|
if (err)
|
|
|
goto err;
|
|
|
}
|
|
|
if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) {
|
|
|
- err = init_ingress_acl_root_ns(dev);
|
|
|
+ err = init_ingress_acl_root_ns(steering);
|
|
|
if (err)
|
|
|
goto err;
|
|
|
}
|