mirror of https://gitee.com/openkylin/linux.git
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: f0d22d1874
('net/mlx5_core: Introduce flow steering autogrouped
flow table')
Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Reported-by: Amir Vadai <amir@vadai.me>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
45c78e0219
commit
c3f9bf628b
|
@ -1065,33 +1065,6 @@ static struct mlx5_flow_rule *add_rule_fg(struct mlx5_flow_group *fg,
|
||||||
return rule;
|
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 *
|
static struct mlx5_flow_rule *
|
||||||
_mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
_mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
||||||
u8 match_criteria_enable,
|
u8 match_criteria_enable,
|
||||||
|
@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria,
|
g = create_autogroup(ft, match_criteria_enable, match_criteria);
|
||||||
match_value, action, flow_tag, dest);
|
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:
|
||||||
unlock_ref_node(&ft->node);
|
unlock_ref_node(&ft->node);
|
||||||
return rule;
|
return rule;
|
||||||
|
|
Loading…
Reference in New Issue