[v24.11,v1] net/sfc: allow for use of indirect counter in tunnel offload

Message ID 20240729163847.7261-1-ivan.malov@arknetworks.am (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series [v24.11,v1] net/sfc: allow for use of indirect counter in tunnel offload |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/intel-Functional success Functional PASS
ci/github-robot: build success github build: passed
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-marvell-Functional success Functional Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-abi-testing success Testing PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-compile-amd64-testing pending Testing pending
ci/iol-sample-apps-testing success Testing PASS

Commit Message

Ivan Malov July 29, 2024, 4:38 p.m. UTC
Support the use of indirect counters in so-called SWITCH
rules (second stage lookup and steering after supposed
decapsulation) in tunnel offload. An indirect counter
can either come instead of an inline counter or, when
the latter is a conntrack-assisted counter, follow it.

Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <andy.moreton@amd.com>
---
 drivers/net/sfc/sfc_mae.c | 66 ++++++++++++++++++++++++++++++++-------
 drivers/net/sfc/sfc_mae.h |  1 +
 2 files changed, 55 insertions(+), 12 deletions(-)
  

Comments

Ferruh Yigit Aug. 1, 2024, 9:29 a.m. UTC | #1
On 7/29/2024 5:38 PM, Ivan Malov wrote:
> Support the use of indirect counters in so-called SWITCH
> rules (second stage lookup and steering after supposed
> decapsulation) in tunnel offload. An indirect counter
> can either come instead of an inline counter or, when
> the latter is a conntrack-assisted counter, follow it.
> 
> Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
> Reviewed-by: Andy Moreton <andy.moreton@amd.com>
>

Applied to dpdk-next-net/main, thanks.
  

Patch

diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 60ff6d2181..ebca402ce4 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -972,6 +972,9 @@  sfc_mae_counter_del(struct sfc_adapter *sa, struct sfc_mae_counter *counter)
 
 	--(counter->refcnt);
 
+	if (counter->refcnt == 1)
+		counter->ft_switch_hit_counter = NULL;
+
 	if (counter->refcnt != 0)
 		return;
 
@@ -4517,21 +4520,23 @@  sfc_mae_rule_parse_action_indirect(struct sfc_adapter *sa, bool replayable_only,
 					return EEXIST;
 				}
 
-				if (ft_rule_type != SFC_FT_RULE_NONE) {
-					return rte_flow_error_set(error, EINVAL,
+				if (ft_rule_type != SFC_FT_RULE_SWITCH &&
+				    entry->counter->ft_switch_hit_counter != NULL) {
+					return rte_flow_error_set(error, EBUSY,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
-					  "cannot use indirect count action in tunnel model");
+					  "cannot use requested indirect counter as it is in use by incompatible offload");
 				}
 
 				SFC_ASSERT(ctx->counter == NULL);
 
 				rc = efx_mae_action_set_populate_count(ctx->spec);
-				if (rc != 0) {
+				if (rc != 0 && !ctx->counter_implicit) {
 					return rte_flow_error_set(error, rc,
 					 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 					 "failed to add COUNT to MAE action set");
 				}
 
+				ctx->counter_implicit = false;
 				ctx->counter = entry->counter;
 				++(ctx->counter->refcnt);
 				break;
@@ -5237,7 +5242,7 @@  sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 		goto fail_action_set_spec_init;
 
 	if (spec_mae->ft_rule_type == SFC_FT_RULE_SWITCH) {
-		bool have_user_action_count = false;
+		bool have_inline_action_count = false;
 
 		/* TUNNEL rules don't decapsulate packets. SWITCH rules do. */
 		rc = efx_mae_action_set_populate_decap(ctx->spec);
@@ -5247,15 +5252,15 @@  sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 		for (action = actions;
 		     action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
 			if (action->type == RTE_FLOW_ACTION_TYPE_COUNT) {
-				have_user_action_count = true;
+				have_inline_action_count = true;
 				break;
 			}
 		}
 
-		if (!have_user_action_count &&
+		if (!have_inline_action_count &&
 		    sfc_mae_counter_stream_enabled(sa)) {
 			/*
-			 * The user opted not to use action COUNT in this rule,
+			 * The user might have opted not to have a counter here,
 			 * but the counter should be enabled implicitly because
 			 * packets hitting this rule contribute to the tunnel's
 			 * total number of hits. See sfc_mae_counter_get().
@@ -5264,9 +5269,19 @@  sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 			if (rc != 0)
 				goto fail_enforce_ft_count;
 
-			rc = sfc_mae_counter_add(sa, NULL, &ctx->counter);
-			if (rc != 0)
-				goto fail_enforce_ft_count;
+			/*
+			 * An action of type COUNT may come inlined (see above)
+			 * or via a shareable handle (enclosed by an action of
+			 * type INDIRECT). The latter is expensive to resolve
+			 * here. For now assume an implicit counter is needed.
+			 *
+			 * But if the flow does come with an indirect counter,
+			 * sfc_mae_rule_parse_action_indirect() will test the
+			 * flag to cope with its "populate" failure. It will
+			 * reset the flag so that below code can skip
+			 * creating a software object for the counter.
+			 */
+			ctx->counter_implicit = true;
 		}
 	}
 
@@ -5314,8 +5329,33 @@  sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 		 */
 		efx_mae_action_set_populate_mark_reset(ctx->spec);
 
+		if (ctx->counter_implicit) {
+			/*
+			 * Turns out the rule indeed does not have a user
+			 * counter, so add one. The action bit in the
+			 * action set specification has already been
+			 * populated by the above preparse logic.
+			 */
+			rc = sfc_mae_counter_add(sa, NULL, &ctx->counter);
+			if (rc != 0)
+				goto fail_add_implicit_counter;
+		}
+
 		if (ctx->counter != NULL) {
-			(ctx->counter)->ft_switch_hit_counter =
+			struct sfc_mae_counter *counter = ctx->counter;
+
+			if (counter->indirect &&
+			    counter->refcnt > 1 /* indirect handle */ +
+					      1 /* 1st use */ &&
+			    counter->ft_switch_hit_counter !=
+			    &spec_mae->ft_ctx->switch_hit_counter) {
+				rc = rte_flow_error_set(error, EBUSY,
+					RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+					"requested indirect counter is in use by another tunnel context");
+				goto fail_check_indirect_counter_ft_ctx;
+			}
+
+			counter->ft_switch_hit_counter =
 				&spec_mae->ft_ctx->switch_hit_counter;
 		} else if (sfc_mae_counter_stream_enabled(sa)) {
 			SFC_ASSERT(ct);
@@ -5366,6 +5406,8 @@  sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 
 fail_action_set_add:
 fail_check_fate_action:
+fail_check_indirect_counter_ft_ctx:
+fail_add_implicit_counter:
 fail_workaround_tunnel_delivery:
 fail_rule_parse_action:
 	sfc_mae_encap_header_del(sa, ctx->encap_header);
diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h
index 2bdf5eeec2..c24dd7cd17 100644
--- a/drivers/net/sfc/sfc_mae.h
+++ b/drivers/net/sfc/sfc_mae.h
@@ -227,6 +227,7 @@  struct sfc_mae_aset_ctx {
 	struct sfc_mae_mac_addr		*dst_mac;
 	struct sfc_mae_mac_addr		*src_mac;
 
+	bool				counter_implicit;
 	bool				fate_set;
 
 	efx_mae_actions_t		*spec;