Commit f7a48511 authored by Yevgeny Kliteynik's avatar Yevgeny Kliteynik Committed by Saeed Mahameed
Browse files

net/mlx5e: TC, CT: Offload ct clear only once



Non-clear CT action causes a flow rule split, while CT clear action
doesn't and is just a header-rewrite to the current flow rule.
But ct offload is done in post_parse and is per ct action instance,
so ct clear offload is parsed multiple times, while its deleted once.

Fix this by post_parsing the ct action only once per flow attribute
(which is per flow rule) by using a offloaded ct_attr flag.

Fixes: 08fe94ec ("net/mlx5e: TC, Remove special handling of CT action")
Signed-off-by: default avatarPaul Blakey <paulb@nvidia.com>
Signed-off-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 65e64640
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -1545,6 +1545,7 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,

	attr->ct_attr.ct_action |= act->ct.action; /* So we can have clear + ct */
	attr->ct_attr.zone = act->ct.zone;
	if (!(act->ct.action & TCA_CT_ACT_CLEAR))
		attr->ct_attr.nf_ft = act->ct.flow_table;
	attr->ct_attr.act_miss_cookie = act->miss_cookie;

@@ -1990,6 +1991,9 @@ mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *att
	if (!priv)
		return -EOPNOTSUPP;

	if (attr->ct_attr.offloaded)
		return 0;

	if (attr->ct_attr.ct_action & TCA_CT_ACT_CLEAR) {
		err = mlx5_tc_ct_entry_set_registers(priv, &attr->parse_attr->mod_hdr_acts,
						     0, 0, 0, 0);
@@ -1999,11 +2003,15 @@ mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *att
		attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
	}

	if (!attr->ct_attr.nf_ft) /* means only ct clear action, and not ct_clear,ct() */
	if (!attr->ct_attr.nf_ft) { /* means only ct clear action, and not ct_clear,ct() */
		attr->ct_attr.offloaded = true;
		return 0;
	}

	mutex_lock(&priv->control_lock);
	err = __mlx5_tc_ct_flow_offload(priv, attr);
	if (!err)
		attr->ct_attr.offloaded = true;
	mutex_unlock(&priv->control_lock);

	return err;
@@ -2021,7 +2029,7 @@ void
mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
		       struct mlx5_flow_attr *attr)
{
	if (!attr->ct_attr.ft) /* no ct action, return */
	if (!attr->ct_attr.offloaded) /* no ct action, return */
		return;
	if (!attr->ct_attr.nf_ft) /* means only ct clear action, and not ct_clear,ct() */
		return;
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ struct mlx5_ct_attr {
	u32 ct_labels_id;
	u32 act_miss_mapping;
	u64 act_miss_cookie;
	bool offloaded;
	struct mlx5_ct_ft *ft;
};