mlx5e_tc_rule_offload() adds the flow meter to the attribute and then adds the offloaded rule. If mlx5_eswitch_add_offloaded_rule() fails, the meter reference taken by mlx5e_tc_add_flow_meter() is not dropped. The error propagates to mlx5e_tc_add_fdb_flow() and the flow is freed without the OFFLOADED flag, so mlx5e_tc_rule_unoffload() and mlx5e_tc_del_flow_meter() are never called. Release the meter and the post meter state in the failure path of mlx5e_tc_rule_offload() itself. Fixes: a8d52b024d6d ("net/mlx5e: TC, Support offloading police action") Cc: stable@vger.kernel.org Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex Signed-off-by: Wentao Liang --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 708b7987ea4c..17bd92529a44 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -491,6 +491,8 @@ mlx5e_tc_rule_offload(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; + struct mlx5_flow_handle *rule; + bool meter_added = false; int err; if (!is_mdev_switchdev_mode(priv->mdev)) @@ -503,9 +505,14 @@ mlx5e_tc_rule_offload(struct mlx5e_priv *priv, err = mlx5e_tc_add_flow_meter(priv, attr); if (err) return ERR_PTR(err); + meter_added = true; } - return mlx5_eswitch_add_offloaded_rule(esw, spec, attr); + rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr); + if (IS_ERR(rule) && meter_added) + mlx5e_tc_del_flow_meter(esw, attr); + + return rule; } void -- 2.34.1