From patchwork Tue Feb 1 08:49:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106753 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 ABB95A00C5; Tue, 1 Feb 2022 09:50:12 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7D208411DF; Tue, 1 Feb 2022 09:50:08 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id F28A240685 for ; Tue, 1 Feb 2022 09:50:05 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id 9E1A140; Tue, 1 Feb 2022 11:50:05 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 9E1A140 Authentication-Results: shelob.oktetlabs.ru/9E1A140; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 1/8] net/sfc: rework flow action RSS support Date: Tue, 1 Feb 2022 11:49:55 +0300 Message-Id: <20220201085002.320102-2-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 Currently, the driver always allocates a dedicated NIC RSS context for every separate flow rule with action RSS, which is not optimal. First of all, multiple rules which have the same RSS specification can share a context since filters in the hardware operate this way. Secondly, entries in a context's indirection table are not precise queue IDs but offsets with regard to the base queue ID of a filter. This way, for example, queue arrays "0, 1, 2" and "3, 4, 5" in two otherwise identical RSS specifications allow the driver to use the same context since they both yield the same table of queue offsets. Rework flow action RSS support in order to use these optimisations. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/meson.build | 1 + drivers/net/sfc/sfc.c | 12 +- drivers/net/sfc/sfc.h | 4 +- drivers/net/sfc/sfc_ethdev.c | 8 +- drivers/net/sfc/sfc_flow.c | 249 ++++---------------- drivers/net/sfc/sfc_flow.h | 19 +- drivers/net/sfc/sfc_flow_rss.c | 409 +++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_flow_rss.h | 81 +++++++ 8 files changed, 562 insertions(+), 221 deletions(-) create mode 100644 drivers/net/sfc/sfc_flow_rss.c create mode 100644 drivers/net/sfc/sfc_flow_rss.h diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build index 46d94184b8..547cb8db8c 100644 --- a/drivers/net/sfc/meson.build +++ b/drivers/net/sfc/meson.build @@ -90,6 +90,7 @@ sources = files( 'sfc_mae.c', 'sfc_mae_counter.c', 'sfc_flow.c', + 'sfc_flow_rss.c', 'sfc_flow_tunnel.c', 'sfc_dp.c', 'sfc_ef10_rx.c', diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 2cead4e045..51726d229b 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -848,7 +848,9 @@ sfc_rss_attach(struct sfc_adapter *sa) efx_intr_fini(sa->nic); rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); - rss->dummy_rss_context = EFX_RSS_CONTEXT_DEFAULT; + memset(&rss->dummy_ctx, 0, sizeof(rss->dummy_ctx)); + rss->dummy_ctx.conf.qid_span = 1; + rss->dummy_ctx.dummy = true; return 0; @@ -970,6 +972,10 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_rss_attach; + rc = sfc_flow_rss_attach(sa); + if (rc != 0) + goto fail_flow_rss_attach; + rc = sfc_filter_attach(sa); if (rc != 0) goto fail_filter_attach; @@ -1033,6 +1039,9 @@ sfc_attach(struct sfc_adapter *sa) sfc_filter_detach(sa); fail_filter_attach: + sfc_flow_rss_detach(sa); + +fail_flow_rss_attach: sfc_rss_detach(sa); fail_rss_attach: @@ -1087,6 +1096,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_mae_detach(sa); sfc_mae_counter_rxq_detach(sa); sfc_filter_detach(sa); + sfc_flow_rss_detach(sa); sfc_rss_detach(sa); sfc_port_detach(sa); sfc_ev_detach(sa); diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 3337cb57e3..c075c01883 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,6 +27,7 @@ #include "sfc_debug.h" #include "sfc_log.h" #include "sfc_filter.h" +#include "sfc_flow_rss.h" #include "sfc_flow_tunnel.h" #include "sfc_sriov.h" #include "sfc_mae.h" @@ -118,7 +119,7 @@ struct sfc_rss { unsigned int tbl[EFX_RSS_TBL_SIZE]; uint8_t key[EFX_RSS_KEY_SIZE]; - uint32_t dummy_rss_context; + struct sfc_flow_rss_ctx dummy_ctx; }; /* Adapter private data shared by primary and secondary processes */ @@ -238,6 +239,7 @@ struct sfc_adapter { struct sfc_intr intr; struct sfc_port port; struct sfc_sw_stats sw_stats; + struct sfc_flow_rss flow_rss; /* Registry of tunnel offload contexts */ struct sfc_flow_tunnel flow_tunnels[SFC_FT_MAX_NTUNNELS]; struct sfc_filter filter; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index d4210b63dd..abf7b8d287 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -1674,15 +1674,13 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); struct sfc_rss *rss = &sfc_sa2shared(sa)->rss; unsigned int efx_hash_types; - uint32_t contexts[] = {EFX_RSS_CONTEXT_DEFAULT, rss->dummy_rss_context}; unsigned int n_contexts; unsigned int mode_i = 0; unsigned int key_i = 0; + uint32_t contexts[2]; unsigned int i = 0; int rc = 0; - n_contexts = rss->dummy_rss_context == EFX_RSS_CONTEXT_DEFAULT ? 1 : 2; - if (sfc_sa2shared(sa)->isolated) return -ENOTSUP; @@ -1709,6 +1707,10 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, if (rc != 0) goto fail_rx_hf_rte_to_efx; + contexts[0] = EFX_RSS_CONTEXT_DEFAULT; + contexts[1] = rss->dummy_ctx.nic_handle; + n_contexts = (rss->dummy_ctx.nic_handle_refcnt == 0) ? 1 : 2; + for (mode_i = 0; mode_i < n_contexts; mode_i++) { rc = efx_rx_scale_mode_set(sa->nic, contexts[mode_i], rss->hash_alg, efx_hash_types, diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 509fde4a86..bbb40a3b38 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -22,6 +22,7 @@ #include "sfc_rx.h" #include "sfc_filter.h" #include "sfc_flow.h" +#include "sfc_flow_rss.h" #include "sfc_flow_tunnel.h" #include "sfc_log.h" #include "sfc_dp_rx.h" @@ -41,11 +42,12 @@ static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_filter; static sfc_flow_parse_cb_t sfc_flow_parse_rte_to_mae; static sfc_flow_insert_cb_t sfc_flow_filter_insert; static sfc_flow_remove_cb_t sfc_flow_filter_remove; +static sfc_flow_cleanup_cb_t sfc_flow_cleanup; static const struct sfc_flow_ops_by_spec sfc_flow_ops_filter = { .parse = sfc_flow_parse_rte_to_filter, .verify = NULL, - .cleanup = NULL, + .cleanup = sfc_flow_cleanup, .insert = sfc_flow_filter_insert, .remove = sfc_flow_filter_remove, .query = NULL, @@ -1429,8 +1431,14 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, spec_filter->template.efs_dmaq_id = (uint16_t)rxq->hw_index; rxq_info = &sfc_sa2shared(sa)->rxq_info[queue->index]; - spec_filter->rss_hash_required = !!(rxq_info->rxq_flags & - SFC_RXQ_FLAG_RSS_HASH); + + if ((rxq_info->rxq_flags & SFC_RXQ_FLAG_RSS_HASH) != 0) { + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_rss *ethdev_rss = &sas->rss; + + spec_filter->template.efs_flags |= EFX_FILTER_FLAG_RX_RSS; + spec_filter->rss_ctx = ðdev_rss->dummy_ctx; + } return 0; } @@ -1440,107 +1448,30 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, const struct rte_flow_action_rss *action_rss, struct rte_flow *flow) { - struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); - struct sfc_rss *rss = &sas->rss; - sfc_ethdev_qid_t ethdev_qid; + struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter; + struct sfc_flow_rss_conf conf; + uint16_t sw_qid_min; struct sfc_rxq *rxq; - unsigned int rxq_hw_index_min; - unsigned int rxq_hw_index_max; - efx_rx_hash_type_t efx_hash_types; - const uint8_t *rss_key; - struct sfc_flow_spec *spec = &flow->spec; - struct sfc_flow_spec_filter *spec_filter = &spec->filter; - struct sfc_flow_rss *sfc_rss_conf = &spec_filter->rss_conf; - unsigned int i; - - if (action_rss->queue_num == 0) - return -EINVAL; - - ethdev_qid = sfc_sa2shared(sa)->ethdev_rxq_count - 1; - rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, ethdev_qid); - rxq_hw_index_min = rxq->hw_index; - rxq_hw_index_max = 0; - - for (i = 0; i < action_rss->queue_num; ++i) { - ethdev_qid = action_rss->queue[i]; - - if ((unsigned int)ethdev_qid >= - sfc_sa2shared(sa)->ethdev_rxq_count) - return -EINVAL; - - rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, ethdev_qid); - - if (rxq->hw_index < rxq_hw_index_min) - rxq_hw_index_min = rxq->hw_index; - - if (rxq->hw_index > rxq_hw_index_max) - rxq_hw_index_max = rxq->hw_index; - } + int rc; - if (rxq_hw_index_max - rxq_hw_index_min + 1 > EFX_MAXRSS) - return -EINVAL; + spec_filter->template.efs_flags |= EFX_FILTER_FLAG_RX_RSS; - switch (action_rss->func) { - case RTE_ETH_HASH_FUNCTION_DEFAULT: - case RTE_ETH_HASH_FUNCTION_TOEPLITZ: - break; - default: - return -EINVAL; - } + rc = sfc_flow_rss_parse_conf(sa, action_rss, &conf, &sw_qid_min); + if (rc != 0) + return -rc; - if (action_rss->level) - return -EINVAL; + rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, sw_qid_min); + spec_filter->template.efs_dmaq_id = rxq->hw_index; - /* - * Dummy RSS action with only one queue and no specific settings - * for hash types and key does not require dedicated RSS context - * and may be simplified to single queue action. - */ - if (action_rss->queue_num == 1 && action_rss->types == 0 && - action_rss->key_len == 0) { - spec_filter->template.efs_dmaq_id = rxq_hw_index_min; + spec_filter->rss_ctx = sfc_flow_rss_ctx_reuse(sa, &conf, sw_qid_min, + action_rss->queue); + if (spec_filter->rss_ctx != NULL) return 0; - } - - if (action_rss->types) { - int rc; - - rc = sfc_rx_hf_rte_to_efx(sa, action_rss->types, - &efx_hash_types); - if (rc != 0) - return -rc; - } else { - unsigned int i; - - efx_hash_types = 0; - for (i = 0; i < rss->hf_map_nb_entries; ++i) - efx_hash_types |= rss->hf_map[i].efx; - } - - if (action_rss->key_len) { - if (action_rss->key_len != sizeof(rss->key)) - return -EINVAL; - - rss_key = action_rss->key; - } else { - rss_key = rss->key; - } - - spec_filter->rss = B_TRUE; - - sfc_rss_conf->rxq_hw_index_min = rxq_hw_index_min; - sfc_rss_conf->rxq_hw_index_max = rxq_hw_index_max; - sfc_rss_conf->rss_hash_types = efx_hash_types; - rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(rss->key)); - for (i = 0; i < RTE_DIM(sfc_rss_conf->rss_tbl); ++i) { - unsigned int nb_queues = action_rss->queue_num; - struct sfc_rxq *rxq; - - ethdev_qid = action_rss->queue[i % nb_queues]; - rxq = sfc_rxq_ctrl_by_ethdev_qid(sa, ethdev_qid); - sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min; - } + rc = sfc_flow_rss_ctx_add(sa, &conf, sw_qid_min, action_rss->queue, + &spec_filter->rss_ctx); + if (rc != 0) + return -rc; return 0; } @@ -1597,61 +1528,17 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { - struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); - struct sfc_rss *rss = &sas->rss; struct sfc_flow_spec_filter *spec_filter = &flow->spec.filter; - struct sfc_flow_rss *flow_rss = &spec_filter->rss_conf; - uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; - boolean_t create_context; - unsigned int i; + struct sfc_flow_rss_ctx *rss_ctx = spec_filter->rss_ctx; int rc = 0; - create_context = spec_filter->rss || (spec_filter->rss_hash_required && - rss->dummy_rss_context == EFX_RSS_CONTEXT_DEFAULT); - - if (create_context) { - unsigned int rss_spread; - unsigned int rss_hash_types; - uint8_t *rss_key; - - if (spec_filter->rss) { - rss_spread = flow_rss->rxq_hw_index_max - - flow_rss->rxq_hw_index_min + 1; - rss_hash_types = flow_rss->rss_hash_types; - rss_key = flow_rss->rss_key; - } else { - /* - * Initialize dummy RSS context parameters to have - * valid RSS hash. Use default RSS hash function and - * key. - */ - rss_spread = 1; - rss_hash_types = rss->hash_types; - rss_key = rss->key; - } - - rc = efx_rx_scale_context_alloc(sa->nic, - EFX_RX_SCALE_EXCLUSIVE, - rss_spread, - &efs_rss_context); - if (rc != 0) - goto fail_scale_context_alloc; - - rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, - rss->hash_alg, - rss_hash_types, B_TRUE); - if (rc != 0) - goto fail_scale_mode_set; + rc = sfc_flow_rss_ctx_program(sa, rss_ctx); + if (rc != 0) + goto fail_rss_ctx_program; - rc = efx_rx_scale_key_set(sa->nic, efs_rss_context, - rss_key, sizeof(rss->key)); - if (rc != 0) - goto fail_scale_key_set; - } else { - efs_rss_context = rss->dummy_rss_context; - } + if (rss_ctx != NULL) { + unsigned int i; - if (spec_filter->rss || spec_filter->rss_hash_required) { /* * At this point, fully elaborated filter specifications * have been produced from the template. To make sure that @@ -1661,10 +1548,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, for (i = 0; i < spec_filter->count; i++) { efx_filter_spec_t *spec = &spec_filter->filters[i]; - spec->efs_rss_context = efs_rss_context; - spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS; - if (spec_filter->rss) - spec->efs_dmaq_id = flow_rss->rxq_hw_index_min; + spec->efs_rss_context = rss_ctx->nic_handle; } } @@ -1672,42 +1556,12 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, if (rc != 0) goto fail_filter_insert; - if (create_context) { - unsigned int dummy_tbl[RTE_DIM(flow_rss->rss_tbl)] = {0}; - unsigned int *tbl; - - tbl = spec_filter->rss ? flow_rss->rss_tbl : dummy_tbl; - - /* - * Scale table is set after filter insertion because - * the table entries are relative to the base RxQ ID - * and the latter is submitted to the HW by means of - * inserting a filter, so by the time of the request - * the HW knows all the information needed to verify - * the table entries, and the operation will succeed - */ - rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context, - tbl, RTE_DIM(flow_rss->rss_tbl)); - if (rc != 0) - goto fail_scale_tbl_set; - - /* Remember created dummy RSS context */ - if (!spec_filter->rss) - rss->dummy_rss_context = efs_rss_context; - } - return 0; -fail_scale_tbl_set: - sfc_flow_spec_remove(sa, &flow->spec); - fail_filter_insert: -fail_scale_key_set: -fail_scale_mode_set: - if (create_context) - efx_rx_scale_context_free(sa->nic, efs_rss_context); + sfc_flow_rss_ctx_terminate(sa, rss_ctx); -fail_scale_context_alloc: +fail_rss_ctx_program: return rc; } @@ -1722,18 +1576,9 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, if (rc != 0) return rc; - if (spec_filter->rss) { - /* - * All specifications for a given flow rule have the same RSS - * context, so that RSS context value is taken from the first - * filter specification - */ - efx_filter_spec_t *spec = &spec_filter->filters[0]; - - rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context); - } + sfc_flow_rss_ctx_terminate(sa, spec_filter->rss_ctx); - return rc; + return 0; } static int @@ -2985,8 +2830,6 @@ sfc_flow_fini(struct sfc_adapter *sa) void sfc_flow_stop(struct sfc_adapter *sa) { - struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); - struct sfc_rss *rss = &sas->rss; struct rte_flow *flow; SFC_ASSERT(sfc_adapter_is_locked(sa)); @@ -2994,11 +2837,6 @@ sfc_flow_stop(struct sfc_adapter *sa) TAILQ_FOREACH(flow, &sa->flow_list, entries) sfc_flow_remove(sa, flow, NULL); - if (rss->dummy_rss_context != EFX_RSS_CONTEXT_DEFAULT) { - efx_rx_scale_context_free(sa->nic, rss->dummy_rss_context); - rss->dummy_rss_context = EFX_RSS_CONTEXT_DEFAULT; - } - /* * MAE counter service is not stopped on flow rule remove to avoid * extra work. Make sure that it is stopped here. @@ -3029,3 +2867,12 @@ sfc_flow_start(struct sfc_adapter *sa) fail_bad_flow: return rc; } + +static void +sfc_flow_cleanup(struct sfc_adapter *sa, struct rte_flow *flow) +{ + if (flow == NULL) + return; + + sfc_flow_rss_ctx_del(sa, flow->spec.filter.rss_ctx); +} diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index efdecc97ab..545e2267d4 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -15,6 +15,8 @@ #include "efx.h" +#include "sfc_flow_rss.h" + #ifdef __cplusplus extern "C" { #endif @@ -30,15 +32,6 @@ extern "C" { #define SFC_BUILD_SET_OVERFLOW(_action, _set) \ RTE_BUILD_BUG_ON((_action) >= sizeof(_set) * CHAR_BIT) -/* RSS configuration storage */ -struct sfc_flow_rss { - unsigned int rxq_hw_index_min; - unsigned int rxq_hw_index_max; - unsigned int rss_hash_types; - uint8_t rss_key[EFX_RSS_KEY_SIZE]; - unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; -}; - /* Flow engines supported by the implementation */ enum sfc_flow_spec_type { SFC_FLOW_SPEC_FILTER = 0, @@ -55,12 +48,8 @@ struct sfc_flow_spec_filter { efx_filter_spec_t filters[SF_FLOW_SPEC_NB_FILTERS_MAX]; /* number of complete specifications */ unsigned int count; - /* RSS toggle */ - boolean_t rss; - /* RSS hash toggle */ - boolean_t rss_hash_required; - /* RSS configuration */ - struct sfc_flow_rss rss_conf; + /* RSS context (or NULL) */ + struct sfc_flow_rss_ctx *rss_ctx; }; /* Indicates the role of a given flow in tunnel offload */ diff --git a/drivers/net/sfc/sfc_flow_rss.c b/drivers/net/sfc/sfc_flow_rss.c new file mode 100644 index 0000000000..17876f11c1 --- /dev/null +++ b/drivers/net/sfc/sfc_flow_rss.c @@ -0,0 +1,409 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Xilinx, Inc. + */ + +#include +#include + +#include +#include +#include + +#include "efx.h" + +#include "sfc.h" +#include "sfc_debug.h" +#include "sfc_flow_rss.h" +#include "sfc_log.h" +#include "sfc_rx.h" + +int +sfc_flow_rss_attach(struct sfc_adapter *sa) +{ + struct sfc_flow_rss *flow_rss = &sa->flow_rss; + + sfc_log_init(sa, "entry"); + + TAILQ_INIT(&flow_rss->ctx_list); + + sfc_log_init(sa, "done"); + + return 0; +} + +void +sfc_flow_rss_detach(struct sfc_adapter *sa) +{ + sfc_log_init(sa, "entry"); + + sfc_log_init(sa, "done"); +} + +int +sfc_flow_rss_parse_conf(struct sfc_adapter *sa, + const struct rte_flow_action_rss *in, + struct sfc_flow_rss_conf *out, uint16_t *sw_qid_minp) +{ + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + const struct sfc_rss *ethdev_rss = &sas->rss; + uint16_t sw_qid_min; + uint16_t sw_qid_max; + const uint8_t *key; + unsigned int i; + int rc; + + if (in->level) { + /* + * The caller demands that RSS hash be computed + * within the given encapsulation frame / level. + * Per flow control for that is not implemented. + */ + sfc_err(sa, "flow-rss: parse: 'level' must be 0"); + return EINVAL; + } + + if (in->types != 0) { + rc = sfc_rx_hf_rte_to_efx(sa, in->types, + &out->efx_hash_types); + if (rc != 0) { + sfc_err(sa, "flow-rss: parse: failed to process 'types'"); + return rc; + } + } else { + sfc_dbg(sa, "flow-rss: parse: 'types' is 0; proceeding with ethdev setting"); + out->efx_hash_types = ethdev_rss->hash_types; + } + + if (in->key_len != 0) { + if (in->key_len != sizeof(out->key)) { + sfc_err(sa, "flow-rss: parse: 'key_len' must be either %zu or 0", + sizeof(out->key)); + return EINVAL; + } + + if (in->key == NULL) { + sfc_err(sa, "flow-rss: parse: 'key' is NULL"); + return EINVAL; + } + + key = in->key; + } else { + sfc_dbg(sa, "flow-rss: parse: 'key_len' is 0; proceeding with ethdev key"); + key = ethdev_rss->key; + } + + rte_memcpy(out->key, key, sizeof(out->key)); + + switch (in->func) { + case RTE_ETH_HASH_FUNCTION_DEFAULT: + /* + * DEFAULT means that conformance to a specific + * hash algorithm is a don't care to the caller. + * The driver can pick the one it deems optimal. + */ + break; + case RTE_ETH_HASH_FUNCTION_TOEPLITZ: + if (ethdev_rss->hash_alg != EFX_RX_HASHALG_TOEPLITZ) { + sfc_err(sa, "flow-rss: parse: 'func' TOEPLITZ is unavailable; use DEFAULT"); + return EINVAL; + } + break; + default: + sfc_err(sa, "flow-rss: parse: 'func' #%d is unsupported", in->func); + return EINVAL; + } + + if (in->queue_num == 0) { + sfc_err(sa, "flow-rss: parse: 'queue_num' is 0; MIN=1"); + return EINVAL; + } + + if (in->queue_num > EFX_RSS_TBL_SIZE) { + sfc_err(sa, "flow-rss: parse: 'queue_num' is too large; MAX=%u", + EFX_RSS_TBL_SIZE); + return EINVAL; + } + + if (in->queue == NULL) { + sfc_err(sa, "flow-rss: parse: 'queue' is NULL"); + return EINVAL; + } + + sw_qid_min = sas->ethdev_rxq_count - 1; + sw_qid_max = 0; + + out->nb_qid_offsets = 0; + + for (i = 0; i < in->queue_num; ++i) { + uint16_t sw_qid = in->queue[i]; + + if (sw_qid >= sas->ethdev_rxq_count) { + sfc_err(sa, "flow-rss: parse: queue=%u does not exist", + sw_qid); + return EINVAL; + } + + if (sw_qid < sw_qid_min) + sw_qid_min = sw_qid; + + if (sw_qid > sw_qid_max) + sw_qid_max = sw_qid; + + if (sw_qid != in->queue[0] + i) + out->nb_qid_offsets = in->queue_num; + } + + out->qid_span = sw_qid_max - sw_qid_min + 1; + + if (out->qid_span > EFX_MAXRSS) { + sfc_err(sa, "flow-rss: parse: queue ID span %u is too large; MAX=%u", + out->qid_span, EFX_MAXRSS); + return EINVAL; + } + + if (sw_qid_minp != NULL) + *sw_qid_minp = sw_qid_min; + + return 0; +} + +struct sfc_flow_rss_ctx * +sfc_flow_rss_ctx_reuse(struct sfc_adapter *sa, + const struct sfc_flow_rss_conf *conf, + uint16_t sw_qid_min, const uint16_t *sw_qids) +{ + struct sfc_flow_rss *flow_rss = &sa->flow_rss; + static struct sfc_flow_rss_ctx *ctx; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + TAILQ_FOREACH(ctx, &flow_rss->ctx_list, entries) { + if (memcmp(&ctx->conf, conf, sizeof(*conf)) != 0) + continue; + + if (conf->nb_qid_offsets != 0) { + bool match_confirmed = true; + unsigned int i; + + for (i = 0; i < conf->nb_qid_offsets; ++i) { + uint16_t qid_offset = sw_qids[i] - sw_qid_min; + + if (ctx->qid_offsets[i] != qid_offset) { + match_confirmed = false; + break; + } + } + + if (!match_confirmed) + continue; + } + + sfc_dbg(sa, "flow-rss: reusing ctx=%p", ctx); + ++(ctx->refcnt); + return ctx; + } + + return NULL; +} + +int +sfc_flow_rss_ctx_add(struct sfc_adapter *sa, + const struct sfc_flow_rss_conf *conf, uint16_t sw_qid_min, + const uint16_t *sw_qids, struct sfc_flow_rss_ctx **ctxp) +{ + struct sfc_flow_rss *flow_rss = &sa->flow_rss; + struct sfc_flow_rss_ctx *ctx; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + ctx = rte_zmalloc("sfc_flow_rss_ctx", sizeof(*ctx), 0); + if (ctx == NULL) + return ENOMEM; + + if (conf->nb_qid_offsets != 0) { + unsigned int i; + + ctx->qid_offsets = rte_calloc("sfc_flow_rss_ctx_qid_offsets", + conf->nb_qid_offsets, + sizeof(*ctx->qid_offsets), 0); + if (ctx->qid_offsets == NULL) { + rte_free(ctx); + return ENOMEM; + } + + for (i = 0; i < conf->nb_qid_offsets; ++i) + ctx->qid_offsets[i] = sw_qids[i] - sw_qid_min; + } + + ctx->conf = *conf; + ctx->refcnt = 1; + + TAILQ_INSERT_TAIL(&flow_rss->ctx_list, ctx, entries); + + *ctxp = ctx; + + sfc_dbg(sa, "flow-rss: added ctx=%p", ctx); + + return 0; +} + +void +sfc_flow_rss_ctx_del(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) +{ + struct sfc_flow_rss *flow_rss = &sa->flow_rss; + + if (ctx == NULL) + return; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + if (ctx->dummy) + return; + + SFC_ASSERT(ctx->refcnt != 0); + + --(ctx->refcnt); + + if (ctx->refcnt != 0) + return; + + if (ctx->nic_handle_refcnt != 0) { + sfc_err(sa, "flow-rss: deleting ctx=%p abandons its NIC resource: handle=0x%08x, refcnt=%u", + ctx, ctx->nic_handle, ctx->nic_handle_refcnt); + } + + TAILQ_REMOVE(&flow_rss->ctx_list, ctx, entries); + rte_free(ctx->qid_offsets); + rte_free(ctx); + + sfc_dbg(sa, "flow-rss: deleted ctx=%p", ctx); +} + +static int +sfc_flow_rss_ctx_program_tbl(struct sfc_adapter *sa, + const struct sfc_flow_rss_ctx *ctx) +{ + const struct sfc_flow_rss_conf *conf = &ctx->conf; + unsigned int *tbl = sa->flow_rss.bounce_tbl; + unsigned int i; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + if (conf->nb_qid_offsets != 0) { + SFC_ASSERT(ctx->qid_offsets != NULL); + + for (i = 0; i < EFX_RSS_TBL_SIZE; ++i) + tbl[i] = ctx->qid_offsets[i % conf->nb_qid_offsets]; + } else { + for (i = 0; i < EFX_RSS_TBL_SIZE; ++i) + tbl[i] = i % conf->qid_span; + } + + return efx_rx_scale_tbl_set(sa->nic, ctx->nic_handle, + tbl, EFX_RSS_TBL_SIZE); +} + +int +sfc_flow_rss_ctx_program(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) +{ + efx_rx_scale_context_type_t ctx_type = EFX_RX_SCALE_EXCLUSIVE; + struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + struct sfc_rss *ethdev_rss = &sas->rss; + struct sfc_flow_rss_conf *conf; + bool allocation_done = B_FALSE; + int rc; + + if (ctx == NULL) + return 0; + + conf = &ctx->conf; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + if (ctx->nic_handle_refcnt == 0) { + rc = efx_rx_scale_context_alloc(sa->nic, ctx_type, + conf->qid_span, + &ctx->nic_handle); + if (rc != 0) { + sfc_err(sa, "flow-rss: failed to allocate NIC resource for ctx=%p: type=%d, qid_span=%u, rc=%d", + ctx, ctx_type, conf->qid_span, rc); + goto fail; + } + + sfc_dbg(sa, "flow-rss: allocated NIC resource for ctx=%p: type=%d, qid_span=%u; handle=0x%08x", + ctx, ctx_type, conf->qid_span, + ctx->nic_handle); + + ++(ctx->nic_handle_refcnt); + allocation_done = B_TRUE; + } else { + ++(ctx->nic_handle_refcnt); + return 0; + } + + rc = efx_rx_scale_mode_set(sa->nic, ctx->nic_handle, + ethdev_rss->hash_alg, + (ctx->dummy) ? ethdev_rss->hash_types : + conf->efx_hash_types, + B_TRUE); + if (rc != 0) { + sfc_err(sa, "flow-rss: failed to configure hash for ctx=%p: efx_hash_alg=%d, efx_hash_types=0x%08x; rc=%d", + ctx, ethdev_rss->hash_alg, + (ctx->dummy) ? ethdev_rss->hash_types : + conf->efx_hash_types, + rc); + goto fail; + } + + rc = efx_rx_scale_key_set(sa->nic, ctx->nic_handle, + (ctx->dummy) ? ethdev_rss->key : conf->key, + RTE_DIM(conf->key)); + if (rc != 0) { + sfc_err(sa, "flow-rss: failed to set key for ctx=%p; rc=%d", + ctx, rc); + goto fail; + } + + rc = sfc_flow_rss_ctx_program_tbl(sa, ctx); + if (rc != 0) { + sfc_err(sa, "flow-rss: failed to program table for ctx=%p; rc=%d", + ctx, rc); + goto fail; + } + + return 0; + +fail: + if (allocation_done) + sfc_flow_rss_ctx_terminate(sa, ctx); + + return rc; +} + +void +sfc_flow_rss_ctx_terminate(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) +{ + if (ctx == NULL) + return; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + SFC_ASSERT(ctx->nic_handle_refcnt != 0); + --(ctx->nic_handle_refcnt); + + if (ctx->nic_handle_refcnt == 0) { + int rc; + + rc = efx_rx_scale_context_free(sa->nic, ctx->nic_handle); + if (rc != 0) { + sfc_err(sa, "flow-rss: failed to release NIC resource for ctx=%p: handle=0x%08x; rc=%d", + ctx, ctx->nic_handle, rc); + + sfc_warn(sa, "flow-rss: proceeding despite the prior error"); + } + + sfc_dbg(sa, "flow-rss: released NIC resource for ctx=%p; rc=%d", + ctx, rc); + } +} diff --git a/drivers/net/sfc/sfc_flow_rss.h b/drivers/net/sfc/sfc_flow_rss.h new file mode 100644 index 0000000000..cb2355ab67 --- /dev/null +++ b/drivers/net/sfc/sfc_flow_rss.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2022 Xilinx, Inc. + */ + +#ifndef _SFC_FLOW_RSS_H +#define _SFC_FLOW_RSS_H + +#include +#include + +#include +#include + +#include "efx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct sfc_flow_rss_conf { + uint8_t key[EFX_RSS_KEY_SIZE]; + efx_rx_hash_type_t efx_hash_types; + unsigned int nb_qid_offsets; + unsigned int qid_span; +}; + +struct sfc_flow_rss_ctx { + TAILQ_ENTRY(sfc_flow_rss_ctx) entries; + + unsigned int refcnt; + bool dummy; + + unsigned int nic_handle_refcnt; + uint32_t nic_handle; + + struct sfc_flow_rss_conf conf; + + uint16_t *qid_offsets; +}; + +TAILQ_HEAD(sfc_flow_rss_ctx_list, sfc_flow_rss_ctx); + +struct sfc_flow_rss { + unsigned int bounce_tbl[EFX_RSS_TBL_SIZE]; + + struct sfc_flow_rss_ctx_list ctx_list; +}; + +struct sfc_adapter; + +int sfc_flow_rss_attach(struct sfc_adapter *sa); + +void sfc_flow_rss_detach(struct sfc_adapter *sa); + +int sfc_flow_rss_parse_conf(struct sfc_adapter *sa, + const struct rte_flow_action_rss *in, + struct sfc_flow_rss_conf *out, + uint16_t *sw_qid_minp); + +struct sfc_flow_rss_ctx *sfc_flow_rss_ctx_reuse(struct sfc_adapter *sa, + const struct sfc_flow_rss_conf *conf, + uint16_t sw_qid_min, const uint16_t *sw_qids); + +int sfc_flow_rss_ctx_add(struct sfc_adapter *sa, + const struct sfc_flow_rss_conf *conf, + uint16_t sw_qid_min, const uint16_t *sw_qids, + struct sfc_flow_rss_ctx **ctxp); + +void sfc_flow_rss_ctx_del(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx); + +int sfc_flow_rss_ctx_program(struct sfc_adapter *sa, + struct sfc_flow_rss_ctx *ctx); + +void sfc_flow_rss_ctx_terminate(struct sfc_adapter *sa, + struct sfc_flow_rss_ctx *ctx); + +#ifdef __cplusplus +} +#endif +#endif /* _SFC_FLOW_RSS_H */ From patchwork Tue Feb 1 08:49:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106759 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 8F982A00C5; Tue, 1 Feb 2022 09:50:48 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 10FEC426F3; Tue, 1 Feb 2022 09:50:15 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 6C75640685 for ; Tue, 1 Feb 2022 09:50:06 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id D3F5241; Tue, 1 Feb 2022 11:50:05 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru D3F5241 Authentication-Results: shelob.oktetlabs.ru/D3F5241; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 2/8] common/sfc_efx/base: query RSS queue span limit on Riverhead Date: Tue, 1 Feb 2022 11:49:56 +0300 Message-Id: <20220201085002.320102-3-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 On Riverhead boards, clients can query the limit on how many queues an RSS context may address. Put the capability to use. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_nic.c | 14 ++++++++++++-- drivers/common/sfc_efx/base/ef10_rx.c | 3 ++- drivers/common/sfc_efx/base/efx.h | 7 +++++++ drivers/common/sfc_efx/base/siena_nic.c | 2 ++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_nic.c b/drivers/common/sfc_efx/base/ef10_nic.c index 355d274470..d9f7c0f362 100644 --- a/drivers/common/sfc_efx/base/ef10_nic.c +++ b/drivers/common/sfc_efx/base/ef10_nic.c @@ -1051,14 +1051,14 @@ ef10_get_datapath_caps( efx_nic_cfg_t *encp = &(enp->en_nic_cfg); efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_CAPABILITIES_IN_LEN, - MC_CMD_GET_CAPABILITIES_V7_OUT_LEN); + MC_CMD_GET_CAPABILITIES_V9_OUT_LEN); efx_rc_t rc; req.emr_cmd = MC_CMD_GET_CAPABILITIES; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN; req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_GET_CAPABILITIES_V7_OUT_LEN; + req.emr_out_length = MC_CMD_GET_CAPABILITIES_V9_OUT_LEN; efx_mcdi_execute_quiet(enp, &req); @@ -1466,6 +1466,16 @@ ef10_get_datapath_caps( encp->enc_mae_admin = B_FALSE; #endif /* EFSYS_OPT_MAE */ +#if EFSYS_OPT_RX_SCALE + if (req.emr_out_length_used >= MC_CMD_GET_CAPABILITIES_V9_OUT_LEN) { + encp->enc_rx_scale_indirection_max_nqueues = + MCDI_OUT_DWORD(req, + GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_QUEUES); + } else { + encp->enc_rx_scale_indirection_max_nqueues = EFX_MAXRSS; + } +#endif /* EFSYS_OPT_RX_SCALE */ + #undef CAP_FLAGS1 #undef CAP_FLAGS2 #undef CAP_FLAGS3 diff --git a/drivers/common/sfc_efx/base/ef10_rx.c b/drivers/common/sfc_efx/base/ef10_rx.c index a658e0dba2..3b041b962e 100644 --- a/drivers/common/sfc_efx/base/ef10_rx.c +++ b/drivers/common/sfc_efx/base/ef10_rx.c @@ -18,6 +18,7 @@ efx_mcdi_rss_context_alloc( __in uint32_t num_queues, __out uint32_t *rss_contextp) { + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN); @@ -25,7 +26,7 @@ efx_mcdi_rss_context_alloc( uint32_t context_type; efx_rc_t rc; - if (num_queues > EFX_MAXRSS) { + if (num_queues > encp->enc_rx_scale_indirection_max_nqueues) { rc = EINVAL; goto fail1; } diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 96769935c0..f875487b89 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -1495,6 +1495,13 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; #if EFSYS_OPT_RX_SCALE + /* + * The limit on how many queues an RSS indirection table can address. + * + * Indirection table entries are offsets relative to a base queue ID. + * This means that the maximum offset has to be less than this value. + */ + uint32_t enc_rx_scale_indirection_max_nqueues; uint32_t enc_rx_scale_max_exclusive_contexts; /* * Mask of supported hash algorithms. diff --git a/drivers/common/sfc_efx/base/siena_nic.c b/drivers/common/sfc_efx/base/siena_nic.c index e42599131a..5f6d298d3f 100644 --- a/drivers/common/sfc_efx/base/siena_nic.c +++ b/drivers/common/sfc_efx/base/siena_nic.c @@ -119,6 +119,8 @@ siena_board_cfg( encp->enc_rx_push_align = 1; #if EFSYS_OPT_RX_SCALE + encp->enc_rx_scale_indirection_max_nqueues = EFX_MAXRSS; + /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; From patchwork Tue Feb 1 08:49:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106754 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 BD87BA00C5; Tue, 1 Feb 2022 09:50:18 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id ADAC941C3D; Tue, 1 Feb 2022 09:50:09 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 704F140698 for ; Tue, 1 Feb 2022 09:50:06 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id 0E53042; Tue, 1 Feb 2022 11:50:06 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 0E53042 Authentication-Results: shelob.oktetlabs.ru/0E53042; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 3/8] net/sfc: use non-static queue span limit in flow action RSS Date: Tue, 1 Feb 2022 11:49:57 +0300 Message-Id: <20220201085002.320102-4-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 On EF10 boards, the limit on how many queues an RSS context can address is 64. On EF100 boards, this parameter may vary. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_flow_rss.c | 8 ++++++-- drivers/net/sfc/sfc_flow_rss.h | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/sfc_flow_rss.c b/drivers/net/sfc/sfc_flow_rss.c index 17876f11c1..1c94333b62 100644 --- a/drivers/net/sfc/sfc_flow_rss.c +++ b/drivers/net/sfc/sfc_flow_rss.c @@ -21,10 +21,13 @@ int sfc_flow_rss_attach(struct sfc_adapter *sa) { + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); struct sfc_flow_rss *flow_rss = &sa->flow_rss; sfc_log_init(sa, "entry"); + flow_rss->qid_span_max = encp->enc_rx_scale_indirection_max_nqueues; + TAILQ_INIT(&flow_rss->ctx_list); sfc_log_init(sa, "done"); @@ -46,6 +49,7 @@ sfc_flow_rss_parse_conf(struct sfc_adapter *sa, struct sfc_flow_rss_conf *out, uint16_t *sw_qid_minp) { struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + const struct sfc_flow_rss *flow_rss = &sa->flow_rss; const struct sfc_rss *ethdev_rss = &sas->rss; uint16_t sw_qid_min; uint16_t sw_qid_max; @@ -156,9 +160,9 @@ sfc_flow_rss_parse_conf(struct sfc_adapter *sa, out->qid_span = sw_qid_max - sw_qid_min + 1; - if (out->qid_span > EFX_MAXRSS) { + if (out->qid_span > flow_rss->qid_span_max) { sfc_err(sa, "flow-rss: parse: queue ID span %u is too large; MAX=%u", - out->qid_span, EFX_MAXRSS); + out->qid_span, flow_rss->qid_span_max); return EINVAL; } diff --git a/drivers/net/sfc/sfc_flow_rss.h b/drivers/net/sfc/sfc_flow_rss.h index cb2355ab67..e9f798a8f3 100644 --- a/drivers/net/sfc/sfc_flow_rss.h +++ b/drivers/net/sfc/sfc_flow_rss.h @@ -42,6 +42,8 @@ struct sfc_flow_rss_ctx { TAILQ_HEAD(sfc_flow_rss_ctx_list, sfc_flow_rss_ctx); struct sfc_flow_rss { + unsigned int qid_span_max; + unsigned int bounce_tbl[EFX_RSS_TBL_SIZE]; struct sfc_flow_rss_ctx_list ctx_list; From patchwork Tue Feb 1 08:49:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106760 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 CACA7A00C5; Tue, 1 Feb 2022 09:50:53 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 137BC426F8; Tue, 1 Feb 2022 09:50:16 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id CC1B540685 for ; Tue, 1 Feb 2022 09:50:07 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id 3980938; Tue, 1 Feb 2022 11:50:06 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 3980938 Authentication-Results: shelob.oktetlabs.ru/3980938; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 4/8] common/sfc_efx/base: revise name of RSS table entry count Date: Tue, 1 Feb 2022 11:49:58 +0300 Message-Id: <20220201085002.320102-5-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 In the existing code, "n" is hardly a clear name for that. Use a clearer name to help future maintainers of the code. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_impl.h | 10 +++--- drivers/common/sfc_efx/base/ef10_rx.c | 25 +++++++-------- drivers/common/sfc_efx/base/efx.h | 10 +++--- drivers/common/sfc_efx/base/efx_rx.c | 39 ++++++++++++------------ drivers/common/sfc_efx/base/rhead_impl.h | 10 +++--- drivers/common/sfc_efx/base/rhead_rx.c | 12 ++++---- 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_impl.h b/drivers/common/sfc_efx/base/ef10_impl.h index d48f238479..597dd24909 100644 --- a/drivers/common/sfc_efx/base/ef10_impl.h +++ b/drivers/common/sfc_efx/base/ef10_impl.h @@ -1163,12 +1163,12 @@ ef10_rx_scale_key_set( __in size_t n); LIBEFX_INTERNAL -extern __checkReturn efx_rc_t +extern __checkReturn efx_rc_t ef10_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n); + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries); LIBEFX_INTERNAL extern __checkReturn uint32_t diff --git a/drivers/common/sfc_efx/base/ef10_rx.c b/drivers/common/sfc_efx/base/ef10_rx.c index 3b041b962e..5008139a3f 100644 --- a/drivers/common/sfc_efx/base/ef10_rx.c +++ b/drivers/common/sfc_efx/base/ef10_rx.c @@ -292,12 +292,12 @@ efx_mcdi_rss_context_set_key( #endif /* EFSYS_OPT_RX_SCALE */ #if EFSYS_OPT_RX_SCALE -static efx_rc_t +static efx_rc_t efx_mcdi_rss_context_set_table( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n) + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries) { efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN, @@ -325,7 +325,8 @@ efx_mcdi_rss_context_set_table( for (i = 0; i < MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN; i++) { - req_table[i] = (n > 0) ? (uint8_t)table[i % n] : 0; + req_table[i] = (nentries > 0) ? + (uint8_t)table[i % nentries] : 0; } efx_mcdi_execute(enp, &req); @@ -514,12 +515,12 @@ ef10_rx_scale_key_set( #endif /* EFSYS_OPT_RX_SCALE */ #if EFSYS_OPT_RX_SCALE - __checkReturn efx_rc_t + __checkReturn efx_rc_t ef10_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n) + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries) { efx_rc_t rc; @@ -533,7 +534,7 @@ ef10_rx_scale_tbl_set( } if ((rc = efx_mcdi_rss_context_set_table(enp, - rss_context, table, n)) != 0) + rss_context, table, nentries)) != 0) goto fail2; return (0); diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index f875487b89..a35e29ebcf 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -2903,12 +2903,12 @@ efx_rx_scale_mode_set( __in boolean_t insert); LIBEFX_API -extern __checkReturn efx_rc_t +extern __checkReturn efx_rc_t efx_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n); + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries); LIBEFX_API extern __checkReturn efx_rc_t diff --git a/drivers/common/sfc_efx/base/efx_rx.c b/drivers/common/sfc_efx/base/efx_rx.c index 7e63363be7..eb3f736f63 100644 --- a/drivers/common/sfc_efx/base/efx_rx.c +++ b/drivers/common/sfc_efx/base/efx_rx.c @@ -41,12 +41,12 @@ siena_rx_scale_key_set( __in_ecount(n) uint8_t *key, __in size_t n); -static __checkReturn efx_rc_t +static __checkReturn efx_rc_t siena_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n); + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries); static __checkReturn uint32_t siena_rx_prefix_hash( @@ -690,12 +690,12 @@ efx_rx_scale_key_set( #endif /* EFSYS_OPT_RX_SCALE */ #if EFSYS_OPT_RX_SCALE - __checkReturn efx_rc_t + __checkReturn efx_rc_t efx_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n) + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries) { const efx_rx_ops_t *erxop = enp->en_erxop; efx_rc_t rc; @@ -703,7 +703,8 @@ efx_rx_scale_tbl_set( EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); - if ((rc = erxop->erxo_scale_tbl_set(enp, rss_context, table, n)) != 0) + if ((rc = erxop->erxo_scale_tbl_set(enp, rss_context, table, + nentries)) != 0) goto fail1; return (0); @@ -1419,12 +1420,12 @@ siena_rx_scale_key_set( #endif #if EFSYS_OPT_RX_SCALE -static __checkReturn efx_rc_t +static __checkReturn efx_rc_t siena_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n) + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries) { efx_oword_t oword; int index; @@ -1438,7 +1439,7 @@ siena_rx_scale_tbl_set( goto fail1; } - if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) { + if (nentries > FR_BZ_RX_INDIRECTION_TBL_ROWS) { rc = EINVAL; goto fail2; } @@ -1447,7 +1448,7 @@ siena_rx_scale_tbl_set( uint32_t byte; /* Calculate the entry to place in the table */ - byte = (n > 0) ? (uint32_t)table[index % n] : 0; + byte = (nentries > 0) ? (uint32_t)table[index % nentries] : 0; EFSYS_PROBE2(table, int, index, uint32_t, byte); @@ -1462,7 +1463,7 @@ siena_rx_scale_tbl_set( uint32_t byte; /* Determine if we're starting a new batch */ - byte = (n > 0) ? (uint32_t)table[index % n] : 0; + byte = (nentries > 0) ? (uint32_t)table[index % nentries] : 0; /* Read the table */ EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL, diff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h index dd38ded775..e0d95ba2aa 100644 --- a/drivers/common/sfc_efx/base/rhead_impl.h +++ b/drivers/common/sfc_efx/base/rhead_impl.h @@ -287,12 +287,12 @@ rhead_rx_scale_key_set( __in size_t n); LIBEFX_INTERNAL -extern __checkReturn efx_rc_t +extern __checkReturn efx_rc_t rhead_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n); + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries); LIBEFX_INTERNAL extern __checkReturn uint32_t diff --git a/drivers/common/sfc_efx/base/rhead_rx.c b/drivers/common/sfc_efx/base/rhead_rx.c index 7b9a4af9da..d28f936ab7 100644 --- a/drivers/common/sfc_efx/base/rhead_rx.c +++ b/drivers/common/sfc_efx/base/rhead_rx.c @@ -162,16 +162,16 @@ rhead_rx_scale_key_set( return (rc); } - __checkReturn efx_rc_t + __checkReturn efx_rc_t rhead_rx_scale_tbl_set( - __in efx_nic_t *enp, - __in uint32_t rss_context, - __in_ecount(n) unsigned int *table, - __in size_t n) + __in efx_nic_t *enp, + __in uint32_t rss_context, + __in_ecount(nentries) unsigned int *table, + __in size_t nentries) { efx_rc_t rc; - rc = ef10_rx_scale_tbl_set(enp, rss_context, table, n); + rc = ef10_rx_scale_tbl_set(enp, rss_context, table, nentries); if (rc != 0) goto fail1; From patchwork Tue Feb 1 08:49:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106755 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 28622A00C5; Tue, 1 Feb 2022 09:50:28 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 715E7426E2; Tue, 1 Feb 2022 09:50:11 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 9E15140691 for ; Tue, 1 Feb 2022 09:50:06 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id 7BEB044; Tue, 1 Feb 2022 11:50:06 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 7BEB044 Authentication-Results: shelob.oktetlabs.ru/7BEB044; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton , Ray Kinsella Subject: [PATCH 5/8] common/sfc_efx/base: support selecting RSS table entry count Date: Tue, 1 Feb 2022 11:49:59 +0300 Message-Id: <20220201085002.320102-6-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 On Riverhead boards, the client can control how many entries to have in the indirection table of an exclusive RSS context. Provide the new parameter to clients and indicate its bounds. Extend the API for writing the table to have the flexibility. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_impl.h | 1 + drivers/common/sfc_efx/base/ef10_nic.c | 13 +++ drivers/common/sfc_efx/base/ef10_rx.c | 136 +++++++++++++++++++++-- drivers/common/sfc_efx/base/efx.h | 18 +++ drivers/common/sfc_efx/base/efx_impl.h | 3 +- drivers/common/sfc_efx/base/efx_mcdi.h | 11 ++ drivers/common/sfc_efx/base/efx_rx.c | 38 ++++++- drivers/common/sfc_efx/base/rhead_impl.h | 1 + drivers/common/sfc_efx/base/rhead_rx.c | 4 +- drivers/common/sfc_efx/version.map | 1 + 10 files changed, 212 insertions(+), 14 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_impl.h b/drivers/common/sfc_efx/base/ef10_impl.h index 597dd24909..342a9a2006 100644 --- a/drivers/common/sfc_efx/base/ef10_impl.h +++ b/drivers/common/sfc_efx/base/ef10_impl.h @@ -1137,6 +1137,7 @@ ef10_rx_scale_context_alloc( __in efx_nic_t *enp, __in efx_rx_scale_context_type_t type, __in uint32_t num_queues, + __in uint32_t table_nentries, __out uint32_t *rss_contextp); LIBEFX_INTERNAL diff --git a/drivers/common/sfc_efx/base/ef10_nic.c b/drivers/common/sfc_efx/base/ef10_nic.c index d9f7c0f362..cca31bc725 100644 --- a/drivers/common/sfc_efx/base/ef10_nic.c +++ b/drivers/common/sfc_efx/base/ef10_nic.c @@ -1409,6 +1409,11 @@ ef10_get_datapath_caps( */ encp->enc_rx_scale_l4_hash_supported = B_TRUE; } + + if (CAP_FLAGS3(req, RSS_SELECTABLE_TABLE_SIZE)) + encp->enc_rx_scale_tbl_entry_count_is_selectable = B_TRUE; + else + encp->enc_rx_scale_tbl_entry_count_is_selectable = B_FALSE; #endif /* EFSYS_OPT_RX_SCALE */ /* Check if the firmware supports "FLAG" and "MARK" filter actions */ @@ -1471,8 +1476,16 @@ ef10_get_datapath_caps( encp->enc_rx_scale_indirection_max_nqueues = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_QUEUES); + encp->enc_rx_scale_tbl_min_nentries = + MCDI_OUT_DWORD(req, + GET_CAPABILITIES_V9_OUT_RSS_MIN_INDIRECTION_TABLE_SIZE); + encp->enc_rx_scale_tbl_max_nentries = + MCDI_OUT_DWORD(req, + GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_TABLE_SIZE); } else { encp->enc_rx_scale_indirection_max_nqueues = EFX_MAXRSS; + encp->enc_rx_scale_tbl_min_nentries = EFX_RSS_TBL_SIZE; + encp->enc_rx_scale_tbl_max_nentries = EFX_RSS_TBL_SIZE; } #endif /* EFSYS_OPT_RX_SCALE */ diff --git a/drivers/common/sfc_efx/base/ef10_rx.c b/drivers/common/sfc_efx/base/ef10_rx.c index 5008139a3f..78af7300a0 100644 --- a/drivers/common/sfc_efx/base/ef10_rx.c +++ b/drivers/common/sfc_efx/base/ef10_rx.c @@ -16,11 +16,12 @@ efx_mcdi_rss_context_alloc( __in efx_nic_t *enp, __in efx_rx_scale_context_type_t type, __in uint32_t num_queues, + __in uint32_t table_nentries, __out uint32_t *rss_contextp) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); efx_mcdi_req_t req; - EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN, + EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_LEN, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN); uint32_t rss_context; uint32_t context_type; @@ -31,6 +32,13 @@ efx_mcdi_rss_context_alloc( goto fail1; } + if (table_nentries < encp->enc_rx_scale_tbl_min_nentries || + table_nentries > encp->enc_rx_scale_tbl_max_nentries || + !ISP2(table_nentries)) { + rc = EINVAL; + goto fail2; + } + switch (type) { case EFX_RX_SCALE_EXCLUSIVE: context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE; @@ -40,12 +48,15 @@ efx_mcdi_rss_context_alloc( break; default: rc = EINVAL; - goto fail2; + goto fail3; } req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC; req.emr_in_buf = payload; - req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN; + req.emr_in_length = + (encp->enc_rx_scale_tbl_entry_count_is_selectable != B_FALSE) ? + MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_LEN : + MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN; req.emr_out_buf = payload; req.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN; @@ -61,28 +72,36 @@ efx_mcdi_rss_context_alloc( */ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, num_queues); + if (encp->enc_rx_scale_tbl_entry_count_is_selectable != B_FALSE) { + MCDI_IN_SET_DWORD(req, + RSS_CONTEXT_ALLOC_V2_IN_INDIRECTION_TABLE_SIZE, + table_nentries); + } + efx_mcdi_execute(enp, &req); if (req.emr_rc != 0) { rc = req.emr_rc; - goto fail3; + goto fail4; } if (req.emr_out_length_used < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) { rc = EMSGSIZE; - goto fail4; + goto fail5; } rss_context = MCDI_OUT_DWORD(req, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID); if (rss_context == EF10_RSS_CONTEXT_INVALID) { rc = ENOENT; - goto fail5; + goto fail6; } *rss_contextp = rss_context; return (0); +fail6: + EFSYS_PROBE(fail6); fail5: EFSYS_PROBE(fail5); fail4: @@ -347,6 +366,76 @@ efx_mcdi_rss_context_set_table( } #endif /* EFSYS_OPT_RX_SCALE */ +#if EFSYS_OPT_RX_SCALE +static __checkReturn efx_rc_t +efx_mcdi_rss_context_write_table( + __in efx_nic_t *enp, + __in uint32_t context, + __in unsigned int start_idx, + __in_ecount(nentries) unsigned int *table, + __in unsigned int nentries) +{ + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LENMAX_MCDI2, + MC_CMD_RSS_CONTEXT_WRITE_TABLE_OUT_LEN); + unsigned int i; + int rc; + + if (nentries > + MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MAXNUM_MCDI2) { + rc = EINVAL; + goto fail1; + } + + if (start_idx + nentries > + encp->enc_rx_scale_tbl_max_nentries) { + rc = EINVAL; + goto fail2; + } + + req.emr_cmd = MC_CMD_RSS_CONTEXT_WRITE_TABLE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_LEN(nentries); + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_RSS_CONTEXT_WRITE_TABLE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, + RSS_CONTEXT_WRITE_TABLE_IN_RSS_CONTEXT_ID, context); + + for (i = 0; i < nentries; ++i) { + if (table[i] >= encp->enc_rx_scale_indirection_max_nqueues) { + rc = EINVAL; + goto fail3; + } + + MCDI_IN_POPULATE_INDEXED_DWORD_2(req, + RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES, i, + RSS_CONTEXT_WRITE_TABLE_ENTRY_INDEX, start_idx + i, + RSS_CONTEXT_WRITE_TABLE_ENTRY_VALUE, table[i]); + } + + efx_mcdi_execute(enp, &req); + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail4; + } + + return (0); + +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} +#endif /* EFSYS_OPT_RX_SCALE */ + __checkReturn efx_rc_t ef10_rx_init( @@ -355,7 +444,7 @@ ef10_rx_init( #if EFSYS_OPT_RX_SCALE if (efx_mcdi_rss_context_alloc(enp, EFX_RX_SCALE_EXCLUSIVE, EFX_MAXRSS, - &enp->en_rss_context) == 0) { + EFX_RSS_TBL_SIZE, &enp->en_rss_context) == 0) { /* * Allocated an exclusive RSS context, which allows both the * indirection table and key to be modified. @@ -398,11 +487,13 @@ ef10_rx_scale_context_alloc( __in efx_nic_t *enp, __in efx_rx_scale_context_type_t type, __in uint32_t num_queues, + __in uint32_t table_nentries, __out uint32_t *rss_contextp) { efx_rc_t rc; - rc = efx_mcdi_rss_context_alloc(enp, type, num_queues, rss_contextp); + rc = efx_mcdi_rss_context_alloc(enp, type, num_queues, table_nentries, + rss_contextp); if (rc != 0) goto fail1; @@ -522,6 +613,7 @@ ef10_rx_scale_tbl_set( __in_ecount(nentries) unsigned int *table, __in size_t nentries) { + const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); efx_rc_t rc; @@ -533,12 +625,34 @@ ef10_rx_scale_tbl_set( rss_context = enp->en_rss_context; } - if ((rc = efx_mcdi_rss_context_set_table(enp, - rss_context, table, nentries)) != 0) - goto fail2; + if (encp->enc_rx_scale_tbl_entry_count_is_selectable != B_FALSE) { + uint32_t index, remain, batch; + + batch = MC_CMD_RSS_CONTEXT_WRITE_TABLE_IN_ENTRIES_MAXNUM_MCDI2; + index = 0; + + for (remain = nentries; remain > 0; remain -= batch) { + if (batch > remain) + batch = remain; + + rc = efx_mcdi_rss_context_write_table(enp, rss_context, + index, &table[index], batch); + if (rc != 0) + goto fail2; + + index += batch; + } + } else { + rc = efx_mcdi_rss_context_set_table(enp, rss_context, table, + nentries); + if (rc != 0) + goto fail3; + } return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index a35e29ebcf..4523829eb2 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -1502,6 +1502,10 @@ typedef struct efx_nic_cfg_s { * This means that the maximum offset has to be less than this value. */ uint32_t enc_rx_scale_indirection_max_nqueues; + /* Minimum number of entries an RSS indirection table can contain. */ + uint32_t enc_rx_scale_tbl_min_nentries; + /* Maximum number of entries an RSS indirection table can contain. */ + uint32_t enc_rx_scale_tbl_max_nentries; uint32_t enc_rx_scale_max_exclusive_contexts; /* * Mask of supported hash algorithms. @@ -1514,6 +1518,11 @@ typedef struct efx_nic_cfg_s { */ boolean_t enc_rx_scale_l4_hash_supported; boolean_t enc_rx_scale_additional_modes_supported; + /* + * Indicates whether the user can decide how many entries to + * have in the indirection table of an exclusive RSS context. + */ + boolean_t enc_rx_scale_tbl_entry_count_is_selectable; #endif /* EFSYS_OPT_RX_SCALE */ #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; @@ -2887,6 +2896,15 @@ efx_rx_scale_context_alloc( __in uint32_t num_queues, __out uint32_t *rss_contextp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_rx_scale_context_alloc_v2( + __in efx_nic_t *enp, + __in efx_rx_scale_context_type_t type, + __in uint32_t num_queues, + __in uint32_t table_nentries, + __out uint32_t *rss_contextp); + LIBEFX_API extern __checkReturn efx_rc_t efx_rx_scale_context_free( diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h index e2802e6672..7dfe30b695 100644 --- a/drivers/common/sfc_efx/base/efx_impl.h +++ b/drivers/common/sfc_efx/base/efx_impl.h @@ -173,7 +173,8 @@ typedef struct efx_rx_ops_s { #if EFSYS_OPT_RX_SCALE efx_rc_t (*erxo_scale_context_alloc)(efx_nic_t *, efx_rx_scale_context_type_t, - uint32_t, uint32_t *); + uint32_t, uint32_t, + uint32_t *); efx_rc_t (*erxo_scale_context_free)(efx_nic_t *, uint32_t); efx_rc_t (*erxo_scale_mode_set)(efx_nic_t *, uint32_t, efx_rx_hash_alg_t, diff --git a/drivers/common/sfc_efx/base/efx_mcdi.h b/drivers/common/sfc_efx/base/efx_mcdi.h index c91ea41911..14a3833567 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.h +++ b/drivers/common/sfc_efx/base/efx_mcdi.h @@ -315,6 +315,10 @@ efx_mcdi_set_nic_addr_regions( #define MCDI_IN2(_emr, _type, _ofst) \ MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST) +#define MCDI_INDEXED_IN2(_emr, _type, _ofst, _idx) \ + MCDI_IN(_emr, _type, MC_CMD_ ## _ofst ## _OFST + \ + _idx * MC_CMD_ ## _ofst ## _LEN) + #define MCDI_IN_SET_BYTE(_emr, _ofst, _value) \ EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst), \ EFX_BYTE_0, _value) @@ -356,6 +360,13 @@ efx_mcdi_set_nic_addr_regions( MC_CMD_ ## _field1, _value1, \ MC_CMD_ ## _field2, _value2) +#define MCDI_IN_POPULATE_INDEXED_DWORD_2(_emr, _ofst, _idx, \ + _field1, _value1, _field2, _value2) \ + EFX_POPULATE_DWORD_2( \ + *MCDI_INDEXED_IN2(_emr, efx_dword_t, _ofst, _idx), \ + MC_CMD_ ## _field1, _value1, \ + MC_CMD_ ## _field2, _value2) + #define MCDI_IN_POPULATE_DWORD_3(_emr, _ofst, _field1, _value1, \ _field2, _value2, _field3, _value3) \ EFX_POPULATE_DWORD_3(*MCDI_IN2(_emr, efx_dword_t, _ofst), \ diff --git a/drivers/common/sfc_efx/base/efx_rx.c b/drivers/common/sfc_efx/base/efx_rx.c index eb3f736f63..d10b990259 100644 --- a/drivers/common/sfc_efx/base/efx_rx.c +++ b/drivers/common/sfc_efx/base/efx_rx.c @@ -514,8 +514,44 @@ efx_rx_scale_context_alloc( rc = ENOTSUP; goto fail1; } + + if ((rc = erxop->erxo_scale_context_alloc(enp, type, num_queues, + EFX_RSS_TBL_SIZE, rss_contextp)) != 0) { + goto fail2; + } + + return (0); + +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} +#endif /* EFSYS_OPT_RX_SCALE */ + +#if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_context_alloc_v2( + __in efx_nic_t *enp, + __in efx_rx_scale_context_type_t type, + __in uint32_t num_queues, + __in uint32_t table_nentries, + __out uint32_t *rss_contextp) +{ + const efx_rx_ops_t *erxop = enp->en_erxop; + efx_rc_t rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + + if (erxop->erxo_scale_context_alloc == NULL) { + rc = ENOTSUP; + goto fail1; + } + if ((rc = erxop->erxo_scale_context_alloc(enp, type, - num_queues, rss_contextp)) != 0) { + num_queues, table_nentries, rss_contextp)) != 0) { goto fail2; } diff --git a/drivers/common/sfc_efx/base/rhead_impl.h b/drivers/common/sfc_efx/base/rhead_impl.h index e0d95ba2aa..fb0ecca79d 100644 --- a/drivers/common/sfc_efx/base/rhead_impl.h +++ b/drivers/common/sfc_efx/base/rhead_impl.h @@ -261,6 +261,7 @@ rhead_rx_scale_context_alloc( __in efx_nic_t *enp, __in efx_rx_scale_context_type_t type, __in uint32_t num_queues, + __in uint32_t table_nentries, __out uint32_t *rss_contextp); LIBEFX_INTERNAL diff --git a/drivers/common/sfc_efx/base/rhead_rx.c b/drivers/common/sfc_efx/base/rhead_rx.c index d28f936ab7..d0ac5c02f8 100644 --- a/drivers/common/sfc_efx/base/rhead_rx.c +++ b/drivers/common/sfc_efx/base/rhead_rx.c @@ -88,11 +88,13 @@ rhead_rx_scale_context_alloc( __in efx_nic_t *enp, __in efx_rx_scale_context_type_t type, __in uint32_t num_queues, + __in uint32_t table_nentries, __out uint32_t *rss_contextp) { efx_rc_t rc; - rc = ef10_rx_scale_context_alloc(enp, type, num_queues, rss_contextp); + rc = ef10_rx_scale_context_alloc(enp, type, num_queues, table_nentries, + rss_contextp); if (rc != 0) goto fail1; diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 97dd943ec4..9510897b83 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -216,6 +216,7 @@ INTERNAL { efx_rx_qpost; efx_rx_qpush; efx_rx_scale_context_alloc; + efx_rx_scale_context_alloc_v2; efx_rx_scale_context_free; efx_rx_scale_default_support_get; efx_rx_scale_hash_flags_get; From patchwork Tue Feb 1 08:50:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106756 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 D2E33A00C5; Tue, 1 Feb 2022 09:50:33 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 69F13426E5; Tue, 1 Feb 2022 09:50:12 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id DCCA240685 for ; Tue, 1 Feb 2022 09:50:06 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id A02224A; Tue, 1 Feb 2022 11:50:06 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru A02224A Authentication-Results: shelob.oktetlabs.ru/A02224A; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 6/8] net/sfc: use adaptive table entry count in flow action RSS Date: Tue, 1 Feb 2022 11:50:00 +0300 Message-Id: <20220201085002.320102-7-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 Currently, every RSS context uses 128 indirection entries in the hardware. That is not always optimal because the entries come from a pool shared among all PCI functions of the board, while the format of action RSS allows to pass less queue IDs. With EF100 boards, it is possible to decide how many entries to allocate for the indirection table of a context. Make use of that in order to optimise resource usage in RSS scenarios. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_flow_rss.c | 72 +++++++++++++++++++++++++++------- drivers/net/sfc/sfc_flow_rss.h | 4 +- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/drivers/net/sfc/sfc_flow_rss.c b/drivers/net/sfc/sfc_flow_rss.c index 1c94333b62..4bf3002164 100644 --- a/drivers/net/sfc/sfc_flow_rss.c +++ b/drivers/net/sfc/sfc_flow_rss.c @@ -23,23 +23,45 @@ sfc_flow_rss_attach(struct sfc_adapter *sa) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); struct sfc_flow_rss *flow_rss = &sa->flow_rss; + int rc; sfc_log_init(sa, "entry"); flow_rss->qid_span_max = encp->enc_rx_scale_indirection_max_nqueues; + flow_rss->nb_tbl_entries_min = encp->enc_rx_scale_tbl_min_nentries; + flow_rss->nb_tbl_entries_max = encp->enc_rx_scale_tbl_max_nentries; + + sfc_log_init(sa, "allocate the bounce buffer for indirection entries"); + flow_rss->bounce_tbl = rte_calloc("sfc_flow_rss_bounce_tbl", + flow_rss->nb_tbl_entries_max, + sizeof(*flow_rss->bounce_tbl), 0); + if (flow_rss->bounce_tbl == NULL) { + rc = ENOMEM; + goto fail; + } TAILQ_INIT(&flow_rss->ctx_list); sfc_log_init(sa, "done"); return 0; + +fail: + sfc_log_init(sa, "failed %d", rc); + + return rc; } void sfc_flow_rss_detach(struct sfc_adapter *sa) { + struct sfc_flow_rss *flow_rss = &sa->flow_rss; + sfc_log_init(sa, "entry"); + sfc_log_init(sa, "free the bounce buffer for indirection entries"); + rte_free(flow_rss->bounce_tbl); + sfc_log_init(sa, "done"); } @@ -123,9 +145,9 @@ sfc_flow_rss_parse_conf(struct sfc_adapter *sa, return EINVAL; } - if (in->queue_num > EFX_RSS_TBL_SIZE) { + if (in->queue_num > flow_rss->nb_tbl_entries_max) { sfc_err(sa, "flow-rss: parse: 'queue_num' is too large; MAX=%u", - EFX_RSS_TBL_SIZE); + flow_rss->nb_tbl_entries_max); return EINVAL; } @@ -286,6 +308,7 @@ sfc_flow_rss_ctx_del(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) static int sfc_flow_rss_ctx_program_tbl(struct sfc_adapter *sa, + unsigned int nb_tbl_entries, const struct sfc_flow_rss_ctx *ctx) { const struct sfc_flow_rss_conf *conf = &ctx->conf; @@ -297,15 +320,15 @@ sfc_flow_rss_ctx_program_tbl(struct sfc_adapter *sa, if (conf->nb_qid_offsets != 0) { SFC_ASSERT(ctx->qid_offsets != NULL); - for (i = 0; i < EFX_RSS_TBL_SIZE; ++i) + for (i = 0; i < nb_tbl_entries; ++i) tbl[i] = ctx->qid_offsets[i % conf->nb_qid_offsets]; } else { - for (i = 0; i < EFX_RSS_TBL_SIZE; ++i) + for (i = 0; i < nb_tbl_entries; ++i) tbl[i] = i % conf->qid_span; } return efx_rx_scale_tbl_set(sa->nic, ctx->nic_handle, - tbl, EFX_RSS_TBL_SIZE); + tbl, nb_tbl_entries); } int @@ -313,9 +336,12 @@ sfc_flow_rss_ctx_program(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) { efx_rx_scale_context_type_t ctx_type = EFX_RX_SCALE_EXCLUSIVE; struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + const struct sfc_flow_rss *flow_rss = &sa->flow_rss; struct sfc_rss *ethdev_rss = &sas->rss; struct sfc_flow_rss_conf *conf; bool allocation_done = B_FALSE; + unsigned int nb_qid_offsets; + unsigned int nb_tbl_entries; int rc; if (ctx == NULL) @@ -325,18 +351,34 @@ sfc_flow_rss_ctx_program(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) SFC_ASSERT(sfc_adapter_is_locked(sa)); + if (conf->nb_qid_offsets != 0) + nb_qid_offsets = conf->nb_qid_offsets; + else + nb_qid_offsets = conf->qid_span; + + if (!RTE_IS_POWER_OF_2(nb_qid_offsets)) { + /* + * Most likely, it pays to enlarge the indirection + * table to facilitate better distribution quality. + */ + nb_qid_offsets = flow_rss->nb_tbl_entries_max; + } + + nb_tbl_entries = RTE_MAX(flow_rss->nb_tbl_entries_min, nb_qid_offsets); + if (ctx->nic_handle_refcnt == 0) { - rc = efx_rx_scale_context_alloc(sa->nic, ctx_type, - conf->qid_span, - &ctx->nic_handle); + rc = efx_rx_scale_context_alloc_v2(sa->nic, ctx_type, + conf->qid_span, + nb_tbl_entries, + &ctx->nic_handle); if (rc != 0) { - sfc_err(sa, "flow-rss: failed to allocate NIC resource for ctx=%p: type=%d, qid_span=%u, rc=%d", - ctx, ctx_type, conf->qid_span, rc); + sfc_err(sa, "flow-rss: failed to allocate NIC resource for ctx=%p: type=%d, qid_span=%u, nb_tbl_entries=%u; rc=%d", + ctx, ctx_type, conf->qid_span, nb_tbl_entries, rc); goto fail; } - sfc_dbg(sa, "flow-rss: allocated NIC resource for ctx=%p: type=%d, qid_span=%u; handle=0x%08x", - ctx, ctx_type, conf->qid_span, + sfc_dbg(sa, "flow-rss: allocated NIC resource for ctx=%p: type=%d, qid_span=%u, nb_tbl_entries=%u; handle=0x%08x", + ctx, ctx_type, conf->qid_span, nb_tbl_entries, ctx->nic_handle); ++(ctx->nic_handle_refcnt); @@ -369,10 +411,10 @@ sfc_flow_rss_ctx_program(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) goto fail; } - rc = sfc_flow_rss_ctx_program_tbl(sa, ctx); + rc = sfc_flow_rss_ctx_program_tbl(sa, nb_tbl_entries, ctx); if (rc != 0) { - sfc_err(sa, "flow-rss: failed to program table for ctx=%p; rc=%d", - ctx, rc); + sfc_err(sa, "flow-rss: failed to program table for ctx=%p: nb_tbl_entries=%u; rc=%d", + ctx, nb_tbl_entries, rc); goto fail; } diff --git a/drivers/net/sfc/sfc_flow_rss.h b/drivers/net/sfc/sfc_flow_rss.h index e9f798a8f3..3341d06cf4 100644 --- a/drivers/net/sfc/sfc_flow_rss.h +++ b/drivers/net/sfc/sfc_flow_rss.h @@ -42,9 +42,11 @@ struct sfc_flow_rss_ctx { TAILQ_HEAD(sfc_flow_rss_ctx_list, sfc_flow_rss_ctx); struct sfc_flow_rss { + unsigned int nb_tbl_entries_min; + unsigned int nb_tbl_entries_max; unsigned int qid_span_max; - unsigned int bounce_tbl[EFX_RSS_TBL_SIZE]; + unsigned int *bounce_tbl; /* MAX */ struct sfc_flow_rss_ctx_list ctx_list; }; From patchwork Tue Feb 1 08:50:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106757 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 0F36AA00C5; Tue, 1 Feb 2022 09:50:39 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5888D426DD; Tue, 1 Feb 2022 09:50:13 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 05DB640691 for ; Tue, 1 Feb 2022 09:50:07 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id C6D134C; Tue, 1 Feb 2022 11:50:06 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru C6D134C Authentication-Results: shelob.oktetlabs.ru/C6D134C; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 7/8] common/sfc_efx/base: support the even spread RSS mode Date: Tue, 1 Feb 2022 11:50:01 +0300 Message-Id: <20220201085002.320102-8-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 Riverhead boards support spreading traffic across the specified number of queues without using indirections. This mode is provided by a dedicated RSS context type. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/ef10_nic.c | 22 +++++++++++++ drivers/common/sfc_efx/base/ef10_rx.c | 42 ++++++++++++++++++------- drivers/common/sfc_efx/base/efx.h | 8 ++++- drivers/common/sfc_efx/base/efx_rx.c | 6 +++- drivers/common/sfc_efx/base/siena_nic.c | 3 ++ 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/drivers/common/sfc_efx/base/ef10_nic.c b/drivers/common/sfc_efx/base/ef10_nic.c index cca31bc725..aa667309ab 100644 --- a/drivers/common/sfc_efx/base/ef10_nic.c +++ b/drivers/common/sfc_efx/base/ef10_nic.c @@ -1482,10 +1482,32 @@ ef10_get_datapath_caps( encp->enc_rx_scale_tbl_max_nentries = MCDI_OUT_DWORD(req, GET_CAPABILITIES_V9_OUT_RSS_MAX_INDIRECTION_TABLE_SIZE); + + if (CAP_FLAGS3(req, RSS_EVEN_SPREADING)) { +#define RSS_MAX_EVEN_SPREADING_QUEUES \ + GET_CAPABILITIES_V9_OUT_RSS_MAX_EVEN_SPREADING_QUEUES + /* + * The even spreading mode distributes traffic across + * the specified number of queues without the need to + * allocate precious indirection entry pool resources. + */ + encp->enc_rx_scale_even_spread_max_nqueues = + MCDI_OUT_DWORD(req, RSS_MAX_EVEN_SPREADING_QUEUES); +#undef RSS_MAX_EVEN_SPREADING_QUEUES + } else { + /* There is no support for the even spread contexts. */ + encp->enc_rx_scale_even_spread_max_nqueues = 0; + } } else { encp->enc_rx_scale_indirection_max_nqueues = EFX_MAXRSS; encp->enc_rx_scale_tbl_min_nentries = EFX_RSS_TBL_SIZE; encp->enc_rx_scale_tbl_max_nentries = EFX_RSS_TBL_SIZE; + + /* + * Assume that there is no support + * for the even spread contexts. + */ + encp->enc_rx_scale_even_spread_max_nqueues = 0; } #endif /* EFSYS_OPT_RX_SCALE */ diff --git a/drivers/common/sfc_efx/base/ef10_rx.c b/drivers/common/sfc_efx/base/ef10_rx.c index 78af7300a0..afc9cf025f 100644 --- a/drivers/common/sfc_efx/base/ef10_rx.c +++ b/drivers/common/sfc_efx/base/ef10_rx.c @@ -23,30 +23,45 @@ efx_mcdi_rss_context_alloc( efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_ALLOC_V2_IN_LEN, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN); + uint32_t table_nentries_min; + uint32_t table_nentries_max; + uint32_t num_queues_max; uint32_t rss_context; uint32_t context_type; efx_rc_t rc; - if (num_queues > encp->enc_rx_scale_indirection_max_nqueues) { - rc = EINVAL; - goto fail1; - } - - if (table_nentries < encp->enc_rx_scale_tbl_min_nentries || - table_nentries > encp->enc_rx_scale_tbl_max_nentries || - !ISP2(table_nentries)) { - rc = EINVAL; - goto fail2; - } - switch (type) { case EFX_RX_SCALE_EXCLUSIVE: context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE; + num_queues_max = encp->enc_rx_scale_indirection_max_nqueues; + table_nentries_min = encp->enc_rx_scale_tbl_min_nentries; + table_nentries_max = encp->enc_rx_scale_tbl_max_nentries; break; case EFX_RX_SCALE_SHARED: context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED; + num_queues_max = encp->enc_rx_scale_indirection_max_nqueues; + table_nentries_min = encp->enc_rx_scale_tbl_min_nentries; + table_nentries_max = encp->enc_rx_scale_tbl_max_nentries; + break; + case EFX_RX_SCALE_EVEN_SPREAD: + context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EVEN_SPREADING; + num_queues_max = encp->enc_rx_scale_even_spread_max_nqueues; + table_nentries_min = 0; + table_nentries_max = 0; break; default: + rc = EINVAL; + goto fail1; + } + + if (num_queues == 0 || num_queues > num_queues_max) { + rc = EINVAL; + goto fail2; + } + + if (table_nentries < table_nentries_min || + table_nentries > table_nentries_max || + (table_nentries != 0 && !ISP2(table_nentries))) { rc = EINVAL; goto fail3; } @@ -69,6 +84,9 @@ efx_mcdi_rss_context_alloc( * indirection table offsets. * For shared contexts, the provided context will spread traffic over * NUM_QUEUES many queues. + * For the even spread contexts, the provided context will spread + * traffic over NUM_QUEUES many queues, but that will not involve + * the use of precious indirection table resources in the adapter. */ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, num_queues); diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 4523829eb2..854527e0fd 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -1495,6 +1495,11 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; #if EFSYS_OPT_RX_SCALE + /* + * The limit on how many queues an RSS context in the even spread + * mode can span. When this mode is not supported, the value is 0. + */ + uint32_t enc_rx_scale_even_spread_max_nqueues; /* * The limit on how many queues an RSS indirection table can address. * @@ -2784,7 +2789,8 @@ typedef enum efx_rx_hash_support_e { typedef enum efx_rx_scale_context_type_e { EFX_RX_SCALE_UNAVAILABLE = 0, /* No RX scale context */ EFX_RX_SCALE_EXCLUSIVE, /* Writable key/indirection table */ - EFX_RX_SCALE_SHARED /* Read-only key/indirection table */ + EFX_RX_SCALE_SHARED, /* Read-only key/indirection table */ + EFX_RX_SCALE_EVEN_SPREAD, /* No indirection table, writable key */ } efx_rx_scale_context_type_t; /* diff --git a/drivers/common/sfc_efx/base/efx_rx.c b/drivers/common/sfc_efx/base/efx_rx.c index d10b990259..45dc5d6c6d 100644 --- a/drivers/common/sfc_efx/base/efx_rx.c +++ b/drivers/common/sfc_efx/base/efx_rx.c @@ -504,6 +504,7 @@ efx_rx_scale_context_alloc( __in uint32_t num_queues, __out uint32_t *rss_contextp) { + uint32_t table_nentries = EFX_RSS_TBL_SIZE; const efx_rx_ops_t *erxop = enp->en_erxop; efx_rc_t rc; @@ -515,8 +516,11 @@ efx_rx_scale_context_alloc( goto fail1; } + if (type == EFX_RX_SCALE_EVEN_SPREAD) + table_nentries = 0; + if ((rc = erxop->erxo_scale_context_alloc(enp, type, num_queues, - EFX_RSS_TBL_SIZE, rss_contextp)) != 0) { + table_nentries, rss_contextp)) != 0) { goto fail2; } diff --git a/drivers/common/sfc_efx/base/siena_nic.c b/drivers/common/sfc_efx/base/siena_nic.c index 5f6d298d3f..939551dbf5 100644 --- a/drivers/common/sfc_efx/base/siena_nic.c +++ b/drivers/common/sfc_efx/base/siena_nic.c @@ -121,6 +121,9 @@ siena_board_cfg( #if EFSYS_OPT_RX_SCALE encp->enc_rx_scale_indirection_max_nqueues = EFX_MAXRSS; + /* There is no support for the even spread contexts. */ + encp->enc_rx_scale_even_spread_max_nqueues = 0; + /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; From patchwork Tue Feb 1 08:50:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 106758 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 061B0A00C5; Tue, 1 Feb 2022 09:50:44 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3F86A426ED; Tue, 1 Feb 2022 09:50:14 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 2879240685 for ; Tue, 1 Feb 2022 09:50:07 +0100 (CET) Received: from bree.oktetlabs.ru (bree.oktetlabs.ru [192.168.34.5]) (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 shelob.oktetlabs.ru (Postfix) with ESMTPS id 06E9550; Tue, 1 Feb 2022 11:50:07 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 06E9550 Authentication-Results: shelob.oktetlabs.ru/06E9550; dkim=none; dkim-atps=neutral From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Andy Moreton Subject: [PATCH 8/8] net/sfc: use the even spread mode in flow action RSS Date: Tue, 1 Feb 2022 11:50:02 +0300 Message-Id: <20220201085002.320102-9-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> References: <20220201085002.320102-1-ivan.malov@oktetlabs.ru> 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 If the user provides contiguous ascending queue IDs, use the even spread mode to avoid wasting resources which are needed to serve indirection table entries. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_flow_rss.c | 19 +++++++++++++++++++ drivers/net/sfc/sfc_flow_rss.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/net/sfc/sfc_flow_rss.c b/drivers/net/sfc/sfc_flow_rss.c index 4bf3002164..e28c943335 100644 --- a/drivers/net/sfc/sfc_flow_rss.c +++ b/drivers/net/sfc/sfc_flow_rss.c @@ -140,6 +140,8 @@ sfc_flow_rss_parse_conf(struct sfc_adapter *sa, return EINVAL; } + out->rte_hash_function = in->func; + if (in->queue_num == 0) { sfc_err(sa, "flow-rss: parse: 'queue_num' is 0; MIN=1"); return EINVAL; @@ -317,6 +319,9 @@ sfc_flow_rss_ctx_program_tbl(struct sfc_adapter *sa, SFC_ASSERT(sfc_adapter_is_locked(sa)); + if (nb_tbl_entries == 0) + return 0; + if (conf->nb_qid_offsets != 0) { SFC_ASSERT(ctx->qid_offsets != NULL); @@ -336,6 +341,7 @@ sfc_flow_rss_ctx_program(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) { efx_rx_scale_context_type_t ctx_type = EFX_RX_SCALE_EXCLUSIVE; struct sfc_adapter_shared * const sas = sfc_sa2shared(sa); + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); const struct sfc_flow_rss *flow_rss = &sa->flow_rss; struct sfc_rss *ethdev_rss = &sas->rss; struct sfc_flow_rss_conf *conf; @@ -366,6 +372,19 @@ sfc_flow_rss_ctx_program(struct sfc_adapter *sa, struct sfc_flow_rss_ctx *ctx) nb_tbl_entries = RTE_MAX(flow_rss->nb_tbl_entries_min, nb_qid_offsets); + if (conf->rte_hash_function == RTE_ETH_HASH_FUNCTION_DEFAULT && + conf->nb_qid_offsets == 0 && + conf->qid_span <= encp->enc_rx_scale_even_spread_max_nqueues) { + /* + * Conformance to a specific hash algorithm is a don't care to + * the user. The queue array is contiguous and ascending. That + * means that the even spread context may be requested here in + * order to avoid wasting precious indirection table resources. + */ + ctx_type = EFX_RX_SCALE_EVEN_SPREAD; + nb_tbl_entries = 0; + } + if (ctx->nic_handle_refcnt == 0) { rc = efx_rx_scale_context_alloc_v2(sa->nic, ctx_type, conf->qid_span, diff --git a/drivers/net/sfc/sfc_flow_rss.h b/drivers/net/sfc/sfc_flow_rss.h index 3341d06cf4..2ed81dc190 100644 --- a/drivers/net/sfc/sfc_flow_rss.h +++ b/drivers/net/sfc/sfc_flow_rss.h @@ -20,6 +20,7 @@ extern "C" { struct sfc_flow_rss_conf { uint8_t key[EFX_RSS_KEY_SIZE]; + enum rte_eth_hash_function rte_hash_function; efx_rx_hash_type_t efx_hash_types; unsigned int nb_qid_offsets; unsigned int qid_span;