提交 c3f9bf62 编写于 作者: M Maor Gottlieb 提交者: David S. Miller

net/mlx5_core: Fix soft lockup in steering error flow

In the error flow of adding flow rule to auto-grouped flow
table, we call to tree_remove_node.

tree_remove_node locks the node's parent, however the node's parent
is already locked by mlx5_add_flow_rule and this causes a deadlock.
After this patch, if we failed to add the flow rule, we unlock the
flow table before calling to tree_remove_node.

fixes: f0d22d18 ('net/mlx5_core: Introduce flow steering autogrouped
flow table')
Signed-off-by: NMaor Gottlieb <maorg@mellanox.com>
Reported-by: NAmir Vadai <amir@vadai.me>
Signed-off-by: NSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 45c78e02
......@@ -1065,33 +1065,6 @@ static struct mlx5_flow_rule *add_rule_fg(struct mlx5_flow_group *fg,
return rule;
}
static struct mlx5_flow_rule *add_rule_to_auto_fg(struct mlx5_flow_table *ft,
u8 match_criteria_enable,
u32 *match_criteria,
u32 *match_value,
u8 action,
u32 flow_tag,
struct mlx5_flow_destination *dest)
{
struct mlx5_flow_rule *rule;
struct mlx5_flow_group *g;
g = create_autogroup(ft, match_criteria_enable, match_criteria);
if (IS_ERR(g))
return (void *)g;
rule = add_rule_fg(g, match_value,
action, flow_tag, dest);
if (IS_ERR(rule)) {
/* Remove assumes refcount > 0 and autogroup creates a group
* with a refcount = 0.
*/
tree_get_node(&g->node);
tree_remove_node(&g->node);
}
return rule;
}
static struct mlx5_flow_rule *
_mlx5_add_flow_rule(struct mlx5_flow_table *ft,
u8 match_criteria_enable,
......@@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft,
goto unlock;
}
rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria,
match_value, action, flow_tag, dest);
g = create_autogroup(ft, match_criteria_enable, match_criteria);
if (IS_ERR(g)) {
rule = (void *)g;
goto unlock;
}
rule = add_rule_fg(g, match_value,
action, flow_tag, dest);
if (IS_ERR(rule)) {
/* Remove assumes refcount > 0 and autogroup creates a group
* with a refcount = 0.
*/
unlock_ref_node(&ft->node);
tree_get_node(&g->node);
tree_remove_node(&g->node);
return rule;
}
unlock:
unlock_ref_node(&ft->node);
return rule;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册