DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ivan Malov <ivan.malov@arknetworks.am>
To: dev@dpdk.org
Cc: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,
	Ferruh Yigit <ferruh.yigit@amd.com>,
	Andy Moreton <andy.moreton@amd.com>
Subject: [v24.11 PATCH v1] net/sfc: allow for use of indirect counter in tunnel offload
Date: Mon, 29 Jul 2024 20:38:47 +0400	[thread overview]
Message-ID: <20240729163847.7261-1-ivan.malov@arknetworks.am> (raw)

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(-)

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;
-- 
2.17.1


             reply	other threads:[~2024-07-29 16:39 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-29 16:38 Ivan Malov [this message]
2024-08-01  9:29 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240729163847.7261-1-ivan.malov@arknetworks.am \
    --to=ivan.malov@arknetworks.am \
    --cc=andrew.rybchenko@oktetlabs.ru \
    --cc=andy.moreton@amd.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).