summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaor Gottlieb2017-08-29 18:17:12 +0200
committerSaeed Mahameed2017-09-26 19:52:04 +0200
commitf5c2ff179f51101893e42e78683b23a487929d6c (patch)
tree1979ee3a0bde2993e62d4f25dcd252ae56a0f038
parentnet/mlx5: Support multiple updates of steering rules in parallel (diff)
downloadkernel-qcow2-linux-f5c2ff179f51101893e42e78683b23a487929d6c.tar.gz
kernel-qcow2-linux-f5c2ff179f51101893e42e78683b23a487929d6c.tar.xz
kernel-qcow2-linux-f5c2ff179f51101893e42e78683b23a487929d6c.zip
net/mlx5: Allocate FTE object without lock
Allocation of new FTE is a massive operation, part of it could be done without taking the flow group write lock. Split the FTE allocation to two functions of actions which need to be under lock and action which don't have. Signed-off-by: Maor Gottlieb <maorg@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c92
1 files changed, 46 insertions, 46 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index e7301cf747c5..bc4bbb72fa86 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -546,9 +546,33 @@ static void del_sw_flow_group(struct fs_node *node)
WARN_ON(err);
}
-static struct fs_fte *alloc_fte(struct mlx5_flow_act *flow_act,
- u32 *match_value,
- unsigned int index)
+static int insert_fte(struct mlx5_flow_group *fg, struct fs_fte *fte)
+{
+ int index;
+ int ret;
+
+ index = ida_simple_get(&fg->fte_allocator, 0, fg->max_ftes, GFP_KERNEL);
+ if (index < 0)
+ return index;
+
+ fte->index = index + fg->start_index;
+ ret = rhashtable_insert_fast(&fg->ftes_hash,
+ &fte->hash,
+ rhash_fte);
+ if (ret)
+ goto err_ida_remove;
+
+ tree_add_node(&fte->node, &fg->node);
+ list_add_tail(&fte->node.list, &fg->node.children);
+ return 0;
+
+err_ida_remove:
+ ida_simple_remove(&fg->fte_allocator, index);
+ return ret;
+}
+
+static struct fs_fte *alloc_fte(u32 *match_value,
+ struct mlx5_flow_act *flow_act)
{
struct fs_fte *fte;
@@ -559,51 +583,13 @@ static struct fs_fte *alloc_fte(struct mlx5_flow_act *flow_act,
memcpy(fte->val, match_value, sizeof(fte->val));
fte->node.type = FS_TYPE_FLOW_ENTRY;
fte->flow_tag = flow_act->flow_tag;
- fte->index = index;
fte->action = flow_act->action;
fte->encap_id = flow_act->encap_id;
fte->modify_id = flow_act->modify_id;
- return fte;
-}
-
-static struct fs_fte *alloc_insert_fte(struct mlx5_flow_group *fg,
- u32 *match_value,
- struct mlx5_flow_act *flow_act)
-{
- struct fs_fte *fte;
- int index;
- int ret;
-
- index = ida_simple_get(&fg->fte_allocator, 0,
- fg->max_ftes,
- GFP_KERNEL);
- if (index < 0)
- return ERR_PTR(index);
-
- fte = alloc_fte(flow_act, match_value, index + fg->start_index);
- if (IS_ERR(fte)) {
- ret = PTR_ERR(fte);
- goto err_ida_remove;
- }
-
- ret = rhashtable_insert_fast(&fg->ftes_hash,
- &fte->hash,
- rhash_fte);
- if (ret)
- goto err_free;
-
tree_init_node(&fte->node, del_hw_fte, del_sw_fte);
- tree_add_node(&fte->node, &fg->node);
- list_add_tail(&fte->node.list, &fg->node.children);
return fte;
-
-err_free:
- kfree(fte);
-err_ida_remove:
- ida_simple_remove(&fg->fte_allocator, index);
- return ERR_PTR(ret);
}
static void dealloc_flow_group(struct mlx5_flow_group *fg)
@@ -1589,6 +1575,11 @@ try_add_to_existing_fg(struct mlx5_flow_table *ft,
bool take_write = false;
struct fs_fte *fte;
u64 version;
+ int err;
+
+ fte = alloc_fte(spec->match_value, flow_act);
+ if (IS_ERR(fte))
+ return ERR_PTR(-ENOMEM);
list_for_each_entry(iter, match_head, list) {
nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT);
@@ -1620,6 +1611,7 @@ search_again_locked:
flow_act, dest, dest_num, fte_tmp);
up_write_ref_node(&fte_tmp->node);
tree_put_node(&fte_tmp->node);
+ kfree(fte);
return rule;
}
@@ -1655,13 +1647,14 @@ search_again_locked:
if (!g->node.active)
continue;
- fte = alloc_insert_fte(g, spec->match_value, flow_act);
- if (IS_ERR(fte)) {
- if (PTR_ERR(fte) == -ENOSPC)
+ err = insert_fte(g, fte);
+ if (err) {
+ if (err == -ENOSPC)
continue;
list_for_each_entry(iter, match_head, list)
up_write_ref_node(&iter->g->node);
- return (void *)fte;
+ kfree(fte);
+ return ERR_PTR(err);
}
nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
@@ -1677,6 +1670,7 @@ search_again_locked:
out:
list_for_each_entry(iter, match_head, list)
up_write_ref_node(&iter->g->node);
+ kfree(fte);
return rule;
}
@@ -1746,12 +1740,18 @@ search_again_locked:
if (err)
goto err_release_fg;
- fte = alloc_insert_fte(g, spec->match_value, flow_act);
+ fte = alloc_fte(spec->match_value, flow_act);
if (IS_ERR(fte)) {
err = PTR_ERR(fte);
goto err_release_fg;
}
+ err = insert_fte(g, fte);
+ if (err) {
+ kfree(fte);
+ goto err_release_fg;
+ }
+
nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
up_write_ref_node(&g->node);
rule = add_rule_fg(g, spec->match_value, flow_act, dest,