[PATCH] net: octeontx2-pf: drop the TC mark reference when adding a flow fails

From: Wentao Liang

Date: Tue Nov 03 2026 - 05:36:40 EST


otx2_tc_parse_actions() increments flow_cfg->mark_flows when it finds a
FLOW_ACTION_MARK action. The reference is meant to be dropped again by
otx2_tc_del_flow() when the flow is removed, so a flow that fails to
install after its actions were parsed leaks it: the checks for the MCAM
entry, the insertion into the flow list, the mailbox allocation and the
mailbox reply all free the new flow node without touching the counter.
The same happens when parsing the actions itself fails after the mark
action was processed.

Release the reference on the error paths of otx2_tc_add_flow(), using
the match id of the parsed request to tell whether it was taken.

Fixes: 6a57f091622a ("octeontx2-pf: Add support for offload tc with skbedit mark action")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
index dee38d5c7f65..c3726d9f455a 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
@@ -1237,6 +1237,13 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
return 0;
}

+static void otx2_tc_put_mark_flow(struct otx2_nic *nic,
+ struct npc_install_flow_req *req)
+{
+ if (req->match_id)
+ refcount_dec(&nic->flow_cfg->mark_flows);
+}
+
static int otx2_tc_add_flow(struct otx2_nic *nic,
struct flow_cls_offload *tc_flow_cmd)
{
@@ -1273,6 +1280,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,

rc = otx2_tc_prepare_flow(nic, new_node, tc_flow_cmd, &dummy);
if (rc) {
+ otx2_tc_put_mark_flow(nic, &dummy);
kfree_rcu(new_node, rcu);
return rc;
}
@@ -1287,6 +1295,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
if (rc) {
NL_SET_ERR_MSG_MOD(extack,
"MCAM rule allocation failed");
+ otx2_tc_put_mark_flow(nic, &dummy);
kfree_rcu(new_node, rcu);
return rc;
}
@@ -1331,6 +1340,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
return 0;

free_leaf:
+ otx2_tc_put_mark_flow(nic, &dummy);
if (is_cn20k(nic->pdev))
cn20k_tc_free_mcam_entry(nic, new_node->entry);
otx2_tc_del_from_flow_list(flow_cfg, new_node);
--
2.34.1