From patchwork Sun Jun 4 23:25:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 128062 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C65E342C2C; Mon, 5 Jun 2023 01:28:58 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5326943019; Mon, 5 Jun 2023 01:26:05 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 46F7042D8D for ; Mon, 5 Jun 2023 01:25:43 +0200 (CEST) Received: from localhost.localdomain (unknown [78.109.68.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id CBBDAE126C; Mon, 5 Jun 2023 03:25:42 +0400 (+04) From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Ferruh Yigit , Andy Moreton Subject: [PATCH v3 34/34] net/sfc: use conntrack assistance counters in transfer flows Date: Mon, 5 Jun 2023 03:25:23 +0400 Message-Id: <20230604232523.6746-35-ivan.malov@arknetworks.am> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230604232523.6746-1-ivan.malov@arknetworks.am> References: <20230601195538.8265-1-ivan.malov@arknetworks.am> <20230604232523.6746-1-ivan.malov@arknetworks.am> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org These are 1-bit saturating counters which can only be useful to tell whether a given flow rule has offloaded some packets since the last query. Byte count is never provided for these. Signed-off-by: Ivan Malov Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_flow.h | 2 + drivers/net/sfc/sfc_mae.c | 119 ++++++++++++++++++++++-------- drivers/net/sfc/sfc_mae.h | 2 + drivers/net/sfc/sfc_mae_counter.c | 30 ++++++++ 4 files changed, 124 insertions(+), 29 deletions(-) diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index af94d0654a..601f93e540 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -86,6 +86,8 @@ struct sfc_flow_spec_mae { /* Conntrack (CT) assistance table entry key and response */ sfc_mae_conntrack_response_t ct_resp; sfc_mae_conntrack_key_t ct_key; + /* Conntrack (CT) assistance counter */ + struct sfc_mae_counter *ct_counter; }; /* PMD-specific definition of the opaque type from rte_flow.h */ diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 7353d04af8..ab315853d5 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -65,7 +65,8 @@ sfc_mae_assign_entity_mport(struct sfc_adapter *sa, static int sfc_mae_counter_registry_init(struct sfc_mae_counter_registry *registry, - uint32_t nb_action_counters_max) + uint32_t nb_action_counters_max, + uint32_t nb_conntrack_counters_max) { int ret; @@ -76,12 +77,20 @@ sfc_mae_counter_registry_init(struct sfc_mae_counter_registry *registry, registry->action_counters.type = EFX_COUNTER_TYPE_ACTION; + ret = sfc_mae_counters_init(®istry->conntrack_counters, + nb_conntrack_counters_max); + if (ret != 0) + return ret; + + registry->conntrack_counters.type = EFX_COUNTER_TYPE_CONNTRACK; + return 0; } static void sfc_mae_counter_registry_fini(struct sfc_mae_counter_registry *registry) { + sfc_mae_counters_fini(®istry->conntrack_counters); sfc_mae_counters_fini(®istry->action_counters); } @@ -162,10 +171,13 @@ sfc_mae_attach(struct sfc_adapter *sa) sfc_log_init(sa, "init MAE counter record registry"); rc = sfc_mae_counter_registry_init(&mae->counter_registry, - limits.eml_max_n_action_counters); + limits.eml_max_n_action_counters, + limits.eml_max_n_conntrack_counters); if (rc != 0) { - sfc_err(sa, "failed to init record registry for %u AR counters: %s", - limits.eml_max_n_action_counters, rte_strerror(rc)); + sfc_err(sa, "failed to init record registry for %u AR and %u CT counters: %s", + limits.eml_max_n_action_counters, + limits.eml_max_n_conntrack_counters, + rte_strerror(rc)); goto fail_counter_registry_init; } } @@ -1471,6 +1483,8 @@ sfc_mae_flow_cleanup(struct sfc_adapter *sa, } sfc_mae_action_rule_del(sa, spec_mae->action_rule); + + sfc_mae_counter_del(sa, spec_mae->ct_counter); } static int @@ -4223,7 +4237,7 @@ static const char * const action_names[] = { static int sfc_mae_rule_parse_action(struct sfc_adapter *sa, const struct rte_flow_action *action, - struct rte_flow *flow, + struct rte_flow *flow, bool ct, struct sfc_mae_actions_bundle *bundle, struct sfc_mae_aset_ctx *ctx, struct rte_flow_error *error) @@ -4239,6 +4253,12 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, bool custom_error = B_FALSE; int rc = 0; + if (ct) { + mae_counter_type = EFX_COUNTER_TYPE_CONNTRACK; + counterp = &spec_mae->ct_counter; + spec_ptr = NULL; + } + switch (action->type) { case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, @@ -4526,7 +4546,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, if (rc != 0) goto fail_rule_parse_action; - rc = sfc_mae_rule_parse_action(sa, action, flow, + rc = sfc_mae_rule_parse_action(sa, action, flow, ct, &bundle, &ctx, error); if (rc != 0) goto fail_rule_parse_action; @@ -4561,8 +4581,15 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, */ efx_mae_action_set_populate_mark_reset(ctx.spec); - (ctx.counter)->ft_switch_hit_counter = - &spec_mae->ft_ctx->switch_hit_counter; + if (ctx.counter != NULL) { + (ctx.counter)->ft_switch_hit_counter = + &spec_mae->ft_ctx->switch_hit_counter; + } else if (sfc_mae_counter_stream_enabled(sa)) { + SFC_ASSERT(ct); + + spec_mae->ct_counter->ft_switch_hit_counter = + &spec_mae->ft_ctx->switch_hit_counter; + } break; default: SFC_ASSERT(B_FALSE); @@ -4843,12 +4870,34 @@ sfc_mae_flow_insert(struct sfc_adapter *sa, return rc; if (spec_mae->action_rule->ct_mark != 0) { + struct sfc_mae_counter *counter = spec_mae->ct_counter; + + rc = sfc_mae_counter_enable(sa, counter, NULL); + if (rc != 0) { + sfc_mae_action_rule_disable(sa, action_rule); + return rc; + } + + if (counter != NULL) { + struct sfc_mae_fw_rsrc *fw_rsrc = &counter->fw_rsrc; + + spec_mae->ct_resp.counter_id = fw_rsrc->counter_id.id; + + rc = sfc_mae_counter_start(sa); + if (rc != 0) { + sfc_mae_action_rule_disable(sa, action_rule); + return rc; + } + } else { + spec_mae->ct_resp.counter_id = EFX_MAE_RSRC_ID_INVALID; + } + spec_mae->ct_resp.ct_mark = spec_mae->action_rule->ct_mark; - spec_mae->ct_resp.counter_id = EFX_MAE_RSRC_ID_INVALID; rc = sfc_mae_conntrack_insert(sa, &spec_mae->ct_key, &spec_mae->ct_resp); if (rc != 0) { + sfc_mae_counter_disable(sa, counter); sfc_mae_action_rule_disable(sa, action_rule); return rc; } @@ -4871,6 +4920,8 @@ sfc_mae_flow_remove(struct sfc_adapter *sa, if (action_rule->ct_mark != 0) (void)sfc_mae_conntrack_delete(sa, &spec_mae->ct_key); + sfc_mae_counter_disable(sa, spec_mae->ct_counter); + sfc_mae_action_rule_disable(sa, action_rule); return 0; @@ -4885,31 +4936,41 @@ sfc_mae_query_counter(struct sfc_adapter *sa, { const struct sfc_mae_action_rule *action_rule = spec->action_rule; const struct rte_flow_action_count *conf = action->conf; - struct sfc_mae_action_set *action_set; - struct sfc_mae_counter *counter; + struct sfc_mae_counter *counters[1 /* action rule counter */ + + 1 /* conntrack counter */]; + unsigned int i; int rc; - if (action_rule == NULL || action_rule->action_set == NULL || - action_rule->action_set->counter == NULL || - action_rule->action_set->counter->indirect) { - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, action, - "Queried flow rule does not have count actions"); - } + /* + * The check for counter unavailability is done based + * on counter traversal results. See error set below. + */ + if (action_rule != NULL && action_rule->action_set != NULL && + action_rule->action_set->counter != NULL && + !action_rule->action_set->counter->indirect) + counters[0] = action_rule->action_set->counter; + else + counters[0] = NULL; - action_set = action_rule->action_set; - counter = action_set->counter; + counters[1] = spec->ct_counter; - if (conf == NULL || - (counter->rte_id_valid && conf->id == counter->rte_id)) { - rc = sfc_mae_counter_get(sa, counter, data); - if (rc != 0) { - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, action, - "Queried flow rule counter action is invalid"); - } + for (i = 0; i < RTE_DIM(counters); ++i) { + struct sfc_mae_counter *counter = counters[i]; - return 0; + if (counter == NULL) + continue; + + if (conf == NULL || + (counter->rte_id_valid && conf->id == counter->rte_id)) { + rc = sfc_mae_counter_get(sa, counter, data); + if (rc != 0) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "Queried flow rule counter action is invalid"); + } + + return 0; + } } return rte_flow_error_set(error, ENOENT, diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h index 3a3a5225fd..80585c0e93 100644 --- a/drivers/net/sfc/sfc_mae.h +++ b/drivers/net/sfc/sfc_mae.h @@ -173,6 +173,8 @@ struct sfc_mae_counter_registry { /* Common counter information */ /** Action rule counter record collection */ struct sfc_mae_counter_records action_counters; + /** Conntrack counter record collection */ + struct sfc_mae_counter_records conntrack_counters; /* Information used by counter update service */ /** Callback to get packets from RxQ */ diff --git a/drivers/net/sfc/sfc_mae_counter.c b/drivers/net/sfc/sfc_mae_counter.c index 47448cba15..79043ff7d7 100644 --- a/drivers/net/sfc/sfc_mae_counter.c +++ b/drivers/net/sfc/sfc_mae_counter.c @@ -91,6 +91,9 @@ sfc_mae_counter_fw_rsrc_enable(struct sfc_adapter *sa, case EFX_COUNTER_TYPE_ACTION: counters = ®->action_counters; break; + case EFX_COUNTER_TYPE_CONNTRACK: + counters = ®->conntrack_counters; + break; default: rc = EINVAL; goto fail_counter_type_check; @@ -172,6 +175,9 @@ sfc_mae_counter_fw_rsrc_disable(struct sfc_adapter *sa, case EFX_COUNTER_TYPE_ACTION: counters = ®->action_counters; break; + case EFX_COUNTER_TYPE_CONNTRACK: + counters = ®->conntrack_counters; + break; default: return EINVAL; } @@ -319,6 +325,9 @@ sfc_mae_parse_counter_packet(struct sfc_adapter *sa, case ERF_SC_PACKETISER_HEADER_IDENTIFIER_AR: counters = &counter_registry->action_counters; break; + case ERF_SC_PACKETISER_HEADER_IDENTIFIER_CT: + counters = &counter_registry->conntrack_counters; + break; default: sfc_err(sa, "unexpected MAE counters source identifier %u", id); return; @@ -392,6 +401,23 @@ sfc_mae_parse_counter_packet(struct sfc_adapter *sa, byte_count_hi = EFX_OWORD_FIELD32(counters_data[i], ERF_SC_PACKETISER_PAYLOAD_BYTE_COUNT_HI); + + if (id == ERF_SC_PACKETISER_HEADER_IDENTIFIER_CT) { + /* + * FIXME: + * + * CT counters are 1-bit saturating counters. + * There is no way to express this in DPDK + * currently, so increment the hit count + * by one to let the application know + * that the flow is still effective. + */ + packet_count_lo = 1; + packet_count_hi = 0; + byte_count_lo = 0; + byte_count_hi = 0; + } + sfc_mae_counter_increment(sa, counters, EFX_OWORD_FIELD32(counters_data[i], @@ -983,6 +1009,10 @@ sfc_mae_counter_get(struct sfc_adapter *sa, counters = &sa->mae.counter_registry.action_counters; need_byte_count = true; break; + case EFX_COUNTER_TYPE_CONNTRACK: + counters = &sa->mae.counter_registry.conntrack_counters; + need_byte_count = false; + break; default: return EINVAL; }