Commit 5e86397a authored by Or Gerlitz's avatar Or Gerlitz Committed by David S. Miller

net/mlx5e: Properly handle FW errors while adding TC rules

When the firmware returns an error (common example is an attempt to
add twice the same rule which is refused by the some FWs), we are not
properly derefing/cleaning few resources allocated on the way.
Examples are vport vlan deref under eswitch vlan offloads, and encap
entry/neighbour deref under eswitch encapsulation offloads, fix that.

Fixes: a54e20b4 ('net/mlx5e: Add basic TC tunnel set action for SRIOV offloads')
Fixes: 8b32580d ('net/mlx5e: Add TC vlan action for SRIOV offloads')
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a757d108
...@@ -161,15 +161,21 @@ static void mlx5e_detach_encap(struct mlx5e_priv *priv, ...@@ -161,15 +161,21 @@ static void mlx5e_detach_encap(struct mlx5e_priv *priv,
} }
} }
/* we get here also when setting rule to the FW failed, etc. It means that the
* flow rule itself might not exist, but some offloading related to the actions
* should be cleaned.
*/
static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow) struct mlx5e_tc_flow *flow)
{ {
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5_fc *counter = NULL; struct mlx5_fc *counter = NULL;
if (!IS_ERR(flow->rule)) {
counter = mlx5_flow_rule_counter(flow->rule); counter = mlx5_flow_rule_counter(flow->rule);
mlx5_del_flow_rules(flow->rule); mlx5_del_flow_rules(flow->rule);
mlx5_fc_destroy(priv->mdev, counter);
}
if (esw && esw->mode == SRIOV_OFFLOADS) { if (esw && esw->mode == SRIOV_OFFLOADS) {
mlx5_eswitch_del_vlan_action(esw, flow->attr); mlx5_eswitch_del_vlan_action(esw, flow->attr);
...@@ -177,8 +183,6 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, ...@@ -177,8 +183,6 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
mlx5e_detach_encap(priv, flow); mlx5e_detach_encap(priv, flow);
} }
mlx5_fc_destroy(priv->mdev, counter);
if (!mlx5e_tc_num_filters(priv) && (priv->fs.tc.t)) { if (!mlx5e_tc_num_filters(priv) && (priv->fs.tc.t)) {
mlx5_destroy_flow_table(priv->fs.tc.t); mlx5_destroy_flow_table(priv->fs.tc.t);
priv->fs.tc.t = NULL; priv->fs.tc.t = NULL;
...@@ -1017,7 +1021,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol, ...@@ -1017,7 +1021,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
if (IS_ERR(flow->rule)) { if (IS_ERR(flow->rule)) {
err = PTR_ERR(flow->rule); err = PTR_ERR(flow->rule);
goto err_free; goto err_del_rule;
} }
err = rhashtable_insert_fast(&tc->ht, &flow->node, err = rhashtable_insert_fast(&tc->ht, &flow->node,
...@@ -1028,7 +1032,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol, ...@@ -1028,7 +1032,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
goto out; goto out;
err_del_rule: err_del_rule:
mlx5_del_flow_rules(flow->rule); mlx5e_tc_del_flow(priv, flow);
err_free: err_free:
kfree(flow); kfree(flow);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment