net/mlx5: fs, fail conflicting actions
When combining two steering rules into one check
not only do they share the same actions but those
actions are also the same. This resolves an issue where
when creating two different rules with the same match
the actions are overwritten and one of the rules is deleted
a FW syndrome can be seen in dmesg.
mlx5_core 0000:03:00.0: mlx5_cmd_check:819:(pid 2105): DEALLOC_MODIFY_HEADER_CONTEXT(0x941) op_mod(0x0) failed, status bad resource state(0x9), syndrome (0x1ab444)
Fixes: 0d235c3fab
("net/mlx5: Add hash table to search FTEs in a flow-group")
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
This commit is contained in:
Родитель
8bf94e6414
Коммит
8fa5e7b20e
|
@ -1574,9 +1574,22 @@ static struct mlx5_flow_rule *find_flow_rule(struct fs_fte *fte,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_conflicting_actions(u32 action1, u32 action2)
|
static bool check_conflicting_actions_vlan(const struct mlx5_fs_vlan *vlan0,
|
||||||
|
const struct mlx5_fs_vlan *vlan1)
|
||||||
{
|
{
|
||||||
u32 xored_actions = action1 ^ action2;
|
return vlan0->ethtype != vlan1->ethtype ||
|
||||||
|
vlan0->vid != vlan1->vid ||
|
||||||
|
vlan0->prio != vlan1->prio;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_conflicting_actions(const struct mlx5_flow_act *act1,
|
||||||
|
const struct mlx5_flow_act *act2)
|
||||||
|
{
|
||||||
|
u32 action1 = act1->action;
|
||||||
|
u32 action2 = act2->action;
|
||||||
|
u32 xored_actions;
|
||||||
|
|
||||||
|
xored_actions = action1 ^ action2;
|
||||||
|
|
||||||
/* if one rule only wants to count, it's ok */
|
/* if one rule only wants to count, it's ok */
|
||||||
if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT ||
|
if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT ||
|
||||||
|
@ -1593,6 +1606,22 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
|
||||||
MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2))
|
MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (action1 & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT &&
|
||||||
|
act1->pkt_reformat != act2->pkt_reformat)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (action1 & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
|
||||||
|
act1->modify_hdr != act2->modify_hdr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
|
||||||
|
check_conflicting_actions_vlan(&act1->vlan[0], &act2->vlan[0]))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2 &&
|
||||||
|
check_conflicting_actions_vlan(&act1->vlan[1], &act2->vlan[1]))
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1600,7 +1629,7 @@ static int check_conflicting_ftes(struct fs_fte *fte,
|
||||||
const struct mlx5_flow_context *flow_context,
|
const struct mlx5_flow_context *flow_context,
|
||||||
const struct mlx5_flow_act *flow_act)
|
const struct mlx5_flow_act *flow_act)
|
||||||
{
|
{
|
||||||
if (check_conflicting_actions(flow_act->action, fte->action.action)) {
|
if (check_conflicting_actions(flow_act, &fte->action)) {
|
||||||
mlx5_core_warn(get_dev(&fte->node),
|
mlx5_core_warn(get_dev(&fte->node),
|
||||||
"Found two FTEs with conflicting actions\n");
|
"Found two FTEs with conflicting actions\n");
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче