* [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements @ 2018-04-06 17:21 Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko ` (8 more replies) 0 siblings, 9 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev The patch series should be applied on top of [1] and [2]. checkpatches.sh warnings are bacause of positive errno used inside the driver. checkpatches.sh checks are OK. [1] https://dpdk.org/ml/archives/dev/2018-April/095762.html [2] https://dpdk.org/ml/archives/dev/2018-April/095774.html Ivan Malov (7): net/sfc/base: add a new means to control RSS hash net/sfc/base: support more RSS hash configurations net/sfc/base: honour packed stream RSS restriction net/sfc: process RSS settings on Rx configure step net/sfc: remove conditional compilation for RSS net/sfc: factor out RSS fields from adapter info net/sfc: convert to the advanced EFX RSS interface drivers/net/sfc/base/ef10_nic.c | 65 ++++++++- drivers/net/sfc/base/ef10_rx.c | 74 ++++++++++- drivers/net/sfc/base/efx.h | 120 ++++++++++++++++- drivers/net/sfc/base/efx_rx.c | 159 +++++++++++++++++++++- drivers/net/sfc/base/siena_nic.c | 12 ++ drivers/net/sfc/sfc.c | 37 +++--- drivers/net/sfc/sfc.h | 33 +++-- drivers/net/sfc/sfc_ethdev.c | 76 +++++------ drivers/net/sfc/sfc_flow.c | 75 ++++++----- drivers/net/sfc/sfc_flow.h | 4 - drivers/net/sfc/sfc_rx.c | 275 +++++++++++++++++++++++++++++---------- drivers/net/sfc/sfc_rx.h | 10 +- 12 files changed, 743 insertions(+), 197 deletions(-) -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-19 16:17 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 2/7] net/sfc/base: support more RSS hash configurations Andrew Rybchenko ` (7 subsequent siblings) 8 siblings, 1 reply; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Currently, libefx has no support for additional RSS modes available with later controllers. In order to support this, libefx should be able to list available hash configurations. This patch provides basic infrastructure for the new interface. The client drivers will be able to query the list of supported hash configurations for a particular hash algorithm. Also, it will be possible to configure hashing by means of new definitions. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_rx.c | 29 ++++++++-- drivers/net/sfc/base/efx.h | 90 +++++++++++++++++++++++++++++ drivers/net/sfc/base/efx_rx.c | 126 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 236 insertions(+), 9 deletions(-) diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index 86a6ac7..e7dd1ea 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -298,11 +298,32 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); + efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); + efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; efx_rc_t rc; + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH); + if (rss_context == EF10_RSS_CONTEXT_INVALID) { rc = EINVAL; goto fail1; @@ -320,13 +341,13 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, - (type & EFX_RX_HASH_IPV4) ? 1 : 0, + ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, - (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0, + ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, - (type & EFX_RX_HASH_IPV6) ? 1 : 0, + ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0); efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index fd9f059..2b2b09f 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -2068,11 +2068,30 @@ typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_TOEPLITZ } efx_rx_hash_alg_t; +/* + * Legacy hash type flags. + * + * They represent standard tuples for distinct traffic classes. + */ #define EFX_RX_HASH_IPV4 (1U << 0) #define EFX_RX_HASH_TCPIPV4 (1U << 1) #define EFX_RX_HASH_IPV6 (1U << 2) #define EFX_RX_HASH_TCPIPV6 (1U << 3) +#define EFX_RX_HASH_LEGACY_MASK \ + (EFX_RX_HASH_IPV4 | \ + EFX_RX_HASH_TCPIPV4 | \ + EFX_RX_HASH_IPV6 | \ + EFX_RX_HASH_TCPIPV6) + +/* + * The type of the argument used by efx_rx_scale_mode_set() to + * provide a means for the client drivers to configure hashing. + * + * A properly constructed value can either be: + * - a combination of legacy flags + * - a combination of EFX_RX_HASH() flags + */ typedef unsigned int efx_rx_hash_type_t; typedef enum efx_rx_hash_support_e { @@ -2091,6 +2110,77 @@ typedef enum efx_rx_scale_context_type_e { EFX_RX_SCALE_SHARED /* Read-only key/indirection table */ } efx_rx_scale_context_type_t; +/* + * Traffic classes eligible for hash computation. + * + * Select packet headers used in computing the receive hash. + * This uses the same encoding as the RSS_MODES field of + * MC_CMD_RSS_CONTEXT_SET_FLAGS. + */ +#define EFX_RX_CLASS_IPV4_TCP_LBN 8 +#define EFX_RX_CLASS_IPV4_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV4_LBN 16 +#define EFX_RX_CLASS_IPV4_WIDTH 4 +#define EFX_RX_CLASS_IPV6_TCP_LBN 20 +#define EFX_RX_CLASS_IPV6_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV6_LBN 28 +#define EFX_RX_CLASS_IPV6_WIDTH 4 + +#define EFX_RX_NCLASSES 4 + +/* + * Ancillary flags used to construct generic hash tuples. + * This uses the same encoding as RSS_MODE_HASH_SELECTOR. + */ +#define EFX_RX_CLASS_HASH_SRC_ADDR (1U << 0) +#define EFX_RX_CLASS_HASH_DST_ADDR (1U << 1) +#define EFX_RX_CLASS_HASH_SRC_PORT (1U << 2) +#define EFX_RX_CLASS_HASH_DST_PORT (1U << 3) + +/* + * Generic hash tuples. + * + * They express combinations of packet fields + * which can contribute to the hash value for + * a particular traffic class. + */ +#define EFX_RX_CLASS_HASH_DISABLE 0 + +#define EFX_RX_CLASS_HASH_2TUPLE \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_DST_ADDR) + +#define EFX_RX_CLASS_HASH_4TUPLE \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_DST_ADDR | \ + EFX_RX_CLASS_HASH_SRC_PORT | \ + EFX_RX_CLASS_HASH_DST_PORT) + +#define EFX_RX_CLASS_HASH_NTUPLES 3 + +/* + * Hash flag constructor. + * + * Resulting flags encode hash tuples for specific traffic classes. + * The client drivers are encouraged to use these flags to form + * a hash type value. + */ +#define EFX_RX_HASH(_class, _tuple) \ + EFX_INSERT_FIELD_NATIVE32(0, 31, \ + EFX_RX_CLASS_##_class, EFX_RX_CLASS_HASH_##_tuple) + +/* + * The maximum number of EFX_RX_HASH() flags. + */ +#define EFX_RX_HASH_NFLAGS (EFX_RX_NCLASSES * EFX_RX_CLASS_HASH_NTUPLES) + +extern __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp); + extern __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index ae79584..b495c74 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -294,6 +294,61 @@ efx_rx_scatter_enable( #endif /* EFSYS_OPT_RX_SCATTER */ #if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp) +{ + unsigned int *entryp = flags; + efx_rc_t rc; + + if (flags == NULL || nflagsp == NULL) { + rc = EINVAL; + goto fail1; + } + +#define LIST_FLAGS(_entryp, _class, _l4_hashing) \ + do { \ + if (_l4_hashing) \ + *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ + \ + *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + + switch (hash_alg) { + case EFX_RX_HASHALG_TOEPLITZ: + LIST_FLAGS(entryp, IPV4_TCP, B_TRUE); + LIST_FLAGS(entryp, IPV6_TCP, B_TRUE); + LIST_FLAGS(entryp, IPV4, B_FALSE); + LIST_FLAGS(entryp, IPV6, B_FALSE); + break; + + default: + rc = EINVAL; + goto fail2; + } + +#undef LIST_FLAGS + + *nflagsp = (unsigned int)(entryp - flags); + EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS); + + return (0); + +fail2: + EFSYS_PROBE(fail2); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, @@ -425,19 +480,76 @@ efx_rx_scale_mode_set( __in boolean_t insert) { const efx_rx_ops_t *erxop = enp->en_erxop; + unsigned int type_flags[EFX_RX_HASH_NFLAGS]; + unsigned int type_nflags; + efx_rx_hash_type_t type_check; + unsigned int i; efx_rc_t rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + /* + * Legacy flags and modern bits cannot be + * used at the same time in the hash type. + */ + if ((type & EFX_RX_HASH_LEGACY_MASK) && + (type & ~EFX_RX_HASH_LEGACY_MASK)) { + rc = EINVAL; + goto fail1; + } + + /* + * Translate legacy flags to the new representation + * so that chip-specific handlers will consider the + * new flags only. + */ + if (type & EFX_RX_HASH_IPV4) + type |= EFX_RX_HASH(IPV4, 2TUPLE); + + if (type & EFX_RX_HASH_TCPIPV4) + type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE); + + if (type & EFX_RX_HASH_IPV6) + type |= EFX_RX_HASH(IPV6, 2TUPLE); + + if (type & EFX_RX_HASH_TCPIPV6) + type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE); + + type &= ~EFX_RX_HASH_LEGACY_MASK; + type_check = type; + + /* + * Get the list of supported hash flags and sanitise the input. + */ + rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags); + if (rc != 0) + goto fail2; + + for (i = 0; i < type_nflags; ++i) { + if ((type_check & type_flags[i]) == type_flags[i]) + type_check &= ~(type_flags[i]); + } + + if (type_check != 0) { + rc = EINVAL; + goto fail3; + } + if (erxop->erxo_scale_mode_set != NULL) { if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg, type, insert)) != 0) - goto fail1; + 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); @@ -881,6 +993,10 @@ siena_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); + efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); + efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); efx_rc_t rc; if (rss_context != EFX_RSS_CONTEXT_DEFAULT) { @@ -895,12 +1011,12 @@ siena_rx_scale_mode_set( case EFX_RX_HASHALG_TOEPLITZ: EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert, - type & EFX_RX_HASH_IPV4, - type & EFX_RX_HASH_TCPIPV4); + (type & type_ipv4) == type_ipv4, + (type & type_ipv4_tcp) == type_ipv4_tcp); EFX_RX_TOEPLITZ_IPV6_HASH(enp, - type & EFX_RX_HASH_IPV6, - type & EFX_RX_HASH_TCPIPV6, + (type & type_ipv6) == type_ipv6, + (type & type_ipv6_tcp) == type_ipv6_tcp, rc); if (rc != 0) goto fail2; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash 2018-04-06 17:21 ` [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko @ 2018-04-19 16:17 ` Andrew Rybchenko 0 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:17 UTC (permalink / raw) To: dev; +Cc: Ferruh Yigit, Ivan Malov On 04/06/2018 08:21 PM, Andrew Rybchenko wrote: > From: Ivan Malov <ivan.malov@oktetlabs.ru> > > Currently, libefx has no support for additional RSS modes > available with later controllers. In order to support this, > libefx should be able to list available hash configurations. > > This patch provides basic infrastructure for the new interface. > The client drivers will be able to query the list of supported > hash configurations for a particular hash algorithm. Also, it > will be possible to configure hashing by means of new definitions. > > Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> > Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> > --- > drivers/net/sfc/base/ef10_rx.c | 29 ++++++++-- > drivers/net/sfc/base/efx.h | 90 +++++++++++++++++++++++++++++ > drivers/net/sfc/base/efx_rx.c | 126 +++++++++++++++++++++++++++++++++++++++-- > 3 files changed, 236 insertions(+), 9 deletions(-) > > diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c > index 86a6ac7..e7dd1ea 100644 > --- a/drivers/net/sfc/base/ef10_rx.c > +++ b/drivers/net/sfc/base/ef10_rx.c > @@ -298,11 +298,32 @@ efx_mcdi_rss_context_set_flags( > __in uint32_t rss_context, > __in efx_rx_hash_type_t type) > { > + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); Self NACK, will send v2 It breaks clang build because of false positive warning [...] ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 2/7] net/sfc/base: support more RSS hash configurations 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 3/7] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko ` (6 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Modern firmwares on EF10 adapters have support for more traffic classes eligible for hash computation. Also, it has become possible to adjust hashing per individual class and select distinct packet fields which will be able to contribute to the hash value. This patch adds support for the mentioned features. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_nic.c | 6 ++++++ drivers/net/sfc/base/ef10_rx.c | 41 ++++++++++++++++++++++++++++++++++++++-- drivers/net/sfc/base/efx.h | 20 ++++++++++++++++++-- drivers/net/sfc/base/efx_rx.c | 36 +++++++++++++++++++++++++++++------ drivers/net/sfc/base/siena_nic.c | 3 +++ 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index 42c37dd..f0b6039 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1041,6 +1041,12 @@ ef10_get_datapath_caps( } encp->enc_rx_prefix_size = 14; + /* Check if the firmware supports additional RSS modes */ + if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES)) + encp->enc_rx_scale_additional_modes_supported = B_TRUE; + else + encp->enc_rx_scale_additional_modes_supported = B_FALSE; + /* Check if the firmware supports TSO */ if (CAP_FLAGS1(req, TX_TSO)) encp->enc_fw_assisted_tso_enabled = B_TRUE; diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index e7dd1ea..fc9e342 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -298,10 +298,12 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); + efx_rx_hash_type_t modes; efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; @@ -339,7 +341,28 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, rss_context); - MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, + /* + * Create a copy of the original hash type. + * The copy will be used to fill in RSS_MODE bits and + * may be cleared beforehand. The original variable + * and, thus, EN bits will remain unaffected. + */ + modes = type; + + /* + * If the firmware lacks support for additional modes, RSS_MODE + * fields must contain zeros, otherwise the operation will fail. + */ + if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) + modes = 0; + +#define EXTRACT_RSS_MODE(_type, _class) \ + (EFX_EXTRACT_NATIVE(_type, 0, 31, \ + EFX_LOW_BIT(EFX_RX_CLASS_##_class), \ + EFX_HIGH_BIT(EFX_RX_CLASS_##_class)) & \ + EFX_MASK32(EFX_RX_CLASS_##_class)) + + MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, @@ -347,7 +370,21 @@ efx_mcdi_rss_context_set_flags( RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0, + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4), + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6)); + +#undef EXTRACT_RSS_MODE efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 2b2b09f..2088eb0 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1192,6 +1192,7 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; uint32_t enc_rx_scale_max_exclusive_contexts; + boolean_t enc_rx_scale_additional_modes_supported; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; #endif /* EFSYS_OPT_LOOPBACK */ @@ -2119,14 +2120,18 @@ typedef enum efx_rx_scale_context_type_e { */ #define EFX_RX_CLASS_IPV4_TCP_LBN 8 #define EFX_RX_CLASS_IPV4_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV4_UDP_LBN 12 +#define EFX_RX_CLASS_IPV4_UDP_WIDTH 4 #define EFX_RX_CLASS_IPV4_LBN 16 #define EFX_RX_CLASS_IPV4_WIDTH 4 #define EFX_RX_CLASS_IPV6_TCP_LBN 20 #define EFX_RX_CLASS_IPV6_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV6_UDP_LBN 24 +#define EFX_RX_CLASS_IPV6_UDP_WIDTH 4 #define EFX_RX_CLASS_IPV6_LBN 28 #define EFX_RX_CLASS_IPV6_WIDTH 4 -#define EFX_RX_NCLASSES 4 +#define EFX_RX_NCLASSES 6 /* * Ancillary flags used to construct generic hash tuples. @@ -2146,17 +2151,28 @@ typedef enum efx_rx_scale_context_type_e { */ #define EFX_RX_CLASS_HASH_DISABLE 0 +#define EFX_RX_CLASS_HASH_1TUPLE_SRC EFX_RX_CLASS_HASH_SRC_ADDR +#define EFX_RX_CLASS_HASH_1TUPLE_DST EFX_RX_CLASS_HASH_DST_ADDR + #define EFX_RX_CLASS_HASH_2TUPLE \ (EFX_RX_CLASS_HASH_SRC_ADDR | \ EFX_RX_CLASS_HASH_DST_ADDR) +#define EFX_RX_CLASS_HASH_2TUPLE_SRC \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_SRC_PORT) + +#define EFX_RX_CLASS_HASH_2TUPLE_DST \ + (EFX_RX_CLASS_HASH_DST_ADDR | \ + EFX_RX_CLASS_HASH_DST_PORT) + #define EFX_RX_CLASS_HASH_4TUPLE \ (EFX_RX_CLASS_HASH_SRC_ADDR | \ EFX_RX_CLASS_HASH_DST_ADDR | \ EFX_RX_CLASS_HASH_SRC_PORT | \ EFX_RX_CLASS_HASH_DST_PORT) -#define EFX_RX_CLASS_HASH_NTUPLES 3 +#define EFX_RX_CLASS_HASH_NTUPLES 7 /* * Hash flag constructor. diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index b495c74..840a11c 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -301,6 +301,8 @@ efx_rx_scale_hash_flags_get( __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, __out unsigned int *nflagsp) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t additional_modes; unsigned int *entryp = flags; efx_rc_t rc; @@ -309,12 +311,28 @@ efx_rx_scale_hash_flags_get( goto fail1; } -#define LIST_FLAGS(_entryp, _class, _l4_hashing) \ + additional_modes = encp->enc_rx_scale_additional_modes_supported; + +#define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ do { \ - if (_l4_hashing) \ + if (_l4_hashing) { \ *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ \ + if (_additional_modes) { \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_DST); \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_SRC); \ + } \ + } \ + \ *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + \ + if (_additional_modes) { \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST); \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC); \ + } \ + \ *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ \ _NOTE(CONSTANTCONDITION) \ @@ -322,10 +340,16 @@ efx_rx_scale_hash_flags_get( switch (hash_alg) { case EFX_RX_HASHALG_TOEPLITZ: - LIST_FLAGS(entryp, IPV4_TCP, B_TRUE); - LIST_FLAGS(entryp, IPV6_TCP, B_TRUE); - LIST_FLAGS(entryp, IPV4, B_FALSE); - LIST_FLAGS(entryp, IPV6, B_FALSE); + LIST_FLAGS(entryp, IPV4_TCP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, B_TRUE, additional_modes); + + if (additional_modes) { + LIST_FLAGS(entryp, IPV4_UDP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, B_TRUE, additional_modes); + } + + LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); + LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes); break; default: diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index f518a54..55e0951 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -118,6 +118,9 @@ siena_board_cfg( /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; + /* There is no support for additional RSS modes */ + encp->enc_rx_scale_additional_modes_supported = B_FALSE; + encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT); /* Fragments must not span 4k boundaries. */ encp->enc_tx_dma_desc_boundary = 4096; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 3/7] net/sfc/base: honour packed stream RSS restriction 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 2/7] net/sfc/base: support more RSS hash configurations Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 4/7] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko ` (5 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Packed stream firmware variant on EF10 adapters has a number of properties which must be taken into account: - Only one exclusive RSS context is available per port. - Only IP addresses can contribute to the hash value. Huntington and Medford have one more limitation which is important for the drivers capable of packed stream: - Hash algorithm is non-standard (i.e. non-Toeplitz). This implies XORing together source + destination IP addresses (or last four bytes in the case of IPv6) and using the result as the input to a Toeplitz hash. This patch provides a number of improvements in order to treat the mentioned limitations in the common code. If the firmware variant is packed stream, the list of supported hash tuples will include less variants, and the maximum number of RSS contexts will be set to one. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_nic.c | 59 +++++++++++++++++++++++++++++++++++----- drivers/net/sfc/base/ef10_rx.c | 6 ++-- drivers/net/sfc/base/efx.h | 14 +++++++++- drivers/net/sfc/base/efx_rx.c | 17 +++++++++--- drivers/net/sfc/base/siena_nic.c | 9 ++++++ 5 files changed, 91 insertions(+), 14 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index f0b6039..0ad367c 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1233,11 +1233,63 @@ ef10_get_datapath_caps( else encp->enc_fec_counters = B_FALSE; + if (CAP_FLAGS1(req, RX_RSS_LIMITED)) { + /* Only one exclusive RSS context is available per port. */ + encp->enc_rx_scale_max_exclusive_contexts = 1; + + switch (enp->en_family) { + case EFX_FAMILY_MEDFORD2: + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_TOEPLITZ); + break; + + case EFX_FAMILY_MEDFORD: + case EFX_FAMILY_HUNTINGTON: + /* + * Packed stream firmware variant maintains a + * non-standard algorithm for hash computation. + * It implies explicit XORing together + * source + destination IP addresses (or last + * four bytes in the case of IPv6) and using the + * resulting value as the input to a Toeplitz hash. + */ + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_PACKED_STREAM); + break; + + default: + rc = EINVAL; + goto fail5; + } + + /* Port numbers cannot contribute to the hash value */ + encp->enc_rx_scale_l4_hash_supported = B_FALSE; + } else { + /* + * Maximum number of exclusive RSS contexts. + * EF10 hardware supports 64 in total, but 6 are reserved + * for shared contexts. They are a global resource so + * not all may be available. + */ + encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; + + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_TOEPLITZ); + + /* + * It is possible to use port numbers as + * the input data for hash computation. + */ + encp->enc_rx_scale_l4_hash_supported = B_TRUE; + } + #undef CAP_FLAGS1 #undef CAP_FLAGS2 return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -1707,13 +1759,6 @@ ef10_nic_board_cfg( /* Alignment for WPTR updates */ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; - /* - * Maximum number of exclusive RSS contexts. EF10 hardware supports 64 - * in total, but 6 are reserved for shared contexts. They are a global - * resource so not all may be available. - */ - encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; - encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); /* No boundary crossing limits */ encp->enc_tx_dma_desc_boundary = 0; diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index fc9e342..70e451f 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -609,12 +609,13 @@ ef10_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rc_t rc; - EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ); EFSYS_ASSERT3U(insert, ==, B_TRUE); - if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) { + if ((encp->enc_rx_scale_hash_alg_mask & (1U << alg)) == 0 || + insert == B_FALSE) { rc = EINVAL; goto fail1; } @@ -763,6 +764,7 @@ ef10_rx_prefix_hash( _NOTE(ARGUNUSED(enp)) switch (func) { + case EFX_RX_HASHALG_PACKED_STREAM: case EFX_RX_HASHALG_TOEPLITZ: return (buffer[0] | (buffer[1] << 8) | diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 2088eb0..5d2fef7 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1192,6 +1192,16 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; uint32_t enc_rx_scale_max_exclusive_contexts; + /* + * Mask of supported hash algorithms. + * Hash algorithm types are used as the bit indices. + */ + uint32_t enc_rx_scale_hash_alg_mask; + /* + * Indicates whether port numbers can be included to the + * input data for hash computation. + */ + boolean_t enc_rx_scale_l4_hash_supported; boolean_t enc_rx_scale_additional_modes_supported; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; @@ -2066,7 +2076,9 @@ efx_rx_scatter_enable( typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_LFSR = 0, - EFX_RX_HASHALG_TOEPLITZ + EFX_RX_HASHALG_TOEPLITZ, + EFX_RX_HASHALG_PACKED_STREAM, + EFX_RX_NHASHALGS } efx_rx_hash_alg_t; /* diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index 840a11c..d75957f 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -302,6 +302,7 @@ efx_rx_scale_hash_flags_get( __out unsigned int *nflagsp) { efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t l4; boolean_t additional_modes; unsigned int *entryp = flags; efx_rc_t rc; @@ -311,6 +312,7 @@ efx_rx_scale_hash_flags_get( goto fail1; } + l4 = encp->enc_rx_scale_l4_hash_supported; additional_modes = encp->enc_rx_scale_additional_modes_supported; #define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ @@ -339,13 +341,20 @@ efx_rx_scale_hash_flags_get( } while (B_FALSE) switch (hash_alg) { + case EFX_RX_HASHALG_PACKED_STREAM: + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + /* FALLTHRU */ case EFX_RX_HASHALG_TOEPLITZ: - LIST_FLAGS(entryp, IPV4_TCP, B_TRUE, additional_modes); - LIST_FLAGS(entryp, IPV6_TCP, B_TRUE, additional_modes); + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + + LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes); if (additional_modes) { - LIST_FLAGS(entryp, IPV4_UDP, B_TRUE, additional_modes); - LIST_FLAGS(entryp, IPV6_UDP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes); } LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index 55e0951..f0a88a9 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -118,6 +118,15 @@ siena_board_cfg( /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; + encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR); + encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ); + + /* + * It is always possible to use port numbers + * as the input data for hash computation. + */ + encp->enc_rx_scale_l4_hash_supported = B_TRUE; + /* There is no support for additional RSS modes */ encp->enc_rx_scale_additional_modes_supported = B_FALSE; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 4/7] net/sfc: process RSS settings on Rx configure step 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko ` (2 preceding siblings ...) 2018-04-06 17:21 ` [dpdk-dev] [PATCH 3/7] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 5/7] net/sfc: remove conditional compilation for RSS Andrew Rybchenko ` (4 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov, stable From: Ivan Malov <ivan.malov@oktetlabs.ru> One may submit advanced RSS settings as part of rte_eth_conf to customise RSS configuration from the very beginning. Currently the driver does not check that piece of settings and proceeds with default choices for RSS hash functions and RSS key. This patch implements the required processing. Fixes: 4ec1fc3ba881 ("net/sfc: add basic stubs for RSS support on driver attach") Cc: stable@dpdk.org Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc_rx.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 734ce24..fca3931 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -1189,6 +1189,41 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) #if EFSYS_OPT_RX_SCALE static int +sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, + struct rte_eth_rss_conf *conf) +{ + efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types; + + if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || + conf->rss_key != NULL) + return EINVAL; + } + + if (conf->rss_hf != 0) { + if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { + sfc_err(sa, "unsupported hash functions requested"); + return EINVAL; + } + + efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf); + } + + if (conf->rss_key != NULL) { + if (conf->rss_key_len != sizeof(sa->rss_key)) { + sfc_err(sa, "RSS key size is wrong (should be %lu)", + sizeof(sa->rss_key)); + return EINVAL; + } + rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key)); + } + + sa->rss_hash_types = efx_hash_types; + + return 0; +} + +static int sfc_rx_rss_config(struct sfc_adapter *sa) { int rc = 0; @@ -1416,16 +1451,23 @@ sfc_rx_configure(struct sfc_adapter *sa) MIN(sa->rxq_count, EFX_MAXRSS) : 0; if (sa->rss_channels > 0) { + struct rte_eth_rss_conf *adv_conf_rss; unsigned int sw_index; for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index) sa->rss_tbl[sw_index] = sw_index % sa->rss_channels; + + adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf; + rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss); + if (rc != 0) + goto fail_rx_process_adv_conf_rss; } #endif done: return 0; +fail_rx_process_adv_conf_rss: fail_rx_qinit_info: fail_rxqs_realloc: fail_rxqs_alloc: -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 5/7] net/sfc: remove conditional compilation for RSS 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko ` (3 preceding siblings ...) 2018-04-06 17:21 ` [dpdk-dev] [PATCH 4/7] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 6/7] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko ` (3 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> RSS is one of the most valuable features in the driver, and one would hardly need to disable it at build time. This patch withdraws unnecessary conditionals for RSS snippets. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 10 ---------- drivers/net/sfc/sfc.h | 4 ---- drivers/net/sfc/sfc_ethdev.c | 6 ------ drivers/net/sfc/sfc_flow.c | 10 ---------- drivers/net/sfc/sfc_flow.h | 4 ---- drivers/net/sfc/sfc_rx.c | 25 ------------------------- drivers/net/sfc/sfc_rx.h | 2 -- 7 files changed, 61 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index e456bca..a43b0b4 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -563,7 +563,6 @@ sfc_mem_bar_fini(struct sfc_adapter *sa) memset(ebp, 0, sizeof(*ebp)); } -#if EFSYS_OPT_RX_SCALE /* * A fixed RSS key which has a property of being symmetric * (symmetrical flows are distributed to the same CPU) @@ -577,9 +576,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, }; -#endif -#if EFSYS_OPT_RX_SCALE static int sfc_set_rss_defaults(struct sfc_adapter *sa) { @@ -626,13 +623,6 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) fail_intr_init: return rc; } -#else -static int -sfc_set_rss_defaults(__rte_unused struct sfc_adapter *sa) -{ - return 0; -} -#endif int sfc_attach(struct sfc_adapter *sa) diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 65a4df2..805f211 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,10 +27,8 @@ extern "C" { #endif -#if EFSYS_OPT_RX_SCALE /** RSS hash offloads mask */ #define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP) -#endif /* * +---------------+ @@ -227,13 +225,11 @@ struct sfc_adapter { unsigned int rss_channels; -#if EFSYS_OPT_RX_SCALE efx_rx_scale_context_type_t rss_support; efx_rx_hash_support_t hash_support; efx_rx_hash_type_t rss_hash_types; unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; uint8_t rss_key[EFX_RSS_KEY_SIZE]; -#endif /* * Shared memory copy of the Rx datapath name to be used by diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 2af898e..4f26f60 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -152,13 +152,11 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; -#if EFSYS_OPT_RX_SCALE if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) { dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; } -#endif /* Initialize to hardware limits */ dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS; @@ -1347,7 +1345,6 @@ sfc_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, return sfc_dev_udp_tunnel_op(dev, tunnel_udp, SFC_UDP_TUNNEL_DEL_PORT); } -#if EFSYS_OPT_RX_SCALE static int sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) @@ -1558,7 +1555,6 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, SFC_ASSERT(rc >= 0); return -rc; } -#endif static int sfc_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, @@ -1653,12 +1649,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .mac_addr_set = sfc_mac_addr_set, .udp_tunnel_port_add = sfc_dev_udp_tunnel_port_add, .udp_tunnel_port_del = sfc_dev_udp_tunnel_port_del, -#if EFSYS_OPT_RX_SCALE .reta_update = sfc_dev_rss_reta_update, .reta_query = sfc_dev_rss_reta_query, .rss_hash_update = sfc_dev_rss_hash_update, .rss_hash_conf_get = sfc_dev_rss_hash_conf_get, -#endif .filter_ctrl = sfc_dev_filter_ctrl, .set_mc_addr_list = sfc_set_mc_addr_list, .rxq_info_get = sfc_rx_queue_info_get, diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index b12a472..6f92086 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1258,7 +1258,6 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, return 0; } -#if EFSYS_OPT_RX_SCALE static int sfc_flow_parse_rss(struct sfc_adapter *sa, const struct rte_flow_action_rss *rss, @@ -1329,7 +1328,6 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, return 0; } -#endif /* EFSYS_OPT_RX_SCALE */ static int sfc_flow_spec_flush(struct sfc_adapter *sa, struct sfc_flow_spec *spec, @@ -1379,7 +1377,6 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { -#if EFSYS_OPT_RX_SCALE struct sfc_flow_rss *rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; @@ -1456,9 +1453,6 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, fail_scale_context_alloc: return rc; -#else /* !EFSYS_OPT_RX_SCALE */ - return sfc_flow_spec_insert(sa, &flow->spec); -#endif /* EFSYS_OPT_RX_SCALE */ } static int @@ -1471,7 +1465,6 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, if (rc != 0) return rc; -#if EFSYS_OPT_RX_SCALE if (flow->rss) { /* * All specifications for a given flow rule have the same RSS @@ -1482,7 +1475,6 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context); } -#endif /* EFSYS_OPT_RX_SCALE */ return rc; } @@ -1529,7 +1521,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, is_specified = B_TRUE; break; -#if EFSYS_OPT_RX_SCALE case RTE_FLOW_ACTION_TYPE_RSS: rc = sfc_flow_parse_rss(sa, actions->conf, flow); if (rc != 0) { @@ -1541,7 +1532,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, is_specified = B_TRUE; break; -#endif /* EFSYS_OPT_RX_SCALE */ case RTE_FLOW_ACTION_TYPE_DROP: flow->spec.template.efs_dmaq_id = diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index 69dd683..71ec18c 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -26,7 +26,6 @@ extern "C" { */ #define SF_FLOW_SPEC_NB_FILTERS_MAX 8 -#if EFSYS_OPT_RX_SCALE /* RSS configuration storage */ struct sfc_flow_rss { unsigned int rxq_hw_index_min; @@ -35,7 +34,6 @@ struct sfc_flow_rss { uint8_t rss_key[EFX_RSS_KEY_SIZE]; unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; }; -#endif /* EFSYS_OPT_RX_SCALE */ /* Filter specification storage */ struct sfc_flow_spec { @@ -50,10 +48,8 @@ struct sfc_flow_spec { /* PMD-specific definition of the opaque type from rte_flow.h */ struct rte_flow { struct sfc_flow_spec spec; /* flow spec for hardware filter(s) */ -#if EFSYS_OPT_RX_SCALE boolean_t rss; /* RSS toggle */ struct sfc_flow_rss rss_conf; /* RSS configuration */ -#endif /* EFSYS_OPT_RX_SCALE */ TAILQ_ENTRY(rte_flow) entries; /* flow list entries */ }; diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index fca3931..c30f230 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -184,7 +184,6 @@ sfc_efx_supported_ptypes_get(__rte_unused uint32_t tunnel_encaps) return ptypes; } -#if EFSYS_OPT_RX_SCALE static void sfc_efx_rx_set_rss_hash(struct sfc_efx_rxq *rxq, unsigned int flags, struct rte_mbuf *m) @@ -205,14 +204,6 @@ sfc_efx_rx_set_rss_hash(struct sfc_efx_rxq *rxq, unsigned int flags, m->ol_flags |= PKT_RX_RSS_HASH; } } -#else -static void -sfc_efx_rx_set_rss_hash(__rte_unused struct sfc_efx_rxq *rxq, - __rte_unused unsigned int flags, - __rte_unused struct rte_mbuf *m) -{ -} -#endif static uint16_t sfc_efx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) @@ -1068,10 +1059,8 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; -#if EFSYS_OPT_RX_SCALE if (sa->hash_support == EFX_RX_HASH_AVAILABLE && sa->rss_channels > 0) info.flags |= SFC_RXQ_FLAG_RSS_HASH; -#endif info.rxq_entries = rxq_info->entries; info.rxq_hw_ring = rxq->mem.esm_base; @@ -1141,7 +1130,6 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rte_free(rxq); } -#if EFSYS_OPT_RX_SCALE efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf) { @@ -1185,9 +1173,7 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) return rss_hf; } -#endif -#if EFSYS_OPT_RX_SCALE static int sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, struct rte_eth_rss_conf *conf) @@ -1248,13 +1234,6 @@ sfc_rx_rss_config(struct sfc_adapter *sa) finish: return rc; } -#else -static int -sfc_rx_rss_config(__rte_unused struct sfc_adapter *sa) -{ - return 0; -} -#endif int sfc_rx_start(struct sfc_adapter *sa) @@ -1337,14 +1316,12 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) case ETH_MQ_RX_NONE: /* No special checks are required */ break; -#if EFSYS_OPT_RX_SCALE case ETH_MQ_RX_RSS: if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) { sfc_err(sa, "RSS is not available"); rc = EINVAL; } break; -#endif default: sfc_err(sa, "Rx multi-queue mode %u not supported", rxmode->mq_mode); @@ -1446,7 +1423,6 @@ sfc_rx_configure(struct sfc_adapter *sa) sa->rxq_count++; } -#if EFSYS_OPT_RX_SCALE sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? MIN(sa->rxq_count, EFX_MAXRSS) : 0; @@ -1462,7 +1438,6 @@ sfc_rx_configure(struct sfc_adapter *sa) if (rc != 0) goto fail_rx_process_adv_conf_rss; } -#endif done: return 0; diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h index 6706ee6..ea911be 100644 --- a/drivers/net/sfc/sfc_rx.h +++ b/drivers/net/sfc/sfc_rx.h @@ -152,10 +152,8 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index); int sfc_rx_qdesc_done(struct sfc_dp_rxq *dp_rxq, unsigned int offset); -#if EFSYS_OPT_RX_SCALE efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf); uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types); -#endif #ifdef __cplusplus } -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 6/7] net/sfc: factor out RSS fields from adapter info 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko ` (4 preceding siblings ...) 2018-04-06 17:21 ` [dpdk-dev] [PATCH 5/7] net/sfc: remove conditional compilation for RSS Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 7/7] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko ` (2 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> RSS handling will need more sophisticated fields in the adapter context storage in future patches. This patch groups existing fields in a dedicated structure and updates the rest of the code. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 9 ++++---- drivers/net/sfc/sfc.h | 17 ++++++++------- drivers/net/sfc/sfc_ethdev.c | 49 ++++++++++++++++++++++++------------------- drivers/net/sfc/sfc_flow.c | 50 +++++++++++++++++++++++++------------------- drivers/net/sfc/sfc_rx.c | 47 +++++++++++++++++++++++------------------ 5 files changed, 97 insertions(+), 75 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index a43b0b4..360df33 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -580,6 +580,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { static int sfc_set_rss_defaults(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; int rc; rc = efx_intr_init(sa->nic, sa->intr.type, NULL); @@ -594,11 +595,11 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) if (rc != 0) goto fail_rx_init; - rc = efx_rx_scale_default_support_get(sa->nic, &sa->rss_support); + rc = efx_rx_scale_default_support_get(sa->nic, &rss->context_type); if (rc != 0) goto fail_scale_support_get; - rc = efx_rx_hash_default_support_get(sa->nic, &sa->hash_support); + rc = efx_rx_hash_default_support_get(sa->nic, &rss->hash_support); if (rc != 0) goto fail_hash_support_get; @@ -606,9 +607,9 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) efx_ev_fini(sa->nic); efx_intr_fini(sa->nic); - sa->rss_hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); + rss->hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); - rte_memcpy(sa->rss_key, default_rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); return 0; diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 805f211..9c76d7f 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -154,6 +154,15 @@ struct sfc_port { uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; }; +struct sfc_rss { + unsigned int channels; + efx_rx_scale_context_type_t context_type; + efx_rx_hash_support_t hash_support; + efx_rx_hash_type_t hash_types; + unsigned int tbl[EFX_RSS_TBL_SIZE]; + uint8_t key[EFX_RSS_KEY_SIZE]; +}; + /* Adapter private data */ struct sfc_adapter { /* @@ -223,13 +232,7 @@ struct sfc_adapter { boolean_t tso; - unsigned int rss_channels; - - efx_rx_scale_context_type_t rss_support; - efx_rx_hash_support_t hash_support; - efx_rx_hash_type_t rss_hash_types; - unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; - uint8_t rss_key[EFX_RSS_KEY_SIZE]; + struct sfc_rss rss; /* * Shared memory copy of the Rx datapath name to be used by diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 4f26f60..4cefb73 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -85,6 +85,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct sfc_adapter *sa = dev->data->dev_private; const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_rss *rss = &sa->rss; uint64_t txq_offloads_def = 0; sfc_log_init(sa, "entry"); @@ -152,7 +153,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; - if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) { + if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; @@ -1350,12 +1351,13 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; - if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated) + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated) return -ENOTSUP; - if (sa->rss_channels == 0) + if (rss->channels == 0) return -EINVAL; sfc_adapter_lock(sa); @@ -1366,10 +1368,10 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, * flags which corresponds to the active EFX configuration stored * locally in 'sfc_adapter' and kept up-to-date */ - rss_conf->rss_hf = sfc_efx_to_rte_hash_type(sa->rss_hash_types); + rss_conf->rss_hf = sfc_efx_to_rte_hash_type(rss->hash_types); rss_conf->rss_key_len = EFX_RSS_KEY_SIZE; if (rss_conf->rss_key != NULL) - rte_memcpy(rss_conf->rss_key, sa->rss_key, EFX_RSS_KEY_SIZE); + rte_memcpy(rss_conf->rss_key, rss->key, EFX_RSS_KEY_SIZE); sfc_adapter_unlock(sa); @@ -1381,6 +1383,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; unsigned int efx_hash_types; int rc = 0; @@ -1388,20 +1391,20 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, if (port->isolated) return -ENOTSUP; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { sfc_err(sa, "RSS is not available"); return -ENOTSUP; } - if (sa->rss_channels == 0) { + if (rss->channels == 0) { sfc_err(sa, "RSS is not configured"); return -EINVAL; } if ((rss_conf->rss_key != NULL) && - (rss_conf->rss_key_len != sizeof(sa->rss_key))) { + (rss_conf->rss_key_len != sizeof(rss->key))) { sfc_err(sa, "RSS key size is wrong (should be %lu)", - sizeof(sa->rss_key)); + sizeof(rss->key)); return -EINVAL; } @@ -1425,15 +1428,15 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, rc = efx_rx_scale_key_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, rss_conf->rss_key, - sizeof(sa->rss_key)); + sizeof(rss->key)); if (rc != 0) goto fail_scale_key_set; } - rte_memcpy(sa->rss_key, rss_conf->rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, rss_conf->rss_key, sizeof(rss->key)); } - sa->rss_hash_types = efx_hash_types; + rss->hash_types = efx_hash_types; sfc_adapter_unlock(sa); @@ -1442,7 +1445,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, fail_scale_key_set: if (efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, EFX_RX_HASHALG_TOEPLITZ, - sa->rss_hash_types, B_TRUE) != 0) + rss->hash_types, B_TRUE) != 0) sfc_err(sa, "failed to restore RSS mode"); fail_scale_mode_set: @@ -1456,13 +1459,14 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, uint16_t reta_size) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; int entry; - if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated) + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated) return -ENOTSUP; - if (sa->rss_channels == 0) + if (rss->channels == 0) return -EINVAL; if (reta_size != EFX_RSS_TBL_SIZE) @@ -1475,7 +1479,7 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, int grp_idx = entry % RTE_RETA_GROUP_SIZE; if ((reta_conf[grp].mask >> grp_idx) & 1) - reta_conf[grp].reta[grp_idx] = sa->rss_tbl[entry]; + reta_conf[grp].reta[grp_idx] = rss->tbl[entry]; } sfc_adapter_unlock(sa); @@ -1489,6 +1493,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, uint16_t reta_size) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; unsigned int *rss_tbl_new; uint16_t entry; @@ -1498,12 +1503,12 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, if (port->isolated) return -ENOTSUP; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { sfc_err(sa, "RSS is not available"); return -ENOTSUP; } - if (sa->rss_channels == 0) { + if (rss->channels == 0) { sfc_err(sa, "RSS is not configured"); return -EINVAL; } @@ -1514,13 +1519,13 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, return -EINVAL; } - rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(sa->rss_tbl), 0); + rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(rss->tbl), 0); if (rss_tbl_new == NULL) return -ENOMEM; sfc_adapter_lock(sa); - rte_memcpy(rss_tbl_new, sa->rss_tbl, sizeof(sa->rss_tbl)); + rte_memcpy(rss_tbl_new, rss->tbl, sizeof(rss->tbl)); for (entry = 0; entry < reta_size; entry++) { int grp_idx = entry % RTE_RETA_GROUP_SIZE; @@ -1529,7 +1534,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, grp = &reta_conf[entry / RTE_RETA_GROUP_SIZE]; if (grp->mask & (1ull << grp_idx)) { - if (grp->reta[grp_idx] >= sa->rss_channels) { + if (grp->reta[grp_idx] >= rss->channels) { rc = EINVAL; goto bad_reta_entry; } @@ -1544,7 +1549,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, goto fail_scale_tbl_set; } - rte_memcpy(sa->rss_tbl, rss_tbl_new, sizeof(sa->rss_tbl)); + rte_memcpy(rss->tbl, rss_tbl_new, sizeof(rss->tbl)); fail_scale_tbl_set: bad_reta_entry: diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 6f92086..f89f1de 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1260,18 +1260,20 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, static int sfc_flow_parse_rss(struct sfc_adapter *sa, - const struct rte_flow_action_rss *rss, + const struct rte_flow_action_rss *action_rss, struct rte_flow *flow) { + struct sfc_rss *rss = &sa->rss; unsigned int rxq_sw_index; struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; unsigned int rxq_hw_index_max; + uint64_t rss_hf; const uint8_t *rss_key; struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf; unsigned int i; - if (rss->queue_num == 0) + if (action_rss->queue_num == 0) return -EINVAL; rxq_sw_index = sa->rxq_count - 1; @@ -1279,8 +1281,8 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, rxq_hw_index_min = rxq->hw_index; rxq_hw_index_max = 0; - for (i = 0; i < rss->queue_num; ++i) { - rxq_sw_index = rss->queue[i]; + for (i = 0; i < action_rss->queue_num; ++i) { + rxq_sw_index = action_rss->queue[i]; if (rxq_sw_index >= sa->rxq_count) return -EINVAL; @@ -1294,33 +1296,35 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, rxq_hw_index_max = rxq->hw_index; } - if (rss->func) + if (action_rss->func) return -EINVAL; - if (rss->level) + if (action_rss->level) return -EINVAL; - if ((rss->types & ~SFC_RSS_OFFLOADS) != 0) + rss_hf = rss_action->types + if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0) return -EINVAL; - if (rss->key_len) { - if (rss->key_len != sizeof(sa->rss_key)) + if (action_rss->key_len) { + if (action_rss->key_len != sizeof(rss->key)) return -EINVAL; - rss_key = rss->key; + rss_key = action_rss->key; } else { - rss_key = sa->rss_key; + rss_key = rss->key; } flow->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 = sfc_rte_to_efx_hash_type(rss->types); - rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key)); + sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf); + 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 rxq_sw_index = rss->queue[i % rss->queue_num]; + unsigned int nb_queues = action_rss->queue_num; + unsigned int rxq_sw_index = action_rss->queue[i % nb_queues]; struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq; sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min; @@ -1377,14 +1381,15 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { - struct sfc_flow_rss *rss = &flow->rss_conf; + struct sfc_rss *rss = &sa->rss; + struct sfc_flow_rss *flow_rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; int rc = 0; if (flow->rss) { - unsigned int rss_spread = MIN(rss->rxq_hw_index_max - - rss->rxq_hw_index_min + 1, + unsigned int rss_spread = MIN(flow_rss->rxq_hw_index_max - + flow_rss->rxq_hw_index_min + 1, EFX_MAXRSS); rc = efx_rx_scale_context_alloc(sa->nic, @@ -1396,13 +1401,13 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, EFX_RX_HASHALG_TOEPLITZ, - rss->rss_hash_types, B_TRUE); + flow_rss->rss_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; rc = efx_rx_scale_key_set(sa->nic, efs_rss_context, - rss->rss_key, - sizeof(sa->rss_key)); + flow_rss->rss_key, + sizeof(rss->key)); if (rc != 0) goto fail_scale_key_set; @@ -1416,7 +1421,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, efx_filter_spec_t *spec = &flow->spec.filters[i]; spec->efs_rss_context = efs_rss_context; - spec->efs_dmaq_id = rss->rxq_hw_index_min; + spec->efs_dmaq_id = flow_rss->rxq_hw_index_min; spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS; } } @@ -1435,7 +1440,8 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, * the table entries, and the operation will succeed */ rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context, - rss->rss_tbl, RTE_DIM(rss->rss_tbl)); + flow_rss->rss_tbl, + RTE_DIM(flow_rss->rss_tbl)); if (rc != 0) goto fail_scale_tbl_set; } diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index c30f230..816436a 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -608,7 +608,8 @@ sfc_rx_qflush(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_default_rxq_set_filter(struct sfc_adapter *sa, struct sfc_rxq *rxq) { - boolean_t rss = (sa->rss_channels > 0) ? B_TRUE : B_FALSE; + struct sfc_rss *rss = &sa->rss; + boolean_t need_rss = (rss->channels > 0) ? B_TRUE : B_FALSE; struct sfc_port *port = &sa->port; int rc; @@ -620,7 +621,7 @@ sfc_rx_default_rxq_set_filter(struct sfc_adapter *sa, struct sfc_rxq *rxq) * repeat this step without promiscuous and all-multicast flags set */ retry: - rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common, rss); + rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common, need_rss); if (rc == 0) return 0; else if (rc != EOPNOTSUPP) @@ -970,6 +971,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, struct rte_mempool *mb_pool) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_rss *rss = &sa->rss; int rc; unsigned int rxq_entries; unsigned int evq_entries; @@ -1059,7 +1061,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; - if (sa->hash_support == EFX_RX_HASH_AVAILABLE && sa->rss_channels > 0) + if (rss->hash_support == EFX_RX_HASH_AVAILABLE && rss->channels > 0) info.flags |= SFC_RXQ_FLAG_RSS_HASH; info.rxq_entries = rxq_info->entries; @@ -1178,9 +1180,10 @@ static int sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, struct rte_eth_rss_conf *conf) { - efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types; + struct sfc_rss *rss = &sa->rss; + efx_rx_hash_type_t efx_hash_types = rss->hash_types; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || conf->rss_key != NULL) return EINVAL; @@ -1196,15 +1199,15 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, } if (conf->rss_key != NULL) { - if (conf->rss_key_len != sizeof(sa->rss_key)) { + if (conf->rss_key_len != sizeof(rss->key)) { sfc_err(sa, "RSS key size is wrong (should be %lu)", - sizeof(sa->rss_key)); + sizeof(rss->key)); return EINVAL; } - rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, conf->rss_key, sizeof(rss->key)); } - sa->rss_hash_types = efx_hash_types; + rss->hash_types = efx_hash_types; return 0; } @@ -1212,23 +1215,23 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, static int sfc_rx_rss_config(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; int rc = 0; - if (sa->rss_channels > 0) { + if (rss->channels > 0) { rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, EFX_RX_HASHALG_TOEPLITZ, - sa->rss_hash_types, B_TRUE); + rss->hash_types, B_TRUE); if (rc != 0) goto finish; rc = efx_rx_scale_key_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - sa->rss_key, - sizeof(sa->rss_key)); + rss->key, sizeof(rss->key)); if (rc != 0) goto finish; rc = efx_rx_scale_tbl_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - sa->rss_tbl, RTE_DIM(sa->rss_tbl)); + rss->tbl, RTE_DIM(rss->tbl)); } finish: @@ -1307,6 +1310,7 @@ sfc_rx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) { + struct sfc_rss *rss = &sa->rss; uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) | sfc_rx_get_queue_offload_caps(sa); uint64_t offloads_rejected = rxmode->offloads & ~offloads_supported; @@ -1317,7 +1321,7 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) /* No special checks are required */ break; case ETH_MQ_RX_RSS: - if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) { + if (rss->context_type == EFX_RX_SCALE_UNAVAILABLE) { sfc_err(sa, "RSS is not available"); rc = EINVAL; } @@ -1374,6 +1378,7 @@ sfc_rx_fini_queues(struct sfc_adapter *sa, unsigned int nb_rx_queues) int sfc_rx_configure(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf; const unsigned int nb_rx_queues = sa->eth_dev->data->nb_rx_queues; int rc; @@ -1423,15 +1428,15 @@ sfc_rx_configure(struct sfc_adapter *sa) sa->rxq_count++; } - sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? - MIN(sa->rxq_count, EFX_MAXRSS) : 0; + rss->channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? + MIN(sa->rxq_count, EFX_MAXRSS) : 0; - if (sa->rss_channels > 0) { + if (rss->channels > 0) { struct rte_eth_rss_conf *adv_conf_rss; unsigned int sw_index; for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index) - sa->rss_tbl[sw_index] = sw_index % sa->rss_channels; + rss->tbl[sw_index] = sw_index % rss->channels; adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf; rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss); @@ -1461,9 +1466,11 @@ sfc_rx_configure(struct sfc_adapter *sa) void sfc_rx_close(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; + sfc_rx_fini_queues(sa, 0); - sa->rss_channels = 0; + rss->channels = 0; rte_free(sa->rxq_info); sa->rxq_info = NULL; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH 7/7] net/sfc: convert to the advanced EFX RSS interface 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko ` (5 preceding siblings ...) 2018-04-06 17:21 ` [dpdk-dev] [PATCH 6/7] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko @ 2018-04-06 17:21 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-06 17:21 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> The current code has the following drawbacks: - It is assumed that TCP 4-tuple hash is always supported, which is untrue in the case of packed stream FW variant. - The driver is unaware of UDP hash support available with latest firmware. In order to cope with the mentioned issues, this patch implements the new approach to handle hash settings using the advanced EFX RSS interface. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 24 ++++-- drivers/net/sfc/sfc.h | 12 ++- drivers/net/sfc/sfc_ethdev.c | 23 +++--- drivers/net/sfc/sfc_flow.c | 23 ++++-- drivers/net/sfc/sfc_rx.c | 191 ++++++++++++++++++++++++++++++++++--------- drivers/net/sfc/sfc_rx.h | 8 +- 6 files changed, 217 insertions(+), 64 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 360df33..70ec3d4 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -578,7 +578,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { }; static int -sfc_set_rss_defaults(struct sfc_adapter *sa) +sfc_rss_attach(struct sfc_adapter *sa) { struct sfc_rss *rss = &sa->rss; int rc; @@ -603,16 +603,19 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) if (rc != 0) goto fail_hash_support_get; + rc = sfc_rx_hash_init(sa); + if (rc != 0) + goto fail_rx_hash_init; + efx_rx_fini(sa->nic); efx_ev_fini(sa->nic); efx_intr_fini(sa->nic); - rss->hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); - rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); return 0; +fail_rx_hash_init: fail_hash_support_get: fail_scale_support_get: fail_rx_init: @@ -625,6 +628,12 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) return rc; } +static void +sfc_rss_detach(struct sfc_adapter *sa) +{ + sfc_rx_hash_fini(sa); +} + int sfc_attach(struct sfc_adapter *sa) { @@ -682,9 +691,9 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_port_attach; - rc = sfc_set_rss_defaults(sa); + rc = sfc_rss_attach(sa); if (rc != 0) - goto fail_set_rss_defaults; + goto fail_rss_attach; rc = sfc_filter_attach(sa); if (rc != 0) @@ -701,7 +710,9 @@ sfc_attach(struct sfc_adapter *sa) return 0; fail_filter_attach: -fail_set_rss_defaults: + sfc_rss_detach(sa); + +fail_rss_attach: sfc_port_detach(sa); fail_port_attach: @@ -733,6 +744,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_flow_fini(sa); sfc_filter_detach(sa); + sfc_rss_detach(sa); sfc_port_detach(sa); sfc_ev_detach(sa); sfc_intr_detach(sa); diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 9c76d7f..3a5f6dc 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,9 +27,6 @@ extern "C" { #endif -/** RSS hash offloads mask */ -#define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP) - /* * +---------------+ * | UNINITIALIZED |<-----------+ @@ -154,10 +151,19 @@ struct sfc_port { uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; }; +struct sfc_rss_hf_rte_to_efx { + uint64_t rte; + efx_rx_hash_type_t efx; +}; + struct sfc_rss { unsigned int channels; efx_rx_scale_context_type_t context_type; efx_rx_hash_support_t hash_support; + efx_rx_hash_alg_t hash_alg; + unsigned int hf_map_nb_entries; + struct sfc_rss_hf_rte_to_efx *hf_map; + efx_rx_hash_type_t hash_types; unsigned int tbl[EFX_RSS_TBL_SIZE]; uint8_t key[EFX_RSS_KEY_SIZE]; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 4cefb73..73be4bd 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -154,9 +154,15 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { + uint64_t rte_hf = 0; + unsigned int i; + + for (i = 0; i < rss->hf_map_nb_entries; ++i) + rte_hf |= rss->hf_map[i].rte; + dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; - dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; + dev_info->flow_type_rss_offloads = rte_hf; } /* Initialize to hardware limits */ @@ -1368,7 +1374,7 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, * flags which corresponds to the active EFX configuration stored * locally in 'sfc_adapter' and kept up-to-date */ - rss_conf->rss_hf = sfc_efx_to_rte_hash_type(rss->hash_types); + rss_conf->rss_hf = sfc_rx_hf_efx_to_rte(sa, rss->hash_types); rss_conf->rss_key_len = EFX_RSS_KEY_SIZE; if (rss_conf->rss_key != NULL) rte_memcpy(rss_conf->rss_key, rss->key, EFX_RSS_KEY_SIZE); @@ -1408,18 +1414,14 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, return -EINVAL; } - if ((rss_conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { - sfc_err(sa, "unsupported hash functions requested"); - return -EINVAL; - } - sfc_adapter_lock(sa); - efx_hash_types = sfc_rte_to_efx_hash_type(rss_conf->rss_hf); + rc = sfc_rx_hf_rte_to_efx(sa, rss_conf->rss_hf, &efx_hash_types); + if (rc != 0) + goto fail_rx_hf_rte_to_efx; rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - EFX_RX_HASHALG_TOEPLITZ, - efx_hash_types, B_TRUE); + rss->hash_alg, efx_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; @@ -1449,6 +1451,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, sfc_err(sa, "failed to restore RSS mode"); fail_scale_mode_set: +fail_rx_hf_rte_to_efx: sfc_adapter_unlock(sa); return -rc; } diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index f89f1de..7ea88e8 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1268,7 +1268,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; unsigned int rxq_hw_index_max; - uint64_t rss_hf; + efx_rx_hash_type_t efx_hash_types; const uint8_t *rss_key; struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf; unsigned int i; @@ -1302,9 +1302,20 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, if (action_rss->level) return -EINVAL; - rss_hf = rss_action->types - if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0) - return -EINVAL; + 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)) @@ -1319,7 +1330,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, 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 = sfc_rte_to_efx_hash_type(rss_hf); + 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) { @@ -1400,7 +1411,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, goto fail_scale_context_alloc; rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, - EFX_RX_HASHALG_TOEPLITZ, + rss->hash_alg, flow_rss->rss_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 816436a..a4aae1b 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -1132,48 +1132,166 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rte_free(rxq); } -efx_rx_hash_type_t -sfc_rte_to_efx_hash_type(uint64_t rss_hf) +/* + * Mapping between RTE RSS hash functions and their EFX counterparts. + */ +struct sfc_rss_hf_rte_to_efx sfc_rss_hf_map[] = { + { ETH_RSS_NONFRAG_IPV4_TCP, + EFX_RX_HASH(IPV4_TCP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV4_UDP, + EFX_RX_HASH(IPV4_UDP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX, + EFX_RX_HASH(IPV6_TCP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_IPV6_UDP_EX, + EFX_RX_HASH(IPV6_UDP, 4TUPLE) }, + { ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_OTHER, + EFX_RX_HASH(IPV4_TCP, 2TUPLE) | EFX_RX_HASH(IPV4_UDP, 2TUPLE) | + EFX_RX_HASH(IPV4, 2TUPLE) }, + { ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | ETH_RSS_NONFRAG_IPV6_OTHER | + ETH_RSS_IPV6_EX, + EFX_RX_HASH(IPV6_TCP, 2TUPLE) | EFX_RX_HASH(IPV6_UDP, 2TUPLE) | + EFX_RX_HASH(IPV6, 2TUPLE) } +}; + +static efx_rx_hash_type_t +sfc_rx_hash_types_mask_supp(efx_rx_hash_type_t hash_type, + unsigned int *hash_type_flags_supported, + unsigned int nb_hash_type_flags_supported) { - efx_rx_hash_type_t efx_hash_types = 0; + efx_rx_hash_type_t hash_type_masked = 0; + unsigned int i, j; + + for (i = 0; i < nb_hash_type_flags_supported; ++i) { + unsigned int class_tuple_lbn[] = { + EFX_RX_CLASS_IPV4_TCP_LBN, + EFX_RX_CLASS_IPV4_UDP_LBN, + EFX_RX_CLASS_IPV4_LBN, + EFX_RX_CLASS_IPV6_TCP_LBN, + EFX_RX_CLASS_IPV6_UDP_LBN, + EFX_RX_CLASS_IPV6_LBN + }; + + for (j = 0; j < RTE_DIM(class_tuple_lbn); ++j) { + unsigned int tuple_mask = EFX_RX_CLASS_HASH_4TUPLE; + unsigned int flag; + + tuple_mask <<= class_tuple_lbn[j]; + flag = hash_type & tuple_mask; + + if (flag == hash_type_flags_supported[i]) + hash_type_masked |= flag; + } + } + + return hash_type_masked; +} + +int +sfc_rx_hash_init(struct sfc_adapter *sa) +{ + struct sfc_rss *rss = &sa->rss; + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + uint32_t alg_mask = encp->enc_rx_scale_hash_alg_mask; + efx_rx_hash_alg_t alg; + unsigned int flags_supp[EFX_RX_HASH_NFLAGS]; + unsigned int nb_flags_supp; + struct sfc_rss_hf_rte_to_efx *hf_map; + struct sfc_rss_hf_rte_to_efx *entry; + efx_rx_hash_type_t efx_hash_types; + unsigned int i; + int rc; - if ((rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | - ETH_RSS_NONFRAG_IPV4_OTHER)) != 0) - efx_hash_types |= EFX_RX_HASH_IPV4; + if (alg_mask & (1U << EFX_RX_HASHALG_TOEPLITZ)) + alg = EFX_RX_HASHALG_TOEPLITZ; + else if (alg_mask & (1U << EFX_RX_HASHALG_PACKED_STREAM)) + alg = EFX_RX_HASHALG_PACKED_STREAM; + else + return EINVAL; - if ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != 0) - efx_hash_types |= EFX_RX_HASH_TCPIPV4; + rc = efx_rx_scale_hash_flags_get(sa->nic, alg, flags_supp, + &nb_flags_supp); + if (rc != 0) + return rc; - if ((rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | - ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX)) != 0) - efx_hash_types |= EFX_RX_HASH_IPV6; + hf_map = rte_calloc_socket("sfc-rss-hf-map", + RTE_DIM(sfc_rss_hf_map), + sizeof(*hf_map), 0, sa->socket_id); + if (hf_map == NULL) + return ENOMEM; + + entry = hf_map; + efx_hash_types = 0; + for (i = 0; i < RTE_DIM(sfc_rss_hf_map); ++i) { + efx_rx_hash_type_t ht; + + ht = sfc_rx_hash_types_mask_supp(sfc_rss_hf_map[i].efx, + flags_supp, nb_flags_supp); + if (ht != 0) { + entry->rte = sfc_rss_hf_map[i].rte; + entry->efx = ht; + efx_hash_types |= ht; + ++entry; + } + } - if ((rss_hf & (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX)) != 0) - efx_hash_types |= EFX_RX_HASH_TCPIPV6; + rss->hash_alg = alg; + rss->hf_map_nb_entries = (unsigned int)(entry - hf_map); + rss->hf_map = hf_map; + rss->hash_types = efx_hash_types; - return efx_hash_types; + return 0; } -uint64_t -sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) +void +sfc_rx_hash_fini(struct sfc_adapter *sa) { - uint64_t rss_hf = 0; + struct sfc_rss *rss = &sa->rss; - if ((efx_hash_types & EFX_RX_HASH_IPV4) != 0) - rss_hf |= (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | - ETH_RSS_NONFRAG_IPV4_OTHER); + rte_free(rss->hf_map); +} - if ((efx_hash_types & EFX_RX_HASH_TCPIPV4) != 0) - rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; +int +sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte, + efx_rx_hash_type_t *efx) +{ + struct sfc_rss *rss = &sa->rss; + efx_rx_hash_type_t hash_types = 0; + unsigned int i; - if ((efx_hash_types & EFX_RX_HASH_IPV6) != 0) - rss_hf |= (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | - ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX); + for (i = 0; i < rss->hf_map_nb_entries; ++i) { + uint64_t rte_mask = rss->hf_map[i].rte; - if ((efx_hash_types & EFX_RX_HASH_TCPIPV6) != 0) - rss_hf |= (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX); + if ((rte & rte_mask) != 0) { + rte &= ~rte_mask; + hash_types |= rss->hf_map[i].efx; + } + } + + if (rte != 0) { + sfc_err(sa, "unsupported hash functions requested"); + return EINVAL; + } - return rss_hf; + *efx = hash_types; + + return 0; +} + +uint64_t +sfc_rx_hf_efx_to_rte(struct sfc_adapter *sa, efx_rx_hash_type_t efx) +{ + struct sfc_rss *rss = &sa->rss; + uint64_t rte = 0; + unsigned int i; + + for (i = 0; i < rss->hf_map_nb_entries; ++i) { + efx_rx_hash_type_t hash_type = rss->hf_map[i].efx; + + if ((efx & hash_type) == hash_type) + rte |= rss->hf_map[i].rte; + } + + return rte; } static int @@ -1182,20 +1300,19 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, { struct sfc_rss *rss = &sa->rss; efx_rx_hash_type_t efx_hash_types = rss->hash_types; + uint64_t rss_hf = sfc_rx_hf_efx_to_rte(sa, efx_hash_types); + int rc; if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { - if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || + if ((conf->rss_hf != 0 && conf->rss_hf != rss_hf) || conf->rss_key != NULL) return EINVAL; } if (conf->rss_hf != 0) { - if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { - sfc_err(sa, "unsupported hash functions requested"); - return EINVAL; - } - - efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf); + rc = sfc_rx_hf_rte_to_efx(sa, conf->rss_hf, &efx_hash_types); + if (rc != 0) + return rc; } if (conf->rss_key != NULL) { @@ -1220,8 +1337,8 @@ sfc_rx_rss_config(struct sfc_adapter *sa) if (rss->channels > 0) { rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - EFX_RX_HASHALG_TOEPLITZ, - rss->hash_types, B_TRUE); + rss->hash_alg, rss->hash_types, + B_TRUE); if (rc != 0) goto finish; diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h index ea911be..d9e7b0b 100644 --- a/drivers/net/sfc/sfc_rx.h +++ b/drivers/net/sfc/sfc_rx.h @@ -152,8 +152,12 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index); int sfc_rx_qdesc_done(struct sfc_dp_rxq *dp_rxq, unsigned int offset); -efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf); -uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types); +int sfc_rx_hash_init(struct sfc_adapter *sa); +void sfc_rx_hash_fini(struct sfc_adapter *sa); +int sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte, + efx_rx_hash_type_t *efx); +uint64_t sfc_rx_hf_efx_to_rte(struct sfc_adapter *sa, + efx_rx_hash_type_t efx); #ifdef __cplusplus } -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko ` (6 preceding siblings ...) 2018-04-06 17:21 ` [dpdk-dev] [PATCH 7/7] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko ` (8 more replies) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko 8 siblings, 9 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev The patch series should be applied on top of [1]. checkpatches.sh warnings are bacause of positive errno used inside the driver. checkpatches.sh checks are OK. [1] https://dpdk.org/ml/archives/dev/2018-April/098047.html Andrew Rybchenko (1): net/sfc/base: cope with clang warning on negative shift Ivan Malov (7): net/sfc/base: add a new means to control RSS hash net/sfc/base: support more RSS hash configurations net/sfc/base: honour packed stream RSS restriction net/sfc: process RSS settings on Rx configure step net/sfc: remove conditional compilation for RSS net/sfc: factor out RSS fields from adapter info net/sfc: convert to the advanced EFX RSS interface drivers/net/sfc/base/ef10_nic.c | 65 ++++++++- drivers/net/sfc/base/ef10_rx.c | 74 ++++++++++- drivers/net/sfc/base/efx.h | 120 ++++++++++++++++- drivers/net/sfc/base/efx_rx.c | 159 +++++++++++++++++++++- drivers/net/sfc/base/efx_types.h | 38 ++++-- drivers/net/sfc/base/siena_nic.c | 12 ++ drivers/net/sfc/sfc.c | 37 +++--- drivers/net/sfc/sfc.h | 33 +++-- drivers/net/sfc/sfc_ethdev.c | 76 +++++------ drivers/net/sfc/sfc_flow.c | 75 ++++++----- drivers/net/sfc/sfc_flow.h | 4 - drivers/net/sfc/sfc_rx.c | 275 +++++++++++++++++++++++++++++---------- drivers/net/sfc/sfc_rx.h | 10 +- 13 files changed, 767 insertions(+), 211 deletions(-) -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 1/8] net/sfc/base: cope with clang warning on negative shift 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 2/8] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko ` (7 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev clang 4.0.1-6 on Ubuntu generates false positive warning that shift is negative. It is done regardless of the fact that the branch is not taken because of previous check. The warning is generate in EFX_INSERT_NATIVE32 used by EFX_INSERT_FIELD_NATIVE32. All similar cases are fixed as well. It is undesirable to suppress the warning completely. Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/efx_types.h | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/net/sfc/base/efx_types.h b/drivers/net/sfc/base/efx_types.h index 0581f67..65168ab 100644 --- a/drivers/net/sfc/base/efx_types.h +++ b/drivers/net/sfc/base/efx_types.h @@ -329,6 +329,16 @@ extern int fix_lint; #endif /* + * Saturation arithmetic subtract with minimum equal to zero. + * + * Use saturating arithmetic to ensure a non-negative result. This + * avoids undefined behaviour (and compiler warnings) when used as a + * shift count. + */ +#define EFX_SSUB(_val, _sub) \ + ((_val) > (_sub) ? ((_val) - (_sub)) : 0) + +/* * Extract bit field portion [low,high) from the native-endian element * which contains bits [min,max). * @@ -347,8 +357,8 @@ extern int fix_lint; ((FIX_LINT(_low > _max) || FIX_LINT(_high < _min)) ? \ 0U : \ ((_low > _min) ? \ - ((_element) >> (_low - _min)) : \ - ((_element) << (_min - _low)))) + ((_element) >> EFX_SSUB(_low, _min)) : \ + ((_element) << EFX_SSUB(_min, _low)))) /* * Extract bit field portion [low,high) from the 64-bit little-endian @@ -537,29 +547,29 @@ extern int fix_lint; (((_low > _max) || (_high < _min)) ? \ 0U : \ ((_low > _min) ? \ - (((uint64_t)(_value)) << (_low - _min)) : \ - (((uint64_t)(_value)) >> (_min - _low)))) + (((uint64_t)(_value)) << EFX_SSUB(_low, _min)) :\ + (((uint64_t)(_value)) >> EFX_SSUB(_min, _low)))) #define EFX_INSERT_NATIVE32(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ ((_low > _min) ? \ - (((uint32_t)(_value)) << (_low - _min)) : \ - (((uint32_t)(_value)) >> (_min - _low)))) + (((uint32_t)(_value)) << EFX_SSUB(_low, _min)) :\ + (((uint32_t)(_value)) >> EFX_SSUB(_min, _low)))) #define EFX_INSERT_NATIVE16(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ (uint16_t)((_low > _min) ? \ - ((_value) << (_low - _min)) : \ - ((_value) >> (_min - _low)))) + ((_value) << EFX_SSUB(_low, _min)) : \ + ((_value) >> EFX_SSUB(_min, _low)))) #define EFX_INSERT_NATIVE8(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ (uint8_t)((_low > _min) ? \ - ((_value) << (_low - _min)) : \ - ((_value) >> (_min - _low)))) + ((_value) << EFX_SSUB(_low, _min)) : \ + ((_value) >> EFX_SSUB(_min, _low)))) /* * Construct bit field portion @@ -1288,22 +1298,22 @@ extern int fix_lint; #define EFX_SHIFT64(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 64) ? \ - ((uint64_t)1 << ((_bit) - (_base))) : \ + ((uint64_t)1 << EFX_SSUB((_bit), (_base))) : \ 0U) #define EFX_SHIFT32(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 32) ? \ - ((uint32_t)1 << ((_bit) - (_base))) : \ + ((uint32_t)1 << EFX_SSUB((_bit),(_base))) : \ 0U) #define EFX_SHIFT16(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 16) ? \ - (uint16_t)(1 << ((_bit) - (_base))) : \ + (uint16_t)(1 << EFX_SSUB((_bit), (_base))) : \ 0U) #define EFX_SHIFT8(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 8) ? \ - (uint8_t)(1 << ((_bit) - (_base))) : \ + (uint8_t)(1 << EFX_SSUB((_bit), (_base))) : \ 0U) #define EFX_SET_OWORD_BIT64(_oword, _bit) \ -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 2/8] net/sfc/base: add a new means to control RSS hash 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 3/8] net/sfc/base: support more RSS hash configurations Andrew Rybchenko ` (6 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Currently, libefx has no support for additional RSS modes available with later controllers. In order to support this, libefx should be able to list available hash configurations. This patch provides basic infrastructure for the new interface. The client drivers will be able to query the list of supported hash configurations for a particular hash algorithm. Also, it will be possible to configure hashing by means of new definitions. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_rx.c | 29 ++++++++-- drivers/net/sfc/base/efx.h | 90 +++++++++++++++++++++++++++++ drivers/net/sfc/base/efx_rx.c | 126 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 236 insertions(+), 9 deletions(-) diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index 86a6ac7..e7dd1ea 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -298,11 +298,32 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); + efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); + efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; efx_rc_t rc; + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH); + if (rss_context == EF10_RSS_CONTEXT_INVALID) { rc = EINVAL; goto fail1; @@ -320,13 +341,13 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, - (type & EFX_RX_HASH_IPV4) ? 1 : 0, + ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, - (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0, + ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, - (type & EFX_RX_HASH_IPV6) ? 1 : 0, + ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0); efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 63f0ba5..41aa505 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -2069,11 +2069,30 @@ typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_TOEPLITZ } efx_rx_hash_alg_t; +/* + * Legacy hash type flags. + * + * They represent standard tuples for distinct traffic classes. + */ #define EFX_RX_HASH_IPV4 (1U << 0) #define EFX_RX_HASH_TCPIPV4 (1U << 1) #define EFX_RX_HASH_IPV6 (1U << 2) #define EFX_RX_HASH_TCPIPV6 (1U << 3) +#define EFX_RX_HASH_LEGACY_MASK \ + (EFX_RX_HASH_IPV4 | \ + EFX_RX_HASH_TCPIPV4 | \ + EFX_RX_HASH_IPV6 | \ + EFX_RX_HASH_TCPIPV6) + +/* + * The type of the argument used by efx_rx_scale_mode_set() to + * provide a means for the client drivers to configure hashing. + * + * A properly constructed value can either be: + * - a combination of legacy flags + * - a combination of EFX_RX_HASH() flags + */ typedef unsigned int efx_rx_hash_type_t; typedef enum efx_rx_hash_support_e { @@ -2092,6 +2111,77 @@ typedef enum efx_rx_scale_context_type_e { EFX_RX_SCALE_SHARED /* Read-only key/indirection table */ } efx_rx_scale_context_type_t; +/* + * Traffic classes eligible for hash computation. + * + * Select packet headers used in computing the receive hash. + * This uses the same encoding as the RSS_MODES field of + * MC_CMD_RSS_CONTEXT_SET_FLAGS. + */ +#define EFX_RX_CLASS_IPV4_TCP_LBN 8 +#define EFX_RX_CLASS_IPV4_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV4_LBN 16 +#define EFX_RX_CLASS_IPV4_WIDTH 4 +#define EFX_RX_CLASS_IPV6_TCP_LBN 20 +#define EFX_RX_CLASS_IPV6_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV6_LBN 28 +#define EFX_RX_CLASS_IPV6_WIDTH 4 + +#define EFX_RX_NCLASSES 4 + +/* + * Ancillary flags used to construct generic hash tuples. + * This uses the same encoding as RSS_MODE_HASH_SELECTOR. + */ +#define EFX_RX_CLASS_HASH_SRC_ADDR (1U << 0) +#define EFX_RX_CLASS_HASH_DST_ADDR (1U << 1) +#define EFX_RX_CLASS_HASH_SRC_PORT (1U << 2) +#define EFX_RX_CLASS_HASH_DST_PORT (1U << 3) + +/* + * Generic hash tuples. + * + * They express combinations of packet fields + * which can contribute to the hash value for + * a particular traffic class. + */ +#define EFX_RX_CLASS_HASH_DISABLE 0 + +#define EFX_RX_CLASS_HASH_2TUPLE \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_DST_ADDR) + +#define EFX_RX_CLASS_HASH_4TUPLE \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_DST_ADDR | \ + EFX_RX_CLASS_HASH_SRC_PORT | \ + EFX_RX_CLASS_HASH_DST_PORT) + +#define EFX_RX_CLASS_HASH_NTUPLES 3 + +/* + * Hash flag constructor. + * + * Resulting flags encode hash tuples for specific traffic classes. + * The client drivers are encouraged to use these flags to form + * a hash type value. + */ +#define EFX_RX_HASH(_class, _tuple) \ + EFX_INSERT_FIELD_NATIVE32(0, 31, \ + EFX_RX_CLASS_##_class, EFX_RX_CLASS_HASH_##_tuple) + +/* + * The maximum number of EFX_RX_HASH() flags. + */ +#define EFX_RX_HASH_NFLAGS (EFX_RX_NCLASSES * EFX_RX_CLASS_HASH_NTUPLES) + +extern __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp); + extern __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index ae79584..b495c74 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -294,6 +294,61 @@ efx_rx_scatter_enable( #endif /* EFSYS_OPT_RX_SCATTER */ #if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp) +{ + unsigned int *entryp = flags; + efx_rc_t rc; + + if (flags == NULL || nflagsp == NULL) { + rc = EINVAL; + goto fail1; + } + +#define LIST_FLAGS(_entryp, _class, _l4_hashing) \ + do { \ + if (_l4_hashing) \ + *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ + \ + *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + + switch (hash_alg) { + case EFX_RX_HASHALG_TOEPLITZ: + LIST_FLAGS(entryp, IPV4_TCP, B_TRUE); + LIST_FLAGS(entryp, IPV6_TCP, B_TRUE); + LIST_FLAGS(entryp, IPV4, B_FALSE); + LIST_FLAGS(entryp, IPV6, B_FALSE); + break; + + default: + rc = EINVAL; + goto fail2; + } + +#undef LIST_FLAGS + + *nflagsp = (unsigned int)(entryp - flags); + EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS); + + return (0); + +fail2: + EFSYS_PROBE(fail2); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, @@ -425,19 +480,76 @@ efx_rx_scale_mode_set( __in boolean_t insert) { const efx_rx_ops_t *erxop = enp->en_erxop; + unsigned int type_flags[EFX_RX_HASH_NFLAGS]; + unsigned int type_nflags; + efx_rx_hash_type_t type_check; + unsigned int i; efx_rc_t rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + /* + * Legacy flags and modern bits cannot be + * used at the same time in the hash type. + */ + if ((type & EFX_RX_HASH_LEGACY_MASK) && + (type & ~EFX_RX_HASH_LEGACY_MASK)) { + rc = EINVAL; + goto fail1; + } + + /* + * Translate legacy flags to the new representation + * so that chip-specific handlers will consider the + * new flags only. + */ + if (type & EFX_RX_HASH_IPV4) + type |= EFX_RX_HASH(IPV4, 2TUPLE); + + if (type & EFX_RX_HASH_TCPIPV4) + type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE); + + if (type & EFX_RX_HASH_IPV6) + type |= EFX_RX_HASH(IPV6, 2TUPLE); + + if (type & EFX_RX_HASH_TCPIPV6) + type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE); + + type &= ~EFX_RX_HASH_LEGACY_MASK; + type_check = type; + + /* + * Get the list of supported hash flags and sanitise the input. + */ + rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags); + if (rc != 0) + goto fail2; + + for (i = 0; i < type_nflags; ++i) { + if ((type_check & type_flags[i]) == type_flags[i]) + type_check &= ~(type_flags[i]); + } + + if (type_check != 0) { + rc = EINVAL; + goto fail3; + } + if (erxop->erxo_scale_mode_set != NULL) { if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg, type, insert)) != 0) - goto fail1; + 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); @@ -881,6 +993,10 @@ siena_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); + efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); + efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); efx_rc_t rc; if (rss_context != EFX_RSS_CONTEXT_DEFAULT) { @@ -895,12 +1011,12 @@ siena_rx_scale_mode_set( case EFX_RX_HASHALG_TOEPLITZ: EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert, - type & EFX_RX_HASH_IPV4, - type & EFX_RX_HASH_TCPIPV4); + (type & type_ipv4) == type_ipv4, + (type & type_ipv4_tcp) == type_ipv4_tcp); EFX_RX_TOEPLITZ_IPV6_HASH(enp, - type & EFX_RX_HASH_IPV6, - type & EFX_RX_HASH_TCPIPV6, + (type & type_ipv6) == type_ipv6, + (type & type_ipv6_tcp) == type_ipv6_tcp, rc); if (rc != 0) goto fail2; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 3/8] net/sfc/base: support more RSS hash configurations 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 2/8] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 4/8] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko ` (5 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Modern firmwares on EF10 adapters have support for more traffic classes eligible for hash computation. Also, it has become possible to adjust hashing per individual class and select distinct packet fields which will be able to contribute to the hash value. This patch adds support for the mentioned features. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_nic.c | 6 ++++++ drivers/net/sfc/base/ef10_rx.c | 41 ++++++++++++++++++++++++++++++++++++++-- drivers/net/sfc/base/efx.h | 20 ++++++++++++++++++-- drivers/net/sfc/base/efx_rx.c | 36 +++++++++++++++++++++++++++++------ drivers/net/sfc/base/siena_nic.c | 3 +++ 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index ca11ff4..fa4f7a2 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1041,6 +1041,12 @@ ef10_get_datapath_caps( } encp->enc_rx_prefix_size = 14; + /* Check if the firmware supports additional RSS modes */ + if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES)) + encp->enc_rx_scale_additional_modes_supported = B_TRUE; + else + encp->enc_rx_scale_additional_modes_supported = B_FALSE; + /* Check if the firmware supports TSO */ if (CAP_FLAGS1(req, TX_TSO)) encp->enc_fw_assisted_tso_enabled = B_TRUE; diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index e7dd1ea..fc9e342 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -298,10 +298,12 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); + efx_rx_hash_type_t modes; efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; @@ -339,7 +341,28 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, rss_context); - MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, + /* + * Create a copy of the original hash type. + * The copy will be used to fill in RSS_MODE bits and + * may be cleared beforehand. The original variable + * and, thus, EN bits will remain unaffected. + */ + modes = type; + + /* + * If the firmware lacks support for additional modes, RSS_MODE + * fields must contain zeros, otherwise the operation will fail. + */ + if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) + modes = 0; + +#define EXTRACT_RSS_MODE(_type, _class) \ + (EFX_EXTRACT_NATIVE(_type, 0, 31, \ + EFX_LOW_BIT(EFX_RX_CLASS_##_class), \ + EFX_HIGH_BIT(EFX_RX_CLASS_##_class)) & \ + EFX_MASK32(EFX_RX_CLASS_##_class)) + + MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, @@ -347,7 +370,21 @@ efx_mcdi_rss_context_set_flags( RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0, + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4), + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6)); + +#undef EXTRACT_RSS_MODE efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 41aa505..21d2545 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1192,6 +1192,7 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; uint32_t enc_rx_scale_max_exclusive_contexts; + boolean_t enc_rx_scale_additional_modes_supported; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; #endif /* EFSYS_OPT_LOOPBACK */ @@ -2120,14 +2121,18 @@ typedef enum efx_rx_scale_context_type_e { */ #define EFX_RX_CLASS_IPV4_TCP_LBN 8 #define EFX_RX_CLASS_IPV4_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV4_UDP_LBN 12 +#define EFX_RX_CLASS_IPV4_UDP_WIDTH 4 #define EFX_RX_CLASS_IPV4_LBN 16 #define EFX_RX_CLASS_IPV4_WIDTH 4 #define EFX_RX_CLASS_IPV6_TCP_LBN 20 #define EFX_RX_CLASS_IPV6_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV6_UDP_LBN 24 +#define EFX_RX_CLASS_IPV6_UDP_WIDTH 4 #define EFX_RX_CLASS_IPV6_LBN 28 #define EFX_RX_CLASS_IPV6_WIDTH 4 -#define EFX_RX_NCLASSES 4 +#define EFX_RX_NCLASSES 6 /* * Ancillary flags used to construct generic hash tuples. @@ -2147,17 +2152,28 @@ typedef enum efx_rx_scale_context_type_e { */ #define EFX_RX_CLASS_HASH_DISABLE 0 +#define EFX_RX_CLASS_HASH_1TUPLE_SRC EFX_RX_CLASS_HASH_SRC_ADDR +#define EFX_RX_CLASS_HASH_1TUPLE_DST EFX_RX_CLASS_HASH_DST_ADDR + #define EFX_RX_CLASS_HASH_2TUPLE \ (EFX_RX_CLASS_HASH_SRC_ADDR | \ EFX_RX_CLASS_HASH_DST_ADDR) +#define EFX_RX_CLASS_HASH_2TUPLE_SRC \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_SRC_PORT) + +#define EFX_RX_CLASS_HASH_2TUPLE_DST \ + (EFX_RX_CLASS_HASH_DST_ADDR | \ + EFX_RX_CLASS_HASH_DST_PORT) + #define EFX_RX_CLASS_HASH_4TUPLE \ (EFX_RX_CLASS_HASH_SRC_ADDR | \ EFX_RX_CLASS_HASH_DST_ADDR | \ EFX_RX_CLASS_HASH_SRC_PORT | \ EFX_RX_CLASS_HASH_DST_PORT) -#define EFX_RX_CLASS_HASH_NTUPLES 3 +#define EFX_RX_CLASS_HASH_NTUPLES 7 /* * Hash flag constructor. diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index b495c74..840a11c 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -301,6 +301,8 @@ efx_rx_scale_hash_flags_get( __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, __out unsigned int *nflagsp) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t additional_modes; unsigned int *entryp = flags; efx_rc_t rc; @@ -309,12 +311,28 @@ efx_rx_scale_hash_flags_get( goto fail1; } -#define LIST_FLAGS(_entryp, _class, _l4_hashing) \ + additional_modes = encp->enc_rx_scale_additional_modes_supported; + +#define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ do { \ - if (_l4_hashing) \ + if (_l4_hashing) { \ *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ \ + if (_additional_modes) { \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_DST); \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_SRC); \ + } \ + } \ + \ *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + \ + if (_additional_modes) { \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST); \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC); \ + } \ + \ *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ \ _NOTE(CONSTANTCONDITION) \ @@ -322,10 +340,16 @@ efx_rx_scale_hash_flags_get( switch (hash_alg) { case EFX_RX_HASHALG_TOEPLITZ: - LIST_FLAGS(entryp, IPV4_TCP, B_TRUE); - LIST_FLAGS(entryp, IPV6_TCP, B_TRUE); - LIST_FLAGS(entryp, IPV4, B_FALSE); - LIST_FLAGS(entryp, IPV6, B_FALSE); + LIST_FLAGS(entryp, IPV4_TCP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, B_TRUE, additional_modes); + + if (additional_modes) { + LIST_FLAGS(entryp, IPV4_UDP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, B_TRUE, additional_modes); + } + + LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); + LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes); break; default: diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index 6e57de4..0d6d071 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -118,6 +118,9 @@ siena_board_cfg( /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; + /* There is no support for additional RSS modes */ + encp->enc_rx_scale_additional_modes_supported = B_FALSE; + encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT); /* Fragments must not span 4k boundaries. */ encp->enc_tx_dma_desc_boundary = 4096; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 4/8] net/sfc/base: honour packed stream RSS restriction 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko ` (2 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 3/8] net/sfc/base: support more RSS hash configurations Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 5/8] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko ` (4 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Packed stream firmware variant on EF10 adapters has a number of properties which must be taken into account: - Only one exclusive RSS context is available per port. - Only IP addresses can contribute to the hash value. Huntington and Medford have one more limitation which is important for the drivers capable of packed stream: - Hash algorithm is non-standard (i.e. non-Toeplitz). This implies XORing together source + destination IP addresses (or last four bytes in the case of IPv6) and using the result as the input to a Toeplitz hash. This patch provides a number of improvements in order to treat the mentioned limitations in the common code. If the firmware variant is packed stream, the list of supported hash tuples will include less variants, and the maximum number of RSS contexts will be set to one. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_nic.c | 59 +++++++++++++++++++++++++++++++++++----- drivers/net/sfc/base/ef10_rx.c | 6 ++-- drivers/net/sfc/base/efx.h | 14 +++++++++- drivers/net/sfc/base/efx_rx.c | 17 +++++++++--- drivers/net/sfc/base/siena_nic.c | 9 ++++++ 5 files changed, 91 insertions(+), 14 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index fa4f7a2..e1f1c2e 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1239,11 +1239,63 @@ ef10_get_datapath_caps( else encp->enc_fec_counters = B_FALSE; + if (CAP_FLAGS1(req, RX_RSS_LIMITED)) { + /* Only one exclusive RSS context is available per port. */ + encp->enc_rx_scale_max_exclusive_contexts = 1; + + switch (enp->en_family) { + case EFX_FAMILY_MEDFORD2: + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_TOEPLITZ); + break; + + case EFX_FAMILY_MEDFORD: + case EFX_FAMILY_HUNTINGTON: + /* + * Packed stream firmware variant maintains a + * non-standard algorithm for hash computation. + * It implies explicit XORing together + * source + destination IP addresses (or last + * four bytes in the case of IPv6) and using the + * resulting value as the input to a Toeplitz hash. + */ + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_PACKED_STREAM); + break; + + default: + rc = EINVAL; + goto fail5; + } + + /* Port numbers cannot contribute to the hash value */ + encp->enc_rx_scale_l4_hash_supported = B_FALSE; + } else { + /* + * Maximum number of exclusive RSS contexts. + * EF10 hardware supports 64 in total, but 6 are reserved + * for shared contexts. They are a global resource so + * not all may be available. + */ + encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; + + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_TOEPLITZ); + + /* + * It is possible to use port numbers as + * the input data for hash computation. + */ + encp->enc_rx_scale_l4_hash_supported = B_TRUE; + } + #undef CAP_FLAGS1 #undef CAP_FLAGS2 return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -1713,13 +1765,6 @@ ef10_nic_board_cfg( /* Alignment for WPTR updates */ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; - /* - * Maximum number of exclusive RSS contexts. EF10 hardware supports 64 - * in total, but 6 are reserved for shared contexts. They are a global - * resource so not all may be available. - */ - encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; - encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); /* No boundary crossing limits */ encp->enc_tx_dma_desc_boundary = 0; diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index fc9e342..70e451f 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -609,12 +609,13 @@ ef10_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rc_t rc; - EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ); EFSYS_ASSERT3U(insert, ==, B_TRUE); - if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) { + if ((encp->enc_rx_scale_hash_alg_mask & (1U << alg)) == 0 || + insert == B_FALSE) { rc = EINVAL; goto fail1; } @@ -763,6 +764,7 @@ ef10_rx_prefix_hash( _NOTE(ARGUNUSED(enp)) switch (func) { + case EFX_RX_HASHALG_PACKED_STREAM: case EFX_RX_HASHALG_TOEPLITZ: return (buffer[0] | (buffer[1] << 8) | diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 21d2545..0b75f0f 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1192,6 +1192,16 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; uint32_t enc_rx_scale_max_exclusive_contexts; + /* + * Mask of supported hash algorithms. + * Hash algorithm types are used as the bit indices. + */ + uint32_t enc_rx_scale_hash_alg_mask; + /* + * Indicates whether port numbers can be included to the + * input data for hash computation. + */ + boolean_t enc_rx_scale_l4_hash_supported; boolean_t enc_rx_scale_additional_modes_supported; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; @@ -2067,7 +2077,9 @@ efx_rx_scatter_enable( typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_LFSR = 0, - EFX_RX_HASHALG_TOEPLITZ + EFX_RX_HASHALG_TOEPLITZ, + EFX_RX_HASHALG_PACKED_STREAM, + EFX_RX_NHASHALGS } efx_rx_hash_alg_t; /* diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index 840a11c..d75957f 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -302,6 +302,7 @@ efx_rx_scale_hash_flags_get( __out unsigned int *nflagsp) { efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t l4; boolean_t additional_modes; unsigned int *entryp = flags; efx_rc_t rc; @@ -311,6 +312,7 @@ efx_rx_scale_hash_flags_get( goto fail1; } + l4 = encp->enc_rx_scale_l4_hash_supported; additional_modes = encp->enc_rx_scale_additional_modes_supported; #define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ @@ -339,13 +341,20 @@ efx_rx_scale_hash_flags_get( } while (B_FALSE) switch (hash_alg) { + case EFX_RX_HASHALG_PACKED_STREAM: + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + /* FALLTHRU */ case EFX_RX_HASHALG_TOEPLITZ: - LIST_FLAGS(entryp, IPV4_TCP, B_TRUE, additional_modes); - LIST_FLAGS(entryp, IPV6_TCP, B_TRUE, additional_modes); + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + + LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes); if (additional_modes) { - LIST_FLAGS(entryp, IPV4_UDP, B_TRUE, additional_modes); - LIST_FLAGS(entryp, IPV6_UDP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes); } LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index 0d6d071..c3a9495 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -118,6 +118,15 @@ siena_board_cfg( /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; + encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR); + encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ); + + /* + * It is always possible to use port numbers + * as the input data for hash computation. + */ + encp->enc_rx_scale_l4_hash_supported = B_TRUE; + /* There is no support for additional RSS modes */ encp->enc_rx_scale_additional_modes_supported = B_FALSE; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 5/8] net/sfc: process RSS settings on Rx configure step 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko ` (3 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 4/8] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 6/8] net/sfc: remove conditional compilation for RSS Andrew Rybchenko ` (3 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov, stable From: Ivan Malov <ivan.malov@oktetlabs.ru> One may submit advanced RSS settings as part of rte_eth_conf to customise RSS configuration from the very beginning. Currently the driver does not check that piece of settings and proceeds with default choices for RSS hash functions and RSS key. This patch implements the required processing. Fixes: 4ec1fc3ba881 ("net/sfc: add basic stubs for RSS support on driver attach") Cc: stable@dpdk.org Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc_rx.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 734ce24..fca3931 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -1189,6 +1189,41 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) #if EFSYS_OPT_RX_SCALE static int +sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, + struct rte_eth_rss_conf *conf) +{ + efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types; + + if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || + conf->rss_key != NULL) + return EINVAL; + } + + if (conf->rss_hf != 0) { + if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { + sfc_err(sa, "unsupported hash functions requested"); + return EINVAL; + } + + efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf); + } + + if (conf->rss_key != NULL) { + if (conf->rss_key_len != sizeof(sa->rss_key)) { + sfc_err(sa, "RSS key size is wrong (should be %lu)", + sizeof(sa->rss_key)); + return EINVAL; + } + rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key)); + } + + sa->rss_hash_types = efx_hash_types; + + return 0; +} + +static int sfc_rx_rss_config(struct sfc_adapter *sa) { int rc = 0; @@ -1416,16 +1451,23 @@ sfc_rx_configure(struct sfc_adapter *sa) MIN(sa->rxq_count, EFX_MAXRSS) : 0; if (sa->rss_channels > 0) { + struct rte_eth_rss_conf *adv_conf_rss; unsigned int sw_index; for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index) sa->rss_tbl[sw_index] = sw_index % sa->rss_channels; + + adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf; + rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss); + if (rc != 0) + goto fail_rx_process_adv_conf_rss; } #endif done: return 0; +fail_rx_process_adv_conf_rss: fail_rx_qinit_info: fail_rxqs_realloc: fail_rxqs_alloc: -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 6/8] net/sfc: remove conditional compilation for RSS 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko ` (4 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 5/8] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 7/8] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko ` (2 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> RSS is one of the most valuable features in the driver, and one would hardly need to disable it at build time. This patch withdraws unnecessary conditionals for RSS snippets. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 10 ---------- drivers/net/sfc/sfc.h | 4 ---- drivers/net/sfc/sfc_ethdev.c | 6 ------ drivers/net/sfc/sfc_flow.c | 10 ---------- drivers/net/sfc/sfc_flow.h | 4 ---- drivers/net/sfc/sfc_rx.c | 25 ------------------------- drivers/net/sfc/sfc_rx.h | 2 -- 7 files changed, 61 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index dcf5eb8..41ebd0b 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -623,7 +623,6 @@ sfc_mem_bar_fini(struct sfc_adapter *sa) memset(ebp, 0, sizeof(*ebp)); } -#if EFSYS_OPT_RX_SCALE /* * A fixed RSS key which has a property of being symmetric * (symmetrical flows are distributed to the same CPU) @@ -637,9 +636,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, }; -#endif -#if EFSYS_OPT_RX_SCALE static int sfc_set_rss_defaults(struct sfc_adapter *sa) { @@ -688,13 +685,6 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) fail_intr_init: return rc; } -#else -static int -sfc_set_rss_defaults(__rte_unused struct sfc_adapter *sa) -{ - return 0; -} -#endif int sfc_attach(struct sfc_adapter *sa) diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 65a4df2..805f211 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,10 +27,8 @@ extern "C" { #endif -#if EFSYS_OPT_RX_SCALE /** RSS hash offloads mask */ #define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP) -#endif /* * +---------------+ @@ -227,13 +225,11 @@ struct sfc_adapter { unsigned int rss_channels; -#if EFSYS_OPT_RX_SCALE efx_rx_scale_context_type_t rss_support; efx_rx_hash_support_t hash_support; efx_rx_hash_type_t rss_hash_types; unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; uint8_t rss_key[EFX_RSS_KEY_SIZE]; -#endif /* * Shared memory copy of the Rx datapath name to be used by diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 47d7a86..be6d449 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -151,13 +151,11 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; -#if EFSYS_OPT_RX_SCALE if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) { dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; } -#endif /* Initialize to hardware limits */ dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS; @@ -1357,7 +1355,6 @@ sfc_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, return sfc_dev_udp_tunnel_op(dev, tunnel_udp, SFC_UDP_TUNNEL_DEL_PORT); } -#if EFSYS_OPT_RX_SCALE static int sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) @@ -1568,7 +1565,6 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, SFC_ASSERT(rc >= 0); return -rc; } -#endif static int sfc_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, @@ -1663,12 +1659,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .mac_addr_set = sfc_mac_addr_set, .udp_tunnel_port_add = sfc_dev_udp_tunnel_port_add, .udp_tunnel_port_del = sfc_dev_udp_tunnel_port_del, -#if EFSYS_OPT_RX_SCALE .reta_update = sfc_dev_rss_reta_update, .reta_query = sfc_dev_rss_reta_query, .rss_hash_update = sfc_dev_rss_hash_update, .rss_hash_conf_get = sfc_dev_rss_hash_conf_get, -#endif .filter_ctrl = sfc_dev_filter_ctrl, .set_mc_addr_list = sfc_set_mc_addr_list, .rxq_info_get = sfc_rx_queue_info_get, diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index bcde2c2..9c09cdb 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1248,7 +1248,6 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, return 0; } -#if EFSYS_OPT_RX_SCALE static int sfc_flow_parse_rss(struct sfc_adapter *sa, const struct rte_flow_action_rss *rss, @@ -1324,7 +1323,6 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, return 0; } -#endif /* EFSYS_OPT_RX_SCALE */ static int sfc_flow_spec_flush(struct sfc_adapter *sa, struct sfc_flow_spec *spec, @@ -1374,7 +1372,6 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { -#if EFSYS_OPT_RX_SCALE struct sfc_flow_rss *rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; @@ -1451,9 +1448,6 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, fail_scale_context_alloc: return rc; -#else /* !EFSYS_OPT_RX_SCALE */ - return sfc_flow_spec_insert(sa, &flow->spec); -#endif /* EFSYS_OPT_RX_SCALE */ } static int @@ -1466,7 +1460,6 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, if (rc != 0) return rc; -#if EFSYS_OPT_RX_SCALE if (flow->rss) { /* * All specifications for a given flow rule have the same RSS @@ -1477,7 +1470,6 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context); } -#endif /* EFSYS_OPT_RX_SCALE */ return rc; } @@ -1524,7 +1516,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, is_specified = B_TRUE; break; -#if EFSYS_OPT_RX_SCALE case RTE_FLOW_ACTION_TYPE_RSS: rc = sfc_flow_parse_rss(sa, actions->conf, flow); if (rc != 0) { @@ -1536,7 +1527,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, is_specified = B_TRUE; break; -#endif /* EFSYS_OPT_RX_SCALE */ case RTE_FLOW_ACTION_TYPE_DROP: flow->spec.template.efs_dmaq_id = diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index 69dd683..71ec18c 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -26,7 +26,6 @@ extern "C" { */ #define SF_FLOW_SPEC_NB_FILTERS_MAX 8 -#if EFSYS_OPT_RX_SCALE /* RSS configuration storage */ struct sfc_flow_rss { unsigned int rxq_hw_index_min; @@ -35,7 +34,6 @@ struct sfc_flow_rss { uint8_t rss_key[EFX_RSS_KEY_SIZE]; unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; }; -#endif /* EFSYS_OPT_RX_SCALE */ /* Filter specification storage */ struct sfc_flow_spec { @@ -50,10 +48,8 @@ struct sfc_flow_spec { /* PMD-specific definition of the opaque type from rte_flow.h */ struct rte_flow { struct sfc_flow_spec spec; /* flow spec for hardware filter(s) */ -#if EFSYS_OPT_RX_SCALE boolean_t rss; /* RSS toggle */ struct sfc_flow_rss rss_conf; /* RSS configuration */ -#endif /* EFSYS_OPT_RX_SCALE */ TAILQ_ENTRY(rte_flow) entries; /* flow list entries */ }; diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index fca3931..c30f230 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -184,7 +184,6 @@ sfc_efx_supported_ptypes_get(__rte_unused uint32_t tunnel_encaps) return ptypes; } -#if EFSYS_OPT_RX_SCALE static void sfc_efx_rx_set_rss_hash(struct sfc_efx_rxq *rxq, unsigned int flags, struct rte_mbuf *m) @@ -205,14 +204,6 @@ sfc_efx_rx_set_rss_hash(struct sfc_efx_rxq *rxq, unsigned int flags, m->ol_flags |= PKT_RX_RSS_HASH; } } -#else -static void -sfc_efx_rx_set_rss_hash(__rte_unused struct sfc_efx_rxq *rxq, - __rte_unused unsigned int flags, - __rte_unused struct rte_mbuf *m) -{ -} -#endif static uint16_t sfc_efx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) @@ -1068,10 +1059,8 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; -#if EFSYS_OPT_RX_SCALE if (sa->hash_support == EFX_RX_HASH_AVAILABLE && sa->rss_channels > 0) info.flags |= SFC_RXQ_FLAG_RSS_HASH; -#endif info.rxq_entries = rxq_info->entries; info.rxq_hw_ring = rxq->mem.esm_base; @@ -1141,7 +1130,6 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rte_free(rxq); } -#if EFSYS_OPT_RX_SCALE efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf) { @@ -1185,9 +1173,7 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) return rss_hf; } -#endif -#if EFSYS_OPT_RX_SCALE static int sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, struct rte_eth_rss_conf *conf) @@ -1248,13 +1234,6 @@ sfc_rx_rss_config(struct sfc_adapter *sa) finish: return rc; } -#else -static int -sfc_rx_rss_config(__rte_unused struct sfc_adapter *sa) -{ - return 0; -} -#endif int sfc_rx_start(struct sfc_adapter *sa) @@ -1337,14 +1316,12 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) case ETH_MQ_RX_NONE: /* No special checks are required */ break; -#if EFSYS_OPT_RX_SCALE case ETH_MQ_RX_RSS: if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) { sfc_err(sa, "RSS is not available"); rc = EINVAL; } break; -#endif default: sfc_err(sa, "Rx multi-queue mode %u not supported", rxmode->mq_mode); @@ -1446,7 +1423,6 @@ sfc_rx_configure(struct sfc_adapter *sa) sa->rxq_count++; } -#if EFSYS_OPT_RX_SCALE sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? MIN(sa->rxq_count, EFX_MAXRSS) : 0; @@ -1462,7 +1438,6 @@ sfc_rx_configure(struct sfc_adapter *sa) if (rc != 0) goto fail_rx_process_adv_conf_rss; } -#endif done: return 0; diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h index 6706ee6..ea911be 100644 --- a/drivers/net/sfc/sfc_rx.h +++ b/drivers/net/sfc/sfc_rx.h @@ -152,10 +152,8 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index); int sfc_rx_qdesc_done(struct sfc_dp_rxq *dp_rxq, unsigned int offset); -#if EFSYS_OPT_RX_SCALE efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf); uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types); -#endif #ifdef __cplusplus } -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 7/8] net/sfc: factor out RSS fields from adapter info 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko ` (5 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 6/8] net/sfc: remove conditional compilation for RSS Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 8/8] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko 2018-04-25 17:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> RSS handling will need more sophisticated fields in the adapter context storage in future patches. This patch groups existing fields in a dedicated structure and updates the rest of the code. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 9 ++++---- drivers/net/sfc/sfc.h | 17 ++++++++------- drivers/net/sfc/sfc_ethdev.c | 49 ++++++++++++++++++++++++------------------- drivers/net/sfc/sfc_flow.c | 50 +++++++++++++++++++++++++------------------- drivers/net/sfc/sfc_rx.c | 47 +++++++++++++++++++++++------------------ 5 files changed, 97 insertions(+), 75 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 41ebd0b..1066a5e 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -640,6 +640,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { static int sfc_set_rss_defaults(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; int rc; rc = efx_intr_init(sa->nic, sa->intr.type, NULL); @@ -654,11 +655,11 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) if (rc != 0) goto fail_rx_init; - rc = efx_rx_scale_default_support_get(sa->nic, &sa->rss_support); + rc = efx_rx_scale_default_support_get(sa->nic, &rss->context_type); if (rc != 0) goto fail_scale_support_get; - rc = efx_rx_hash_default_support_get(sa->nic, &sa->hash_support); + rc = efx_rx_hash_default_support_get(sa->nic, &rss->hash_support); if (rc != 0) goto fail_hash_support_get; @@ -666,9 +667,9 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) efx_ev_fini(sa->nic); efx_intr_fini(sa->nic); - sa->rss_hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); + rss->hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); - rte_memcpy(sa->rss_key, default_rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); return 0; diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 805f211..9c76d7f 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -154,6 +154,15 @@ struct sfc_port { uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; }; +struct sfc_rss { + unsigned int channels; + efx_rx_scale_context_type_t context_type; + efx_rx_hash_support_t hash_support; + efx_rx_hash_type_t hash_types; + unsigned int tbl[EFX_RSS_TBL_SIZE]; + uint8_t key[EFX_RSS_KEY_SIZE]; +}; + /* Adapter private data */ struct sfc_adapter { /* @@ -223,13 +232,7 @@ struct sfc_adapter { boolean_t tso; - unsigned int rss_channels; - - efx_rx_scale_context_type_t rss_support; - efx_rx_hash_support_t hash_support; - efx_rx_hash_type_t rss_hash_types; - unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; - uint8_t rss_key[EFX_RSS_KEY_SIZE]; + struct sfc_rss rss; /* * Shared memory copy of the Rx datapath name to be used by diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index be6d449..359d6d2 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -85,6 +85,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct sfc_adapter *sa = dev->data->dev_private; const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_rss *rss = &sa->rss; uint64_t txq_offloads_def = 0; sfc_log_init(sa, "entry"); @@ -151,7 +152,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; - if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) { + if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; @@ -1360,12 +1361,13 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; - if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated) + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated) return -ENOTSUP; - if (sa->rss_channels == 0) + if (rss->channels == 0) return -EINVAL; sfc_adapter_lock(sa); @@ -1376,10 +1378,10 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, * flags which corresponds to the active EFX configuration stored * locally in 'sfc_adapter' and kept up-to-date */ - rss_conf->rss_hf = sfc_efx_to_rte_hash_type(sa->rss_hash_types); + rss_conf->rss_hf = sfc_efx_to_rte_hash_type(rss->hash_types); rss_conf->rss_key_len = EFX_RSS_KEY_SIZE; if (rss_conf->rss_key != NULL) - rte_memcpy(rss_conf->rss_key, sa->rss_key, EFX_RSS_KEY_SIZE); + rte_memcpy(rss_conf->rss_key, rss->key, EFX_RSS_KEY_SIZE); sfc_adapter_unlock(sa); @@ -1391,6 +1393,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; unsigned int efx_hash_types; int rc = 0; @@ -1398,20 +1401,20 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, if (port->isolated) return -ENOTSUP; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { sfc_err(sa, "RSS is not available"); return -ENOTSUP; } - if (sa->rss_channels == 0) { + if (rss->channels == 0) { sfc_err(sa, "RSS is not configured"); return -EINVAL; } if ((rss_conf->rss_key != NULL) && - (rss_conf->rss_key_len != sizeof(sa->rss_key))) { + (rss_conf->rss_key_len != sizeof(rss->key))) { sfc_err(sa, "RSS key size is wrong (should be %lu)", - sizeof(sa->rss_key)); + sizeof(rss->key)); return -EINVAL; } @@ -1435,15 +1438,15 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, rc = efx_rx_scale_key_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, rss_conf->rss_key, - sizeof(sa->rss_key)); + sizeof(rss->key)); if (rc != 0) goto fail_scale_key_set; } - rte_memcpy(sa->rss_key, rss_conf->rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, rss_conf->rss_key, sizeof(rss->key)); } - sa->rss_hash_types = efx_hash_types; + rss->hash_types = efx_hash_types; sfc_adapter_unlock(sa); @@ -1452,7 +1455,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, fail_scale_key_set: if (efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, EFX_RX_HASHALG_TOEPLITZ, - sa->rss_hash_types, B_TRUE) != 0) + rss->hash_types, B_TRUE) != 0) sfc_err(sa, "failed to restore RSS mode"); fail_scale_mode_set: @@ -1466,13 +1469,14 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, uint16_t reta_size) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; int entry; - if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated) + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated) return -ENOTSUP; - if (sa->rss_channels == 0) + if (rss->channels == 0) return -EINVAL; if (reta_size != EFX_RSS_TBL_SIZE) @@ -1485,7 +1489,7 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, int grp_idx = entry % RTE_RETA_GROUP_SIZE; if ((reta_conf[grp].mask >> grp_idx) & 1) - reta_conf[grp].reta[grp_idx] = sa->rss_tbl[entry]; + reta_conf[grp].reta[grp_idx] = rss->tbl[entry]; } sfc_adapter_unlock(sa); @@ -1499,6 +1503,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, uint16_t reta_size) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; unsigned int *rss_tbl_new; uint16_t entry; @@ -1508,12 +1513,12 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, if (port->isolated) return -ENOTSUP; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { sfc_err(sa, "RSS is not available"); return -ENOTSUP; } - if (sa->rss_channels == 0) { + if (rss->channels == 0) { sfc_err(sa, "RSS is not configured"); return -EINVAL; } @@ -1524,13 +1529,13 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, return -EINVAL; } - rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(sa->rss_tbl), 0); + rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(rss->tbl), 0); if (rss_tbl_new == NULL) return -ENOMEM; sfc_adapter_lock(sa); - rte_memcpy(rss_tbl_new, sa->rss_tbl, sizeof(sa->rss_tbl)); + rte_memcpy(rss_tbl_new, rss->tbl, sizeof(rss->tbl)); for (entry = 0; entry < reta_size; entry++) { int grp_idx = entry % RTE_RETA_GROUP_SIZE; @@ -1539,7 +1544,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, grp = &reta_conf[entry / RTE_RETA_GROUP_SIZE]; if (grp->mask & (1ull << grp_idx)) { - if (grp->reta[grp_idx] >= sa->rss_channels) { + if (grp->reta[grp_idx] >= rss->channels) { rc = EINVAL; goto bad_reta_entry; } @@ -1554,7 +1559,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, goto fail_scale_tbl_set; } - rte_memcpy(sa->rss_tbl, rss_tbl_new, sizeof(sa->rss_tbl)); + rte_memcpy(rss->tbl, rss_tbl_new, sizeof(rss->tbl)); fail_scale_tbl_set: bad_reta_entry: diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 9c09cdb..f664cfa 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1250,18 +1250,20 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, static int sfc_flow_parse_rss(struct sfc_adapter *sa, - const struct rte_flow_action_rss *rss, + const struct rte_flow_action_rss *action_rss, struct rte_flow *flow) { + struct sfc_rss *rss = &sa->rss; unsigned int rxq_sw_index; struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; unsigned int rxq_hw_index_max; + uint64_t rss_hf; const uint8_t *rss_key; struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf; unsigned int i; - if (rss->queue_num == 0) + if (action_rss->queue_num == 0) return -EINVAL; rxq_sw_index = sa->rxq_count - 1; @@ -1269,8 +1271,8 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, rxq_hw_index_min = rxq->hw_index; rxq_hw_index_max = 0; - for (i = 0; i < rss->queue_num; ++i) { - rxq_sw_index = rss->queue[i]; + for (i = 0; i < action_rss->queue_num; ++i) { + rxq_sw_index = action_rss->queue[i]; if (rxq_sw_index >= sa->rxq_count) return -EINVAL; @@ -1284,7 +1286,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, rxq_hw_index_max = rxq->hw_index; } - switch (rss->func) { + switch (action_rss->func) { case RTE_ETH_HASH_FUNCTION_DEFAULT: case RTE_ETH_HASH_FUNCTION_TOEPLITZ: break; @@ -1292,30 +1294,32 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, return -EINVAL; } - if (rss->level) + if (action_rss->level) return -EINVAL; - if ((rss->types & ~SFC_RSS_OFFLOADS) != 0) + rss_hf = action_rss->types; + if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0) return -EINVAL; - if (rss->key_len) { - if (rss->key_len != sizeof(sa->rss_key)) + if (action_rss->key_len) { + if (action_rss->key_len != sizeof(rss->key)) return -EINVAL; - rss_key = rss->key; + rss_key = action_rss->key; } else { - rss_key = sa->rss_key; + rss_key = rss->key; } flow->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 = sfc_rte_to_efx_hash_type(rss->types); - rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key)); + sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf); + 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 rxq_sw_index = rss->queue[i % rss->queue_num]; + unsigned int nb_queues = action_rss->queue_num; + unsigned int rxq_sw_index = action_rss->queue[i % nb_queues]; struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq; sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min; @@ -1372,14 +1376,15 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { - struct sfc_flow_rss *rss = &flow->rss_conf; + struct sfc_rss *rss = &sa->rss; + struct sfc_flow_rss *flow_rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; int rc = 0; if (flow->rss) { - unsigned int rss_spread = MIN(rss->rxq_hw_index_max - - rss->rxq_hw_index_min + 1, + unsigned int rss_spread = MIN(flow_rss->rxq_hw_index_max - + flow_rss->rxq_hw_index_min + 1, EFX_MAXRSS); rc = efx_rx_scale_context_alloc(sa->nic, @@ -1391,13 +1396,13 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, EFX_RX_HASHALG_TOEPLITZ, - rss->rss_hash_types, B_TRUE); + flow_rss->rss_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; rc = efx_rx_scale_key_set(sa->nic, efs_rss_context, - rss->rss_key, - sizeof(sa->rss_key)); + flow_rss->rss_key, + sizeof(rss->key)); if (rc != 0) goto fail_scale_key_set; @@ -1411,7 +1416,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, efx_filter_spec_t *spec = &flow->spec.filters[i]; spec->efs_rss_context = efs_rss_context; - spec->efs_dmaq_id = rss->rxq_hw_index_min; + spec->efs_dmaq_id = flow_rss->rxq_hw_index_min; spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS; } } @@ -1430,7 +1435,8 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, * the table entries, and the operation will succeed */ rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context, - rss->rss_tbl, RTE_DIM(rss->rss_tbl)); + flow_rss->rss_tbl, + RTE_DIM(flow_rss->rss_tbl)); if (rc != 0) goto fail_scale_tbl_set; } diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index c30f230..816436a 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -608,7 +608,8 @@ sfc_rx_qflush(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_default_rxq_set_filter(struct sfc_adapter *sa, struct sfc_rxq *rxq) { - boolean_t rss = (sa->rss_channels > 0) ? B_TRUE : B_FALSE; + struct sfc_rss *rss = &sa->rss; + boolean_t need_rss = (rss->channels > 0) ? B_TRUE : B_FALSE; struct sfc_port *port = &sa->port; int rc; @@ -620,7 +621,7 @@ sfc_rx_default_rxq_set_filter(struct sfc_adapter *sa, struct sfc_rxq *rxq) * repeat this step without promiscuous and all-multicast flags set */ retry: - rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common, rss); + rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common, need_rss); if (rc == 0) return 0; else if (rc != EOPNOTSUPP) @@ -970,6 +971,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, struct rte_mempool *mb_pool) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_rss *rss = &sa->rss; int rc; unsigned int rxq_entries; unsigned int evq_entries; @@ -1059,7 +1061,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; - if (sa->hash_support == EFX_RX_HASH_AVAILABLE && sa->rss_channels > 0) + if (rss->hash_support == EFX_RX_HASH_AVAILABLE && rss->channels > 0) info.flags |= SFC_RXQ_FLAG_RSS_HASH; info.rxq_entries = rxq_info->entries; @@ -1178,9 +1180,10 @@ static int sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, struct rte_eth_rss_conf *conf) { - efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types; + struct sfc_rss *rss = &sa->rss; + efx_rx_hash_type_t efx_hash_types = rss->hash_types; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || conf->rss_key != NULL) return EINVAL; @@ -1196,15 +1199,15 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, } if (conf->rss_key != NULL) { - if (conf->rss_key_len != sizeof(sa->rss_key)) { + if (conf->rss_key_len != sizeof(rss->key)) { sfc_err(sa, "RSS key size is wrong (should be %lu)", - sizeof(sa->rss_key)); + sizeof(rss->key)); return EINVAL; } - rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, conf->rss_key, sizeof(rss->key)); } - sa->rss_hash_types = efx_hash_types; + rss->hash_types = efx_hash_types; return 0; } @@ -1212,23 +1215,23 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, static int sfc_rx_rss_config(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; int rc = 0; - if (sa->rss_channels > 0) { + if (rss->channels > 0) { rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, EFX_RX_HASHALG_TOEPLITZ, - sa->rss_hash_types, B_TRUE); + rss->hash_types, B_TRUE); if (rc != 0) goto finish; rc = efx_rx_scale_key_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - sa->rss_key, - sizeof(sa->rss_key)); + rss->key, sizeof(rss->key)); if (rc != 0) goto finish; rc = efx_rx_scale_tbl_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - sa->rss_tbl, RTE_DIM(sa->rss_tbl)); + rss->tbl, RTE_DIM(rss->tbl)); } finish: @@ -1307,6 +1310,7 @@ sfc_rx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) { + struct sfc_rss *rss = &sa->rss; uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) | sfc_rx_get_queue_offload_caps(sa); uint64_t offloads_rejected = rxmode->offloads & ~offloads_supported; @@ -1317,7 +1321,7 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) /* No special checks are required */ break; case ETH_MQ_RX_RSS: - if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) { + if (rss->context_type == EFX_RX_SCALE_UNAVAILABLE) { sfc_err(sa, "RSS is not available"); rc = EINVAL; } @@ -1374,6 +1378,7 @@ sfc_rx_fini_queues(struct sfc_adapter *sa, unsigned int nb_rx_queues) int sfc_rx_configure(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf; const unsigned int nb_rx_queues = sa->eth_dev->data->nb_rx_queues; int rc; @@ -1423,15 +1428,15 @@ sfc_rx_configure(struct sfc_adapter *sa) sa->rxq_count++; } - sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? - MIN(sa->rxq_count, EFX_MAXRSS) : 0; + rss->channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? + MIN(sa->rxq_count, EFX_MAXRSS) : 0; - if (sa->rss_channels > 0) { + if (rss->channels > 0) { struct rte_eth_rss_conf *adv_conf_rss; unsigned int sw_index; for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index) - sa->rss_tbl[sw_index] = sw_index % sa->rss_channels; + rss->tbl[sw_index] = sw_index % rss->channels; adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf; rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss); @@ -1461,9 +1466,11 @@ sfc_rx_configure(struct sfc_adapter *sa) void sfc_rx_close(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; + sfc_rx_fini_queues(sa, 0); - sa->rss_channels = 0; + rss->channels = 0; rte_free(sa->rxq_info); sa->rxq_info = NULL; -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v2 8/8] net/sfc: convert to the advanced EFX RSS interface 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko ` (6 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 7/8] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko @ 2018-04-19 16:41 ` Andrew Rybchenko 2018-04-25 17:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-19 16:41 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> The current code has the following drawbacks: - It is assumed that TCP 4-tuple hash is always supported, which is untrue in the case of packed stream FW variant. - The driver is unaware of UDP hash support available with latest firmware. In order to cope with the mentioned issues, this patch implements the new approach to handle hash settings using the advanced EFX RSS interface. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 24 ++++-- drivers/net/sfc/sfc.h | 12 ++- drivers/net/sfc/sfc_ethdev.c | 23 +++--- drivers/net/sfc/sfc_flow.c | 23 ++++-- drivers/net/sfc/sfc_rx.c | 191 ++++++++++++++++++++++++++++++++++--------- drivers/net/sfc/sfc_rx.h | 8 +- 6 files changed, 217 insertions(+), 64 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 1066a5e..37248bc 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -638,7 +638,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { }; static int -sfc_set_rss_defaults(struct sfc_adapter *sa) +sfc_rss_attach(struct sfc_adapter *sa) { struct sfc_rss *rss = &sa->rss; int rc; @@ -663,16 +663,19 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) if (rc != 0) goto fail_hash_support_get; + rc = sfc_rx_hash_init(sa); + if (rc != 0) + goto fail_rx_hash_init; + efx_rx_fini(sa->nic); efx_ev_fini(sa->nic); efx_intr_fini(sa->nic); - rss->hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); - rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); return 0; +fail_rx_hash_init: fail_hash_support_get: fail_scale_support_get: efx_rx_fini(sa->nic); @@ -687,6 +690,12 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) return rc; } +static void +sfc_rss_detach(struct sfc_adapter *sa) +{ + sfc_rx_hash_fini(sa); +} + int sfc_attach(struct sfc_adapter *sa) { @@ -744,9 +753,9 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_port_attach; - rc = sfc_set_rss_defaults(sa); + rc = sfc_rss_attach(sa); if (rc != 0) - goto fail_set_rss_defaults; + goto fail_rss_attach; rc = sfc_filter_attach(sa); if (rc != 0) @@ -763,7 +772,9 @@ sfc_attach(struct sfc_adapter *sa) return 0; fail_filter_attach: -fail_set_rss_defaults: + sfc_rss_detach(sa); + +fail_rss_attach: sfc_port_detach(sa); fail_port_attach: @@ -795,6 +806,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_flow_fini(sa); sfc_filter_detach(sa); + sfc_rss_detach(sa); sfc_port_detach(sa); sfc_ev_detach(sa); sfc_intr_detach(sa); diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 9c76d7f..3a5f6dc 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,9 +27,6 @@ extern "C" { #endif -/** RSS hash offloads mask */ -#define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP) - /* * +---------------+ * | UNINITIALIZED |<-----------+ @@ -154,10 +151,19 @@ struct sfc_port { uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; }; +struct sfc_rss_hf_rte_to_efx { + uint64_t rte; + efx_rx_hash_type_t efx; +}; + struct sfc_rss { unsigned int channels; efx_rx_scale_context_type_t context_type; efx_rx_hash_support_t hash_support; + efx_rx_hash_alg_t hash_alg; + unsigned int hf_map_nb_entries; + struct sfc_rss_hf_rte_to_efx *hf_map; + efx_rx_hash_type_t hash_types; unsigned int tbl[EFX_RSS_TBL_SIZE]; uint8_t key[EFX_RSS_KEY_SIZE]; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 359d6d2..35a8301 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -153,9 +153,15 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { + uint64_t rte_hf = 0; + unsigned int i; + + for (i = 0; i < rss->hf_map_nb_entries; ++i) + rte_hf |= rss->hf_map[i].rte; + dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; - dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; + dev_info->flow_type_rss_offloads = rte_hf; } /* Initialize to hardware limits */ @@ -1378,7 +1384,7 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, * flags which corresponds to the active EFX configuration stored * locally in 'sfc_adapter' and kept up-to-date */ - rss_conf->rss_hf = sfc_efx_to_rte_hash_type(rss->hash_types); + rss_conf->rss_hf = sfc_rx_hf_efx_to_rte(sa, rss->hash_types); rss_conf->rss_key_len = EFX_RSS_KEY_SIZE; if (rss_conf->rss_key != NULL) rte_memcpy(rss_conf->rss_key, rss->key, EFX_RSS_KEY_SIZE); @@ -1418,18 +1424,14 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, return -EINVAL; } - if ((rss_conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { - sfc_err(sa, "unsupported hash functions requested"); - return -EINVAL; - } - sfc_adapter_lock(sa); - efx_hash_types = sfc_rte_to_efx_hash_type(rss_conf->rss_hf); + rc = sfc_rx_hf_rte_to_efx(sa, rss_conf->rss_hf, &efx_hash_types); + if (rc != 0) + goto fail_rx_hf_rte_to_efx; rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - EFX_RX_HASHALG_TOEPLITZ, - efx_hash_types, B_TRUE); + rss->hash_alg, efx_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; @@ -1459,6 +1461,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, sfc_err(sa, "failed to restore RSS mode"); fail_scale_mode_set: +fail_rx_hf_rte_to_efx: sfc_adapter_unlock(sa); return -rc; } diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index f664cfa..55226f1 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1258,7 +1258,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; unsigned int rxq_hw_index_max; - uint64_t rss_hf; + efx_rx_hash_type_t efx_hash_types; const uint8_t *rss_key; struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf; unsigned int i; @@ -1297,9 +1297,20 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, if (action_rss->level) return -EINVAL; - rss_hf = action_rss->types; - if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0) - return -EINVAL; + 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)) @@ -1314,7 +1325,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, 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 = sfc_rte_to_efx_hash_type(rss_hf); + 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) { @@ -1395,7 +1406,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, goto fail_scale_context_alloc; rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, - EFX_RX_HASHALG_TOEPLITZ, + rss->hash_alg, flow_rss->rss_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 816436a..a4aae1b 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -1132,48 +1132,166 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rte_free(rxq); } -efx_rx_hash_type_t -sfc_rte_to_efx_hash_type(uint64_t rss_hf) +/* + * Mapping between RTE RSS hash functions and their EFX counterparts. + */ +struct sfc_rss_hf_rte_to_efx sfc_rss_hf_map[] = { + { ETH_RSS_NONFRAG_IPV4_TCP, + EFX_RX_HASH(IPV4_TCP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV4_UDP, + EFX_RX_HASH(IPV4_UDP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX, + EFX_RX_HASH(IPV6_TCP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_IPV6_UDP_EX, + EFX_RX_HASH(IPV6_UDP, 4TUPLE) }, + { ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_OTHER, + EFX_RX_HASH(IPV4_TCP, 2TUPLE) | EFX_RX_HASH(IPV4_UDP, 2TUPLE) | + EFX_RX_HASH(IPV4, 2TUPLE) }, + { ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | ETH_RSS_NONFRAG_IPV6_OTHER | + ETH_RSS_IPV6_EX, + EFX_RX_HASH(IPV6_TCP, 2TUPLE) | EFX_RX_HASH(IPV6_UDP, 2TUPLE) | + EFX_RX_HASH(IPV6, 2TUPLE) } +}; + +static efx_rx_hash_type_t +sfc_rx_hash_types_mask_supp(efx_rx_hash_type_t hash_type, + unsigned int *hash_type_flags_supported, + unsigned int nb_hash_type_flags_supported) { - efx_rx_hash_type_t efx_hash_types = 0; + efx_rx_hash_type_t hash_type_masked = 0; + unsigned int i, j; + + for (i = 0; i < nb_hash_type_flags_supported; ++i) { + unsigned int class_tuple_lbn[] = { + EFX_RX_CLASS_IPV4_TCP_LBN, + EFX_RX_CLASS_IPV4_UDP_LBN, + EFX_RX_CLASS_IPV4_LBN, + EFX_RX_CLASS_IPV6_TCP_LBN, + EFX_RX_CLASS_IPV6_UDP_LBN, + EFX_RX_CLASS_IPV6_LBN + }; + + for (j = 0; j < RTE_DIM(class_tuple_lbn); ++j) { + unsigned int tuple_mask = EFX_RX_CLASS_HASH_4TUPLE; + unsigned int flag; + + tuple_mask <<= class_tuple_lbn[j]; + flag = hash_type & tuple_mask; + + if (flag == hash_type_flags_supported[i]) + hash_type_masked |= flag; + } + } + + return hash_type_masked; +} + +int +sfc_rx_hash_init(struct sfc_adapter *sa) +{ + struct sfc_rss *rss = &sa->rss; + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + uint32_t alg_mask = encp->enc_rx_scale_hash_alg_mask; + efx_rx_hash_alg_t alg; + unsigned int flags_supp[EFX_RX_HASH_NFLAGS]; + unsigned int nb_flags_supp; + struct sfc_rss_hf_rte_to_efx *hf_map; + struct sfc_rss_hf_rte_to_efx *entry; + efx_rx_hash_type_t efx_hash_types; + unsigned int i; + int rc; - if ((rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | - ETH_RSS_NONFRAG_IPV4_OTHER)) != 0) - efx_hash_types |= EFX_RX_HASH_IPV4; + if (alg_mask & (1U << EFX_RX_HASHALG_TOEPLITZ)) + alg = EFX_RX_HASHALG_TOEPLITZ; + else if (alg_mask & (1U << EFX_RX_HASHALG_PACKED_STREAM)) + alg = EFX_RX_HASHALG_PACKED_STREAM; + else + return EINVAL; - if ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != 0) - efx_hash_types |= EFX_RX_HASH_TCPIPV4; + rc = efx_rx_scale_hash_flags_get(sa->nic, alg, flags_supp, + &nb_flags_supp); + if (rc != 0) + return rc; - if ((rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | - ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX)) != 0) - efx_hash_types |= EFX_RX_HASH_IPV6; + hf_map = rte_calloc_socket("sfc-rss-hf-map", + RTE_DIM(sfc_rss_hf_map), + sizeof(*hf_map), 0, sa->socket_id); + if (hf_map == NULL) + return ENOMEM; + + entry = hf_map; + efx_hash_types = 0; + for (i = 0; i < RTE_DIM(sfc_rss_hf_map); ++i) { + efx_rx_hash_type_t ht; + + ht = sfc_rx_hash_types_mask_supp(sfc_rss_hf_map[i].efx, + flags_supp, nb_flags_supp); + if (ht != 0) { + entry->rte = sfc_rss_hf_map[i].rte; + entry->efx = ht; + efx_hash_types |= ht; + ++entry; + } + } - if ((rss_hf & (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX)) != 0) - efx_hash_types |= EFX_RX_HASH_TCPIPV6; + rss->hash_alg = alg; + rss->hf_map_nb_entries = (unsigned int)(entry - hf_map); + rss->hf_map = hf_map; + rss->hash_types = efx_hash_types; - return efx_hash_types; + return 0; } -uint64_t -sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) +void +sfc_rx_hash_fini(struct sfc_adapter *sa) { - uint64_t rss_hf = 0; + struct sfc_rss *rss = &sa->rss; - if ((efx_hash_types & EFX_RX_HASH_IPV4) != 0) - rss_hf |= (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | - ETH_RSS_NONFRAG_IPV4_OTHER); + rte_free(rss->hf_map); +} - if ((efx_hash_types & EFX_RX_HASH_TCPIPV4) != 0) - rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; +int +sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte, + efx_rx_hash_type_t *efx) +{ + struct sfc_rss *rss = &sa->rss; + efx_rx_hash_type_t hash_types = 0; + unsigned int i; - if ((efx_hash_types & EFX_RX_HASH_IPV6) != 0) - rss_hf |= (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | - ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX); + for (i = 0; i < rss->hf_map_nb_entries; ++i) { + uint64_t rte_mask = rss->hf_map[i].rte; - if ((efx_hash_types & EFX_RX_HASH_TCPIPV6) != 0) - rss_hf |= (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX); + if ((rte & rte_mask) != 0) { + rte &= ~rte_mask; + hash_types |= rss->hf_map[i].efx; + } + } + + if (rte != 0) { + sfc_err(sa, "unsupported hash functions requested"); + return EINVAL; + } - return rss_hf; + *efx = hash_types; + + return 0; +} + +uint64_t +sfc_rx_hf_efx_to_rte(struct sfc_adapter *sa, efx_rx_hash_type_t efx) +{ + struct sfc_rss *rss = &sa->rss; + uint64_t rte = 0; + unsigned int i; + + for (i = 0; i < rss->hf_map_nb_entries; ++i) { + efx_rx_hash_type_t hash_type = rss->hf_map[i].efx; + + if ((efx & hash_type) == hash_type) + rte |= rss->hf_map[i].rte; + } + + return rte; } static int @@ -1182,20 +1300,19 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, { struct sfc_rss *rss = &sa->rss; efx_rx_hash_type_t efx_hash_types = rss->hash_types; + uint64_t rss_hf = sfc_rx_hf_efx_to_rte(sa, efx_hash_types); + int rc; if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { - if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || + if ((conf->rss_hf != 0 && conf->rss_hf != rss_hf) || conf->rss_key != NULL) return EINVAL; } if (conf->rss_hf != 0) { - if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { - sfc_err(sa, "unsupported hash functions requested"); - return EINVAL; - } - - efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf); + rc = sfc_rx_hf_rte_to_efx(sa, conf->rss_hf, &efx_hash_types); + if (rc != 0) + return rc; } if (conf->rss_key != NULL) { @@ -1220,8 +1337,8 @@ sfc_rx_rss_config(struct sfc_adapter *sa) if (rss->channels > 0) { rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - EFX_RX_HASHALG_TOEPLITZ, - rss->hash_types, B_TRUE); + rss->hash_alg, rss->hash_types, + B_TRUE); if (rc != 0) goto finish; diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h index ea911be..d9e7b0b 100644 --- a/drivers/net/sfc/sfc_rx.h +++ b/drivers/net/sfc/sfc_rx.h @@ -152,8 +152,12 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index); int sfc_rx_qdesc_done(struct sfc_dp_rxq *dp_rxq, unsigned int offset); -efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf); -uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types); +int sfc_rx_hash_init(struct sfc_adapter *sa); +void sfc_rx_hash_fini(struct sfc_adapter *sa); +int sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte, + efx_rx_hash_type_t *efx); +uint64_t sfc_rx_hf_efx_to_rte(struct sfc_adapter *sa, + efx_rx_hash_type_t efx); #ifdef __cplusplus } -- 2.7.4 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko ` (7 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 8/8] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko @ 2018-04-25 17:41 ` Andrew Rybchenko 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:41 UTC (permalink / raw) To: dev; +Cc: Ferruh Yigit On 04/19/2018 07:41 PM, Andrew Rybchenko wrote: > The patch series should be applied on top of [1]. > > checkpatches.sh warnings are bacause of positive errno used inside > the driver. checkpatches.sh checks are OK. > > [1] https://dpdk.org/ml/archives/dev/2018-April/098047.html Self NACK, fix is required in base driver. I'll send v3. ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 0/8] net/sfc: RSS improvements 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko ` (7 preceding siblings ...) 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko ` (8 more replies) 8 siblings, 9 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev The patch series should be applied on top of [1]. checkpatches.sh warnings are bacause of positive errno used inside the driver. checkpatches.sh checks are OK. [1] https://dpdk.org/ml/archives/dev/2018-April/099188.html v2 -> v3: - fix processing of legacy hash type flags in base driver v1 -> v2: - add patch to fix clang build Andrew Rybchenko (1): net/sfc/base: cope with clang warning on negative shift Ivan Malov (7): net/sfc/base: add a new means to control RSS hash net/sfc/base: support more RSS hash configurations net/sfc/base: honour packed stream RSS restriction net/sfc: process RSS settings on Rx configure step net/sfc: remove conditional compilation for RSS net/sfc: factor out RSS fields from adapter info net/sfc: convert to the advanced EFX RSS interface drivers/net/sfc/base/ef10_nic.c | 65 ++++++++- drivers/net/sfc/base/ef10_rx.c | 81 +++++++++++- drivers/net/sfc/base/efx.h | 120 ++++++++++++++++- drivers/net/sfc/base/efx_rx.c | 165 ++++++++++++++++++++++- drivers/net/sfc/base/efx_types.h | 38 ++++-- drivers/net/sfc/base/siena_nic.c | 12 ++ drivers/net/sfc/sfc.c | 37 +++--- drivers/net/sfc/sfc.h | 33 +++-- drivers/net/sfc/sfc_ethdev.c | 76 +++++------ drivers/net/sfc/sfc_flow.c | 75 ++++++----- drivers/net/sfc/sfc_flow.h | 4 - drivers/net/sfc/sfc_rx.c | 275 +++++++++++++++++++++++++++++---------- drivers/net/sfc/sfc_rx.h | 10 +- 13 files changed, 780 insertions(+), 211 deletions(-) -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 1/8] net/sfc/base: cope with clang warning on negative shift 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 2/8] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko ` (7 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev clang 4.0.1-6 on Ubuntu generates false positive warning that shift is negative. It is done regardless of the fact that the branch is not taken because of previous check. The warning is generate in EFX_INSERT_NATIVE32 used by EFX_INSERT_FIELD_NATIVE32. All similar cases are fixed as well. It is undesirable to suppress the warning completely. Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/efx_types.h | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/net/sfc/base/efx_types.h b/drivers/net/sfc/base/efx_types.h index 0581f67f4..65168ab79 100644 --- a/drivers/net/sfc/base/efx_types.h +++ b/drivers/net/sfc/base/efx_types.h @@ -328,6 +328,16 @@ extern int fix_lint; #define FIX_LINT(_x) (_x) #endif +/* + * Saturation arithmetic subtract with minimum equal to zero. + * + * Use saturating arithmetic to ensure a non-negative result. This + * avoids undefined behaviour (and compiler warnings) when used as a + * shift count. + */ +#define EFX_SSUB(_val, _sub) \ + ((_val) > (_sub) ? ((_val) - (_sub)) : 0) + /* * Extract bit field portion [low,high) from the native-endian element * which contains bits [min,max). @@ -347,8 +357,8 @@ extern int fix_lint; ((FIX_LINT(_low > _max) || FIX_LINT(_high < _min)) ? \ 0U : \ ((_low > _min) ? \ - ((_element) >> (_low - _min)) : \ - ((_element) << (_min - _low)))) + ((_element) >> EFX_SSUB(_low, _min)) : \ + ((_element) << EFX_SSUB(_min, _low)))) /* * Extract bit field portion [low,high) from the 64-bit little-endian @@ -537,29 +547,29 @@ extern int fix_lint; (((_low > _max) || (_high < _min)) ? \ 0U : \ ((_low > _min) ? \ - (((uint64_t)(_value)) << (_low - _min)) : \ - (((uint64_t)(_value)) >> (_min - _low)))) + (((uint64_t)(_value)) << EFX_SSUB(_low, _min)) :\ + (((uint64_t)(_value)) >> EFX_SSUB(_min, _low)))) #define EFX_INSERT_NATIVE32(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ ((_low > _min) ? \ - (((uint32_t)(_value)) << (_low - _min)) : \ - (((uint32_t)(_value)) >> (_min - _low)))) + (((uint32_t)(_value)) << EFX_SSUB(_low, _min)) :\ + (((uint32_t)(_value)) >> EFX_SSUB(_min, _low)))) #define EFX_INSERT_NATIVE16(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ (uint16_t)((_low > _min) ? \ - ((_value) << (_low - _min)) : \ - ((_value) >> (_min - _low)))) + ((_value) << EFX_SSUB(_low, _min)) : \ + ((_value) >> EFX_SSUB(_min, _low)))) #define EFX_INSERT_NATIVE8(_min, _max, _low, _high, _value) \ (((_low > _max) || (_high < _min)) ? \ 0U : \ (uint8_t)((_low > _min) ? \ - ((_value) << (_low - _min)) : \ - ((_value) >> (_min - _low)))) + ((_value) << EFX_SSUB(_low, _min)) : \ + ((_value) >> EFX_SSUB(_min, _low)))) /* * Construct bit field portion @@ -1288,22 +1298,22 @@ extern int fix_lint; #define EFX_SHIFT64(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 64) ? \ - ((uint64_t)1 << ((_bit) - (_base))) : \ + ((uint64_t)1 << EFX_SSUB((_bit), (_base))) : \ 0U) #define EFX_SHIFT32(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 32) ? \ - ((uint32_t)1 << ((_bit) - (_base))) : \ + ((uint32_t)1 << EFX_SSUB((_bit),(_base))) : \ 0U) #define EFX_SHIFT16(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 16) ? \ - (uint16_t)(1 << ((_bit) - (_base))) : \ + (uint16_t)(1 << EFX_SSUB((_bit), (_base))) : \ 0U) #define EFX_SHIFT8(_bit, _base) \ (((_bit) >= (_base) && (_bit) < (_base) + 8) ? \ - (uint8_t)(1 << ((_bit) - (_base))) : \ + (uint8_t)(1 << EFX_SSUB((_bit), (_base))) : \ 0U) #define EFX_SET_OWORD_BIT64(_oword, _bit) \ -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 2/8] net/sfc/base: add a new means to control RSS hash 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 3/8] net/sfc/base: support more RSS hash configurations Andrew Rybchenko ` (6 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Currently, libefx has no support for additional RSS modes available with later controllers. In order to support this, libefx should be able to list available hash configurations. This patch provides basic infrastructure for the new interface. The client drivers will be able to query the list of supported hash configurations for a particular hash algorithm. Also, it will be possible to configure hashing by means of new definitions. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_rx.c | 34 +++++++++-- drivers/net/sfc/base/efx.h | 90 ++++++++++++++++++++++++++++ drivers/net/sfc/base/efx_rx.c | 130 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 245 insertions(+), 9 deletions(-) diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index 86a6ac7ef..d1971e38a 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -298,11 +298,32 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_rx_hash_type_t type_ipv4; + efx_rx_hash_type_t type_ipv4_tcp; + efx_rx_hash_type_t type_ipv6; + efx_rx_hash_type_t type_ipv6_tcp; efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; efx_rc_t rc; + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV4_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_TCP_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_LBN == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN); + EFX_STATIC_ASSERT(EFX_RX_CLASS_IPV6_WIDTH == + MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH); + if (rss_context == EF10_RSS_CONTEXT_INVALID) { rc = EINVAL; goto fail1; @@ -318,15 +339,20 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, rss_context); + type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE); + type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE); + type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); + MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, - (type & EFX_RX_HASH_IPV4) ? 1 : 0, + ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, - (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0, + ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, - (type & EFX_RX_HASH_IPV6) ? 1 : 0, + ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0); efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 63f0ba52d..41aa505bc 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -2069,11 +2069,30 @@ typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_TOEPLITZ } efx_rx_hash_alg_t; +/* + * Legacy hash type flags. + * + * They represent standard tuples for distinct traffic classes. + */ #define EFX_RX_HASH_IPV4 (1U << 0) #define EFX_RX_HASH_TCPIPV4 (1U << 1) #define EFX_RX_HASH_IPV6 (1U << 2) #define EFX_RX_HASH_TCPIPV6 (1U << 3) +#define EFX_RX_HASH_LEGACY_MASK \ + (EFX_RX_HASH_IPV4 | \ + EFX_RX_HASH_TCPIPV4 | \ + EFX_RX_HASH_IPV6 | \ + EFX_RX_HASH_TCPIPV6) + +/* + * The type of the argument used by efx_rx_scale_mode_set() to + * provide a means for the client drivers to configure hashing. + * + * A properly constructed value can either be: + * - a combination of legacy flags + * - a combination of EFX_RX_HASH() flags + */ typedef unsigned int efx_rx_hash_type_t; typedef enum efx_rx_hash_support_e { @@ -2092,6 +2111,77 @@ typedef enum efx_rx_scale_context_type_e { EFX_RX_SCALE_SHARED /* Read-only key/indirection table */ } efx_rx_scale_context_type_t; +/* + * Traffic classes eligible for hash computation. + * + * Select packet headers used in computing the receive hash. + * This uses the same encoding as the RSS_MODES field of + * MC_CMD_RSS_CONTEXT_SET_FLAGS. + */ +#define EFX_RX_CLASS_IPV4_TCP_LBN 8 +#define EFX_RX_CLASS_IPV4_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV4_LBN 16 +#define EFX_RX_CLASS_IPV4_WIDTH 4 +#define EFX_RX_CLASS_IPV6_TCP_LBN 20 +#define EFX_RX_CLASS_IPV6_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV6_LBN 28 +#define EFX_RX_CLASS_IPV6_WIDTH 4 + +#define EFX_RX_NCLASSES 4 + +/* + * Ancillary flags used to construct generic hash tuples. + * This uses the same encoding as RSS_MODE_HASH_SELECTOR. + */ +#define EFX_RX_CLASS_HASH_SRC_ADDR (1U << 0) +#define EFX_RX_CLASS_HASH_DST_ADDR (1U << 1) +#define EFX_RX_CLASS_HASH_SRC_PORT (1U << 2) +#define EFX_RX_CLASS_HASH_DST_PORT (1U << 3) + +/* + * Generic hash tuples. + * + * They express combinations of packet fields + * which can contribute to the hash value for + * a particular traffic class. + */ +#define EFX_RX_CLASS_HASH_DISABLE 0 + +#define EFX_RX_CLASS_HASH_2TUPLE \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_DST_ADDR) + +#define EFX_RX_CLASS_HASH_4TUPLE \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_DST_ADDR | \ + EFX_RX_CLASS_HASH_SRC_PORT | \ + EFX_RX_CLASS_HASH_DST_PORT) + +#define EFX_RX_CLASS_HASH_NTUPLES 3 + +/* + * Hash flag constructor. + * + * Resulting flags encode hash tuples for specific traffic classes. + * The client drivers are encouraged to use these flags to form + * a hash type value. + */ +#define EFX_RX_HASH(_class, _tuple) \ + EFX_INSERT_FIELD_NATIVE32(0, 31, \ + EFX_RX_CLASS_##_class, EFX_RX_CLASS_HASH_##_tuple) + +/* + * The maximum number of EFX_RX_HASH() flags. + */ +#define EFX_RX_HASH_NFLAGS (EFX_RX_NCLASSES * EFX_RX_CLASS_HASH_NTUPLES) + +extern __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp); + extern __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index ae79584fe..a9995b4a4 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -294,6 +294,61 @@ efx_rx_scatter_enable( #endif /* EFSYS_OPT_RX_SCATTER */ #if EFSYS_OPT_RX_SCALE + __checkReturn efx_rc_t +efx_rx_scale_hash_flags_get( + __in efx_nic_t *enp, + __in efx_rx_hash_alg_t hash_alg, + __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, + __out unsigned int *nflagsp) +{ + unsigned int *entryp = flags; + efx_rc_t rc; + + if (flags == NULL || nflagsp == NULL) { + rc = EINVAL; + goto fail1; + } + +#define LIST_FLAGS(_entryp, _class, _l4_hashing) \ + do { \ + if (_l4_hashing) \ + *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ + \ + *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ + \ + _NOTE(CONSTANTCONDITION) \ + } while (B_FALSE) + + switch (hash_alg) { + case EFX_RX_HASHALG_TOEPLITZ: + LIST_FLAGS(entryp, IPV4_TCP, B_TRUE); + LIST_FLAGS(entryp, IPV6_TCP, B_TRUE); + LIST_FLAGS(entryp, IPV4, B_FALSE); + LIST_FLAGS(entryp, IPV6, B_FALSE); + break; + + default: + rc = EINVAL; + goto fail2; + } + +#undef LIST_FLAGS + + *nflagsp = (unsigned int)(entryp - flags); + EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS); + + return (0); + +fail2: + EFSYS_PROBE(fail2); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + __checkReturn efx_rc_t efx_rx_hash_default_support_get( __in efx_nic_t *enp, @@ -425,19 +480,80 @@ efx_rx_scale_mode_set( __in boolean_t insert) { const efx_rx_ops_t *erxop = enp->en_erxop; + unsigned int type_flags[EFX_RX_HASH_NFLAGS]; + unsigned int type_nflags; + efx_rx_hash_type_t type_check; + unsigned int i; efx_rc_t rc; EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX); + /* + * Legacy flags and modern bits cannot be + * used at the same time in the hash type. + */ + if ((type & EFX_RX_HASH_LEGACY_MASK) && + (type & ~EFX_RX_HASH_LEGACY_MASK)) { + rc = EINVAL; + goto fail1; + } + + /* + * Translate legacy flags to the new representation + * so that chip-specific handlers will consider the + * new flags only. + */ + if (type & EFX_RX_HASH_IPV4) { + type |= EFX_RX_HASH(IPV4, 2TUPLE); + type |= EFX_RX_HASH(IPV4_TCP, 2TUPLE); + } + + if (type & EFX_RX_HASH_TCPIPV4) + type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE); + + if (type & EFX_RX_HASH_IPV6) { + type |= EFX_RX_HASH(IPV6, 2TUPLE); + type |= EFX_RX_HASH(IPV6_TCP, 2TUPLE); + } + + if (type & EFX_RX_HASH_TCPIPV6) + type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE); + + type &= ~EFX_RX_HASH_LEGACY_MASK; + type_check = type; + + /* + * Get the list of supported hash flags and sanitise the input. + */ + rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags); + if (rc != 0) + goto fail2; + + for (i = 0; i < type_nflags; ++i) { + if ((type_check & type_flags[i]) == type_flags[i]) + type_check &= ~(type_flags[i]); + } + + if (type_check != 0) { + rc = EINVAL; + goto fail3; + } + if (erxop->erxo_scale_mode_set != NULL) { if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg, type, insert)) != 0) - goto fail1; + 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); @@ -881,6 +997,10 @@ siena_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE); + efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE); + efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); efx_rc_t rc; if (rss_context != EFX_RSS_CONTEXT_DEFAULT) { @@ -895,12 +1015,12 @@ siena_rx_scale_mode_set( case EFX_RX_HASHALG_TOEPLITZ: EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert, - type & EFX_RX_HASH_IPV4, - type & EFX_RX_HASH_TCPIPV4); + (type & type_ipv4) == type_ipv4, + (type & type_ipv4_tcp) == type_ipv4_tcp); EFX_RX_TOEPLITZ_IPV6_HASH(enp, - type & EFX_RX_HASH_IPV6, - type & EFX_RX_HASH_TCPIPV6, + (type & type_ipv6) == type_ipv6, + (type & type_ipv6_tcp) == type_ipv6_tcp, rc); if (rc != 0) goto fail2; -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 3/8] net/sfc/base: support more RSS hash configurations 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 2/8] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 4/8] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko ` (5 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Modern firmwares on EF10 adapters have support for more traffic classes eligible for hash computation. Also, it has become possible to adjust hashing per individual class and select distinct packet fields which will be able to contribute to the hash value. This patch adds support for the mentioned features. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_nic.c | 6 +++++ drivers/net/sfc/base/ef10_rx.c | 47 ++++++++++++++++++++++++++++++++++++---- drivers/net/sfc/base/efx.h | 20 +++++++++++++++-- drivers/net/sfc/base/efx_rx.c | 38 +++++++++++++++++++++++++++----- drivers/net/sfc/base/siena_nic.c | 3 +++ 5 files changed, 102 insertions(+), 12 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index ca11ff415..fa4f7a2c6 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1041,6 +1041,12 @@ ef10_get_datapath_caps( } encp->enc_rx_prefix_size = 14; + /* Check if the firmware supports additional RSS modes */ + if (CAP_FLAGS1(req, ADDITIONAL_RSS_MODES)) + encp->enc_rx_scale_additional_modes_supported = B_TRUE; + else + encp->enc_rx_scale_additional_modes_supported = B_FALSE; + /* Check if the firmware supports TSO */ if (CAP_FLAGS1(req, TX_TSO)) encp->enc_fw_assisted_tso_enabled = B_TRUE; diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index d1971e38a..28b800414 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -298,10 +298,12 @@ efx_mcdi_rss_context_set_flags( __in uint32_t rss_context, __in efx_rx_hash_type_t type) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rx_hash_type_t type_ipv4; efx_rx_hash_type_t type_ipv4_tcp; efx_rx_hash_type_t type_ipv6; efx_rx_hash_type_t type_ipv6_tcp; + efx_rx_hash_type_t modes; efx_mcdi_req_t req; uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)]; @@ -339,12 +341,35 @@ efx_mcdi_rss_context_set_flags( MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID, rss_context); - type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE); + type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | EFX_RX_HASH(IPV4_TCP, 2TUPLE) | + EFX_RX_HASH(IPV4_UDP, 2TUPLE); type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); - type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE); + type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | EFX_RX_HASH(IPV6_TCP, 2TUPLE) | + EFX_RX_HASH(IPV6_UDP, 2TUPLE); type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); - MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, + /* + * Create a copy of the original hash type. + * The copy will be used to fill in RSS_MODE bits and + * may be cleared beforehand. The original variable + * and, thus, EN bits will remain unaffected. + */ + modes = type; + + /* + * If the firmware lacks support for additional modes, RSS_MODE + * fields must contain zeros, otherwise the operation will fail. + */ + if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) + modes = 0; + +#define EXTRACT_RSS_MODE(_type, _class) \ + (EFX_EXTRACT_NATIVE(_type, 0, 31, \ + EFX_LOW_BIT(EFX_RX_CLASS_##_class), \ + EFX_HIGH_BIT(EFX_RX_CLASS_##_class)) & \ + EFX_MASK32(EFX_RX_CLASS_##_class)) + + MCDI_IN_POPULATE_DWORD_10(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN, ((type & type_ipv4) == type_ipv4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, @@ -352,7 +377,21 @@ efx_mcdi_rss_context_set_flags( RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, ((type & type_ipv6) == type_ipv6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0); + ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0, + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV4), + RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_TCP), + RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6_UDP), + RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE, + EXTRACT_RSS_MODE(modes, IPV6)); + +#undef EXTRACT_RSS_MODE efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 41aa505bc..21d2545f2 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1192,6 +1192,7 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; uint32_t enc_rx_scale_max_exclusive_contexts; + boolean_t enc_rx_scale_additional_modes_supported; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; #endif /* EFSYS_OPT_LOOPBACK */ @@ -2120,14 +2121,18 @@ typedef enum efx_rx_scale_context_type_e { */ #define EFX_RX_CLASS_IPV4_TCP_LBN 8 #define EFX_RX_CLASS_IPV4_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV4_UDP_LBN 12 +#define EFX_RX_CLASS_IPV4_UDP_WIDTH 4 #define EFX_RX_CLASS_IPV4_LBN 16 #define EFX_RX_CLASS_IPV4_WIDTH 4 #define EFX_RX_CLASS_IPV6_TCP_LBN 20 #define EFX_RX_CLASS_IPV6_TCP_WIDTH 4 +#define EFX_RX_CLASS_IPV6_UDP_LBN 24 +#define EFX_RX_CLASS_IPV6_UDP_WIDTH 4 #define EFX_RX_CLASS_IPV6_LBN 28 #define EFX_RX_CLASS_IPV6_WIDTH 4 -#define EFX_RX_NCLASSES 4 +#define EFX_RX_NCLASSES 6 /* * Ancillary flags used to construct generic hash tuples. @@ -2147,17 +2152,28 @@ typedef enum efx_rx_scale_context_type_e { */ #define EFX_RX_CLASS_HASH_DISABLE 0 +#define EFX_RX_CLASS_HASH_1TUPLE_SRC EFX_RX_CLASS_HASH_SRC_ADDR +#define EFX_RX_CLASS_HASH_1TUPLE_DST EFX_RX_CLASS_HASH_DST_ADDR + #define EFX_RX_CLASS_HASH_2TUPLE \ (EFX_RX_CLASS_HASH_SRC_ADDR | \ EFX_RX_CLASS_HASH_DST_ADDR) +#define EFX_RX_CLASS_HASH_2TUPLE_SRC \ + (EFX_RX_CLASS_HASH_SRC_ADDR | \ + EFX_RX_CLASS_HASH_SRC_PORT) + +#define EFX_RX_CLASS_HASH_2TUPLE_DST \ + (EFX_RX_CLASS_HASH_DST_ADDR | \ + EFX_RX_CLASS_HASH_DST_PORT) + #define EFX_RX_CLASS_HASH_4TUPLE \ (EFX_RX_CLASS_HASH_SRC_ADDR | \ EFX_RX_CLASS_HASH_DST_ADDR | \ EFX_RX_CLASS_HASH_SRC_PORT | \ EFX_RX_CLASS_HASH_DST_PORT) -#define EFX_RX_CLASS_HASH_NTUPLES 3 +#define EFX_RX_CLASS_HASH_NTUPLES 7 /* * Hash flag constructor. diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index a9995b4a4..b02c7f68d 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -301,6 +301,8 @@ efx_rx_scale_hash_flags_get( __inout_ecount(EFX_RX_HASH_NFLAGS) unsigned int *flags, __out unsigned int *nflagsp) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t additional_modes; unsigned int *entryp = flags; efx_rc_t rc; @@ -309,12 +311,28 @@ efx_rx_scale_hash_flags_get( goto fail1; } -#define LIST_FLAGS(_entryp, _class, _l4_hashing) \ + additional_modes = encp->enc_rx_scale_additional_modes_supported; + +#define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ do { \ - if (_l4_hashing) \ + if (_l4_hashing) { \ *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE); \ \ + if (_additional_modes) { \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_DST); \ + *(_entryp++) = \ + EFX_RX_HASH(_class, 2TUPLE_SRC); \ + } \ + } \ + \ *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE); \ + \ + if (_additional_modes) { \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST); \ + *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC); \ + } \ + \ *(_entryp++) = EFX_RX_HASH(_class, DISABLE); \ \ _NOTE(CONSTANTCONDITION) \ @@ -322,10 +340,16 @@ efx_rx_scale_hash_flags_get( switch (hash_alg) { case EFX_RX_HASHALG_TOEPLITZ: - LIST_FLAGS(entryp, IPV4_TCP, B_TRUE); - LIST_FLAGS(entryp, IPV6_TCP, B_TRUE); - LIST_FLAGS(entryp, IPV4, B_FALSE); - LIST_FLAGS(entryp, IPV6, B_FALSE); + LIST_FLAGS(entryp, IPV4_TCP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, B_TRUE, additional_modes); + + if (additional_modes) { + LIST_FLAGS(entryp, IPV4_UDP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, B_TRUE, additional_modes); + } + + LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); + LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes); break; default: @@ -507,6 +531,7 @@ efx_rx_scale_mode_set( if (type & EFX_RX_HASH_IPV4) { type |= EFX_RX_HASH(IPV4, 2TUPLE); type |= EFX_RX_HASH(IPV4_TCP, 2TUPLE); + type |= EFX_RX_HASH(IPV4_UDP, 2TUPLE); } if (type & EFX_RX_HASH_TCPIPV4) @@ -515,6 +540,7 @@ efx_rx_scale_mode_set( if (type & EFX_RX_HASH_IPV6) { type |= EFX_RX_HASH(IPV6, 2TUPLE); type |= EFX_RX_HASH(IPV6_TCP, 2TUPLE); + type |= EFX_RX_HASH(IPV6_UDP, 2TUPLE); } if (type & EFX_RX_HASH_TCPIPV6) diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index 6e57de468..0d6d07151 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -118,6 +118,9 @@ siena_board_cfg( /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; + /* There is no support for additional RSS modes */ + encp->enc_rx_scale_additional_modes_supported = B_FALSE; + encp->enc_tx_dma_desc_size_max = EFX_MASK32(FSF_AZ_TX_KER_BYTE_COUNT); /* Fragments must not span 4k boundaries. */ encp->enc_tx_dma_desc_boundary = 4096; -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 4/8] net/sfc/base: honour packed stream RSS restriction 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko ` (2 preceding siblings ...) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 3/8] net/sfc/base: support more RSS hash configurations Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 5/8] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko ` (4 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> Packed stream firmware variant on EF10 adapters has a number of properties which must be taken into account: - Only one exclusive RSS context is available per port. - Only IP addresses can contribute to the hash value. Huntington and Medford have one more limitation which is important for the drivers capable of packed stream: - Hash algorithm is non-standard (i.e. non-Toeplitz). This implies XORing together source + destination IP addresses (or last four bytes in the case of IPv6) and using the result as the input to a Toeplitz hash. This patch provides a number of improvements in order to treat the mentioned limitations in the common code. If the firmware variant is packed stream, the list of supported hash tuples will include less variants, and the maximum number of RSS contexts will be set to one. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/base/ef10_nic.c | 59 +++++++++++++++++++++++++++++++++++----- drivers/net/sfc/base/ef10_rx.c | 6 ++-- drivers/net/sfc/base/efx.h | 14 +++++++++- drivers/net/sfc/base/efx_rx.c | 17 +++++++++--- drivers/net/sfc/base/siena_nic.c | 9 ++++++ 5 files changed, 91 insertions(+), 14 deletions(-) diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c index fa4f7a2c6..e1f1c2e3e 100644 --- a/drivers/net/sfc/base/ef10_nic.c +++ b/drivers/net/sfc/base/ef10_nic.c @@ -1239,11 +1239,63 @@ ef10_get_datapath_caps( else encp->enc_fec_counters = B_FALSE; + if (CAP_FLAGS1(req, RX_RSS_LIMITED)) { + /* Only one exclusive RSS context is available per port. */ + encp->enc_rx_scale_max_exclusive_contexts = 1; + + switch (enp->en_family) { + case EFX_FAMILY_MEDFORD2: + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_TOEPLITZ); + break; + + case EFX_FAMILY_MEDFORD: + case EFX_FAMILY_HUNTINGTON: + /* + * Packed stream firmware variant maintains a + * non-standard algorithm for hash computation. + * It implies explicit XORing together + * source + destination IP addresses (or last + * four bytes in the case of IPv6) and using the + * resulting value as the input to a Toeplitz hash. + */ + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_PACKED_STREAM); + break; + + default: + rc = EINVAL; + goto fail5; + } + + /* Port numbers cannot contribute to the hash value */ + encp->enc_rx_scale_l4_hash_supported = B_FALSE; + } else { + /* + * Maximum number of exclusive RSS contexts. + * EF10 hardware supports 64 in total, but 6 are reserved + * for shared contexts. They are a global resource so + * not all may be available. + */ + encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; + + encp->enc_rx_scale_hash_alg_mask = + (1U << EFX_RX_HASHALG_TOEPLITZ); + + /* + * It is possible to use port numbers as + * the input data for hash computation. + */ + encp->enc_rx_scale_l4_hash_supported = B_TRUE; + } + #undef CAP_FLAGS1 #undef CAP_FLAGS2 return (0); +fail5: + EFSYS_PROBE(fail5); fail4: EFSYS_PROBE(fail4); fail3: @@ -1713,13 +1765,6 @@ ef10_nic_board_cfg( /* Alignment for WPTR updates */ encp->enc_rx_push_align = EF10_RX_WPTR_ALIGN; - /* - * Maximum number of exclusive RSS contexts. EF10 hardware supports 64 - * in total, but 6 are reserved for shared contexts. They are a global - * resource so not all may be available. - */ - encp->enc_rx_scale_max_exclusive_contexts = 64 - 6; - encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_DZ_RX_KER_BYTE_CNT); /* No boundary crossing limits */ encp->enc_tx_dma_desc_boundary = 0; diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index 28b800414..cd35c2a7b 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -616,12 +616,13 @@ ef10_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; efx_rc_t rc; - EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ); EFSYS_ASSERT3U(insert, ==, B_TRUE); - if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) { + if ((encp->enc_rx_scale_hash_alg_mask & (1U << alg)) == 0 || + insert == B_FALSE) { rc = EINVAL; goto fail1; } @@ -770,6 +771,7 @@ ef10_rx_prefix_hash( _NOTE(ARGUNUSED(enp)) switch (func) { + case EFX_RX_HASHALG_PACKED_STREAM: case EFX_RX_HASHALG_TOEPLITZ: return (buffer[0] | (buffer[1] << 8) | diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h index 21d2545f2..0b75f0fce 100644 --- a/drivers/net/sfc/base/efx.h +++ b/drivers/net/sfc/base/efx.h @@ -1192,6 +1192,16 @@ typedef struct efx_nic_cfg_s { uint32_t enc_rx_buf_align_start; uint32_t enc_rx_buf_align_end; uint32_t enc_rx_scale_max_exclusive_contexts; + /* + * Mask of supported hash algorithms. + * Hash algorithm types are used as the bit indices. + */ + uint32_t enc_rx_scale_hash_alg_mask; + /* + * Indicates whether port numbers can be included to the + * input data for hash computation. + */ + boolean_t enc_rx_scale_l4_hash_supported; boolean_t enc_rx_scale_additional_modes_supported; #if EFSYS_OPT_LOOPBACK efx_qword_t enc_loopback_types[EFX_LINK_NMODES]; @@ -2067,7 +2077,9 @@ efx_rx_scatter_enable( typedef enum efx_rx_hash_alg_e { EFX_RX_HASHALG_LFSR = 0, - EFX_RX_HASHALG_TOEPLITZ + EFX_RX_HASHALG_TOEPLITZ, + EFX_RX_HASHALG_PACKED_STREAM, + EFX_RX_NHASHALGS } efx_rx_hash_alg_t; /* diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index b02c7f68d..dd09946ff 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -302,6 +302,7 @@ efx_rx_scale_hash_flags_get( __out unsigned int *nflagsp) { efx_nic_cfg_t *encp = &enp->en_nic_cfg; + boolean_t l4; boolean_t additional_modes; unsigned int *entryp = flags; efx_rc_t rc; @@ -311,6 +312,7 @@ efx_rx_scale_hash_flags_get( goto fail1; } + l4 = encp->enc_rx_scale_l4_hash_supported; additional_modes = encp->enc_rx_scale_additional_modes_supported; #define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes) \ @@ -339,13 +341,20 @@ efx_rx_scale_hash_flags_get( } while (B_FALSE) switch (hash_alg) { + case EFX_RX_HASHALG_PACKED_STREAM: + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + /* FALLTHRU */ case EFX_RX_HASHALG_TOEPLITZ: - LIST_FLAGS(entryp, IPV4_TCP, B_TRUE, additional_modes); - LIST_FLAGS(entryp, IPV6_TCP, B_TRUE, additional_modes); + if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) + break; + + LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes); if (additional_modes) { - LIST_FLAGS(entryp, IPV4_UDP, B_TRUE, additional_modes); - LIST_FLAGS(entryp, IPV6_UDP, B_TRUE, additional_modes); + LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes); + LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes); } LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes); diff --git a/drivers/net/sfc/base/siena_nic.c b/drivers/net/sfc/base/siena_nic.c index 0d6d07151..c3a949539 100644 --- a/drivers/net/sfc/base/siena_nic.c +++ b/drivers/net/sfc/base/siena_nic.c @@ -118,6 +118,15 @@ siena_board_cfg( /* There is one RSS context per function */ encp->enc_rx_scale_max_exclusive_contexts = 1; + encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_LFSR); + encp->enc_rx_scale_hash_alg_mask |= (1U << EFX_RX_HASHALG_TOEPLITZ); + + /* + * It is always possible to use port numbers + * as the input data for hash computation. + */ + encp->enc_rx_scale_l4_hash_supported = B_TRUE; + /* There is no support for additional RSS modes */ encp->enc_rx_scale_additional_modes_supported = B_FALSE; -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 5/8] net/sfc: process RSS settings on Rx configure step 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko ` (3 preceding siblings ...) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 4/8] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 6/8] net/sfc: remove conditional compilation for RSS Andrew Rybchenko ` (3 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov, stable From: Ivan Malov <ivan.malov@oktetlabs.ru> One may submit advanced RSS settings as part of rte_eth_conf to customise RSS configuration from the very beginning. Currently the driver does not check that piece of settings and proceeds with default choices for RSS hash functions and RSS key. This patch implements the required processing. Fixes: 4ec1fc3ba881 ("net/sfc: add basic stubs for RSS support on driver attach") Cc: stable@dpdk.org Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc_rx.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 734ce24f7..fca39311b 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -1188,6 +1188,41 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) #endif #if EFSYS_OPT_RX_SCALE +static int +sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, + struct rte_eth_rss_conf *conf) +{ + efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types; + + if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || + conf->rss_key != NULL) + return EINVAL; + } + + if (conf->rss_hf != 0) { + if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { + sfc_err(sa, "unsupported hash functions requested"); + return EINVAL; + } + + efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf); + } + + if (conf->rss_key != NULL) { + if (conf->rss_key_len != sizeof(sa->rss_key)) { + sfc_err(sa, "RSS key size is wrong (should be %lu)", + sizeof(sa->rss_key)); + return EINVAL; + } + rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key)); + } + + sa->rss_hash_types = efx_hash_types; + + return 0; +} + static int sfc_rx_rss_config(struct sfc_adapter *sa) { @@ -1416,16 +1451,23 @@ sfc_rx_configure(struct sfc_adapter *sa) MIN(sa->rxq_count, EFX_MAXRSS) : 0; if (sa->rss_channels > 0) { + struct rte_eth_rss_conf *adv_conf_rss; unsigned int sw_index; for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index) sa->rss_tbl[sw_index] = sw_index % sa->rss_channels; + + adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf; + rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss); + if (rc != 0) + goto fail_rx_process_adv_conf_rss; } #endif done: return 0; +fail_rx_process_adv_conf_rss: fail_rx_qinit_info: fail_rxqs_realloc: fail_rxqs_alloc: -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 6/8] net/sfc: remove conditional compilation for RSS 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko ` (4 preceding siblings ...) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 5/8] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 7/8] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko ` (2 subsequent siblings) 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> RSS is one of the most valuable features in the driver, and one would hardly need to disable it at build time. This patch withdraws unnecessary conditionals for RSS snippets. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 10 ---------- drivers/net/sfc/sfc.h | 4 ---- drivers/net/sfc/sfc_ethdev.c | 6 ------ drivers/net/sfc/sfc_flow.c | 10 ---------- drivers/net/sfc/sfc_flow.h | 4 ---- drivers/net/sfc/sfc_rx.c | 25 ------------------------- drivers/net/sfc/sfc_rx.h | 2 -- 7 files changed, 61 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index dcf5eb866..41ebd0b4c 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -623,7 +623,6 @@ sfc_mem_bar_fini(struct sfc_adapter *sa) memset(ebp, 0, sizeof(*ebp)); } -#if EFSYS_OPT_RX_SCALE /* * A fixed RSS key which has a property of being symmetric * (symmetrical flows are distributed to the same CPU) @@ -637,9 +636,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, }; -#endif -#if EFSYS_OPT_RX_SCALE static int sfc_set_rss_defaults(struct sfc_adapter *sa) { @@ -688,13 +685,6 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) fail_intr_init: return rc; } -#else -static int -sfc_set_rss_defaults(__rte_unused struct sfc_adapter *sa) -{ - return 0; -} -#endif int sfc_attach(struct sfc_adapter *sa) diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 65a4df24a..805f211cc 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,10 +27,8 @@ extern "C" { #endif -#if EFSYS_OPT_RX_SCALE /** RSS hash offloads mask */ #define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP) -#endif /* * +---------------+ @@ -227,13 +225,11 @@ struct sfc_adapter { unsigned int rss_channels; -#if EFSYS_OPT_RX_SCALE efx_rx_scale_context_type_t rss_support; efx_rx_hash_support_t hash_support; efx_rx_hash_type_t rss_hash_types; unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; uint8_t rss_key[EFX_RSS_KEY_SIZE]; -#endif /* * Shared memory copy of the Rx datapath name to be used by diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 47d7a8609..be6d44982 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -151,13 +151,11 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; -#if EFSYS_OPT_RX_SCALE if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) { dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; } -#endif /* Initialize to hardware limits */ dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS; @@ -1357,7 +1355,6 @@ sfc_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, return sfc_dev_udp_tunnel_op(dev, tunnel_udp, SFC_UDP_TUNNEL_DEL_PORT); } -#if EFSYS_OPT_RX_SCALE static int sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) @@ -1568,7 +1565,6 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, SFC_ASSERT(rc >= 0); return -rc; } -#endif static int sfc_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, @@ -1663,12 +1659,10 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .mac_addr_set = sfc_mac_addr_set, .udp_tunnel_port_add = sfc_dev_udp_tunnel_port_add, .udp_tunnel_port_del = sfc_dev_udp_tunnel_port_del, -#if EFSYS_OPT_RX_SCALE .reta_update = sfc_dev_rss_reta_update, .reta_query = sfc_dev_rss_reta_query, .rss_hash_update = sfc_dev_rss_hash_update, .rss_hash_conf_get = sfc_dev_rss_hash_conf_get, -#endif .filter_ctrl = sfc_dev_filter_ctrl, .set_mc_addr_list = sfc_set_mc_addr_list, .rxq_info_get = sfc_rx_queue_info_get, diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 78fb05a39..bf08834f8 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1246,7 +1246,6 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, return 0; } -#if EFSYS_OPT_RX_SCALE static int sfc_flow_parse_rss(struct sfc_adapter *sa, const struct rte_flow_action_rss *rss, @@ -1322,7 +1321,6 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, return 0; } -#endif /* EFSYS_OPT_RX_SCALE */ static int sfc_flow_spec_flush(struct sfc_adapter *sa, struct sfc_flow_spec *spec, @@ -1372,7 +1370,6 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { -#if EFSYS_OPT_RX_SCALE struct sfc_flow_rss *rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; @@ -1449,9 +1446,6 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, fail_scale_context_alloc: return rc; -#else /* !EFSYS_OPT_RX_SCALE */ - return sfc_flow_spec_insert(sa, &flow->spec); -#endif /* EFSYS_OPT_RX_SCALE */ } static int @@ -1464,7 +1458,6 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, if (rc != 0) return rc; -#if EFSYS_OPT_RX_SCALE if (flow->rss) { /* * All specifications for a given flow rule have the same RSS @@ -1475,7 +1468,6 @@ sfc_flow_filter_remove(struct sfc_adapter *sa, rc = efx_rx_scale_context_free(sa->nic, spec->efs_rss_context); } -#endif /* EFSYS_OPT_RX_SCALE */ return rc; } @@ -1522,7 +1514,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, is_specified = B_TRUE; break; -#if EFSYS_OPT_RX_SCALE case RTE_FLOW_ACTION_TYPE_RSS: rc = sfc_flow_parse_rss(sa, actions->conf, flow); if (rc != 0) { @@ -1534,7 +1525,6 @@ sfc_flow_parse_actions(struct sfc_adapter *sa, is_specified = B_TRUE; break; -#endif /* EFSYS_OPT_RX_SCALE */ case RTE_FLOW_ACTION_TYPE_DROP: flow->spec.template.efs_dmaq_id = diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h index 69dd6838f..71ec18cb9 100644 --- a/drivers/net/sfc/sfc_flow.h +++ b/drivers/net/sfc/sfc_flow.h @@ -26,7 +26,6 @@ extern "C" { */ #define SF_FLOW_SPEC_NB_FILTERS_MAX 8 -#if EFSYS_OPT_RX_SCALE /* RSS configuration storage */ struct sfc_flow_rss { unsigned int rxq_hw_index_min; @@ -35,7 +34,6 @@ struct sfc_flow_rss { uint8_t rss_key[EFX_RSS_KEY_SIZE]; unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; }; -#endif /* EFSYS_OPT_RX_SCALE */ /* Filter specification storage */ struct sfc_flow_spec { @@ -50,10 +48,8 @@ struct sfc_flow_spec { /* PMD-specific definition of the opaque type from rte_flow.h */ struct rte_flow { struct sfc_flow_spec spec; /* flow spec for hardware filter(s) */ -#if EFSYS_OPT_RX_SCALE boolean_t rss; /* RSS toggle */ struct sfc_flow_rss rss_conf; /* RSS configuration */ -#endif /* EFSYS_OPT_RX_SCALE */ TAILQ_ENTRY(rte_flow) entries; /* flow list entries */ }; diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index fca39311b..c30f2309e 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -184,7 +184,6 @@ sfc_efx_supported_ptypes_get(__rte_unused uint32_t tunnel_encaps) return ptypes; } -#if EFSYS_OPT_RX_SCALE static void sfc_efx_rx_set_rss_hash(struct sfc_efx_rxq *rxq, unsigned int flags, struct rte_mbuf *m) @@ -205,14 +204,6 @@ sfc_efx_rx_set_rss_hash(struct sfc_efx_rxq *rxq, unsigned int flags, m->ol_flags |= PKT_RX_RSS_HASH; } } -#else -static void -sfc_efx_rx_set_rss_hash(__rte_unused struct sfc_efx_rxq *rxq, - __rte_unused unsigned int flags, - __rte_unused struct rte_mbuf *m) -{ -} -#endif static uint16_t sfc_efx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) @@ -1068,10 +1059,8 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; -#if EFSYS_OPT_RX_SCALE if (sa->hash_support == EFX_RX_HASH_AVAILABLE && sa->rss_channels > 0) info.flags |= SFC_RXQ_FLAG_RSS_HASH; -#endif info.rxq_entries = rxq_info->entries; info.rxq_hw_ring = rxq->mem.esm_base; @@ -1141,7 +1130,6 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rte_free(rxq); } -#if EFSYS_OPT_RX_SCALE efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf) { @@ -1185,9 +1173,7 @@ sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) return rss_hf; } -#endif -#if EFSYS_OPT_RX_SCALE static int sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, struct rte_eth_rss_conf *conf) @@ -1248,13 +1234,6 @@ sfc_rx_rss_config(struct sfc_adapter *sa) finish: return rc; } -#else -static int -sfc_rx_rss_config(__rte_unused struct sfc_adapter *sa) -{ - return 0; -} -#endif int sfc_rx_start(struct sfc_adapter *sa) @@ -1337,14 +1316,12 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) case ETH_MQ_RX_NONE: /* No special checks are required */ break; -#if EFSYS_OPT_RX_SCALE case ETH_MQ_RX_RSS: if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) { sfc_err(sa, "RSS is not available"); rc = EINVAL; } break; -#endif default: sfc_err(sa, "Rx multi-queue mode %u not supported", rxmode->mq_mode); @@ -1446,7 +1423,6 @@ sfc_rx_configure(struct sfc_adapter *sa) sa->rxq_count++; } -#if EFSYS_OPT_RX_SCALE sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? MIN(sa->rxq_count, EFX_MAXRSS) : 0; @@ -1462,7 +1438,6 @@ sfc_rx_configure(struct sfc_adapter *sa) if (rc != 0) goto fail_rx_process_adv_conf_rss; } -#endif done: return 0; diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h index 6706ee6fc..ea911be58 100644 --- a/drivers/net/sfc/sfc_rx.h +++ b/drivers/net/sfc/sfc_rx.h @@ -152,10 +152,8 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index); int sfc_rx_qdesc_done(struct sfc_dp_rxq *dp_rxq, unsigned int offset); -#if EFSYS_OPT_RX_SCALE efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf); uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types); -#endif #ifdef __cplusplus } -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 7/8] net/sfc: factor out RSS fields from adapter info 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko ` (5 preceding siblings ...) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 6/8] net/sfc: remove conditional compilation for RSS Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 8/8] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko 2018-04-25 23:19 ` [dpdk-dev] [PATCH v3 0/8] net/sfc: RSS improvements Ferruh Yigit 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> RSS handling will need more sophisticated fields in the adapter context storage in future patches. This patch groups existing fields in a dedicated structure and updates the rest of the code. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 9 ++++---- drivers/net/sfc/sfc.h | 17 ++++++++------- drivers/net/sfc/sfc_ethdev.c | 49 ++++++++++++++++++++++++------------------- drivers/net/sfc/sfc_flow.c | 50 +++++++++++++++++++++++++------------------- drivers/net/sfc/sfc_rx.c | 47 +++++++++++++++++++++++------------------ 5 files changed, 97 insertions(+), 75 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 41ebd0b4c..1066a5edb 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -640,6 +640,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { static int sfc_set_rss_defaults(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; int rc; rc = efx_intr_init(sa->nic, sa->intr.type, NULL); @@ -654,11 +655,11 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) if (rc != 0) goto fail_rx_init; - rc = efx_rx_scale_default_support_get(sa->nic, &sa->rss_support); + rc = efx_rx_scale_default_support_get(sa->nic, &rss->context_type); if (rc != 0) goto fail_scale_support_get; - rc = efx_rx_hash_default_support_get(sa->nic, &sa->hash_support); + rc = efx_rx_hash_default_support_get(sa->nic, &rss->hash_support); if (rc != 0) goto fail_hash_support_get; @@ -666,9 +667,9 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) efx_ev_fini(sa->nic); efx_intr_fini(sa->nic); - sa->rss_hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); + rss->hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); - rte_memcpy(sa->rss_key, default_rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); return 0; diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 805f211cc..9c76d7fa4 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -154,6 +154,15 @@ struct sfc_port { uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; }; +struct sfc_rss { + unsigned int channels; + efx_rx_scale_context_type_t context_type; + efx_rx_hash_support_t hash_support; + efx_rx_hash_type_t hash_types; + unsigned int tbl[EFX_RSS_TBL_SIZE]; + uint8_t key[EFX_RSS_KEY_SIZE]; +}; + /* Adapter private data */ struct sfc_adapter { /* @@ -223,13 +232,7 @@ struct sfc_adapter { boolean_t tso; - unsigned int rss_channels; - - efx_rx_scale_context_type_t rss_support; - efx_rx_hash_support_t hash_support; - efx_rx_hash_type_t rss_hash_types; - unsigned int rss_tbl[EFX_RSS_TBL_SIZE]; - uint8_t rss_key[EFX_RSS_KEY_SIZE]; + struct sfc_rss rss; /* * Shared memory copy of the Rx datapath name to be used by diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index be6d44982..359d6d2f3 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -85,6 +85,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct sfc_adapter *sa = dev->data->dev_private; const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_rss *rss = &sa->rss; uint64_t txq_offloads_def = 0; sfc_log_init(sa, "entry"); @@ -151,7 +152,7 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) if (~sa->dp_tx->features & SFC_DP_TX_FEAT_REFCNT) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; - if (sa->rss_support != EFX_RX_SCALE_UNAVAILABLE) { + if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; @@ -1360,12 +1361,13 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; - if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated) + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated) return -ENOTSUP; - if (sa->rss_channels == 0) + if (rss->channels == 0) return -EINVAL; sfc_adapter_lock(sa); @@ -1376,10 +1378,10 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, * flags which corresponds to the active EFX configuration stored * locally in 'sfc_adapter' and kept up-to-date */ - rss_conf->rss_hf = sfc_efx_to_rte_hash_type(sa->rss_hash_types); + rss_conf->rss_hf = sfc_efx_to_rte_hash_type(rss->hash_types); rss_conf->rss_key_len = EFX_RSS_KEY_SIZE; if (rss_conf->rss_key != NULL) - rte_memcpy(rss_conf->rss_key, sa->rss_key, EFX_RSS_KEY_SIZE); + rte_memcpy(rss_conf->rss_key, rss->key, EFX_RSS_KEY_SIZE); sfc_adapter_unlock(sa); @@ -1391,6 +1393,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; unsigned int efx_hash_types; int rc = 0; @@ -1398,20 +1401,20 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, if (port->isolated) return -ENOTSUP; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { sfc_err(sa, "RSS is not available"); return -ENOTSUP; } - if (sa->rss_channels == 0) { + if (rss->channels == 0) { sfc_err(sa, "RSS is not configured"); return -EINVAL; } if ((rss_conf->rss_key != NULL) && - (rss_conf->rss_key_len != sizeof(sa->rss_key))) { + (rss_conf->rss_key_len != sizeof(rss->key))) { sfc_err(sa, "RSS key size is wrong (should be %lu)", - sizeof(sa->rss_key)); + sizeof(rss->key)); return -EINVAL; } @@ -1435,15 +1438,15 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, rc = efx_rx_scale_key_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, rss_conf->rss_key, - sizeof(sa->rss_key)); + sizeof(rss->key)); if (rc != 0) goto fail_scale_key_set; } - rte_memcpy(sa->rss_key, rss_conf->rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, rss_conf->rss_key, sizeof(rss->key)); } - sa->rss_hash_types = efx_hash_types; + rss->hash_types = efx_hash_types; sfc_adapter_unlock(sa); @@ -1452,7 +1455,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, fail_scale_key_set: if (efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, EFX_RX_HASHALG_TOEPLITZ, - sa->rss_hash_types, B_TRUE) != 0) + rss->hash_types, B_TRUE) != 0) sfc_err(sa, "failed to restore RSS mode"); fail_scale_mode_set: @@ -1466,13 +1469,14 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, uint16_t reta_size) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; int entry; - if ((sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) || port->isolated) + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE || port->isolated) return -ENOTSUP; - if (sa->rss_channels == 0) + if (rss->channels == 0) return -EINVAL; if (reta_size != EFX_RSS_TBL_SIZE) @@ -1485,7 +1489,7 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, int grp_idx = entry % RTE_RETA_GROUP_SIZE; if ((reta_conf[grp].mask >> grp_idx) & 1) - reta_conf[grp].reta[grp_idx] = sa->rss_tbl[entry]; + reta_conf[grp].reta[grp_idx] = rss->tbl[entry]; } sfc_adapter_unlock(sa); @@ -1499,6 +1503,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, uint16_t reta_size) { struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_rss *rss = &sa->rss; struct sfc_port *port = &sa->port; unsigned int *rss_tbl_new; uint16_t entry; @@ -1508,12 +1513,12 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, if (port->isolated) return -ENOTSUP; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { sfc_err(sa, "RSS is not available"); return -ENOTSUP; } - if (sa->rss_channels == 0) { + if (rss->channels == 0) { sfc_err(sa, "RSS is not configured"); return -EINVAL; } @@ -1524,13 +1529,13 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, return -EINVAL; } - rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(sa->rss_tbl), 0); + rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(rss->tbl), 0); if (rss_tbl_new == NULL) return -ENOMEM; sfc_adapter_lock(sa); - rte_memcpy(rss_tbl_new, sa->rss_tbl, sizeof(sa->rss_tbl)); + rte_memcpy(rss_tbl_new, rss->tbl, sizeof(rss->tbl)); for (entry = 0; entry < reta_size; entry++) { int grp_idx = entry % RTE_RETA_GROUP_SIZE; @@ -1539,7 +1544,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, grp = &reta_conf[entry / RTE_RETA_GROUP_SIZE]; if (grp->mask & (1ull << grp_idx)) { - if (grp->reta[grp_idx] >= sa->rss_channels) { + if (grp->reta[grp_idx] >= rss->channels) { rc = EINVAL; goto bad_reta_entry; } @@ -1554,7 +1559,7 @@ sfc_dev_rss_reta_update(struct rte_eth_dev *dev, goto fail_scale_tbl_set; } - rte_memcpy(sa->rss_tbl, rss_tbl_new, sizeof(sa->rss_tbl)); + rte_memcpy(rss->tbl, rss_tbl_new, sizeof(rss->tbl)); fail_scale_tbl_set: bad_reta_entry: diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index bf08834f8..fb9c5bfe2 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1248,18 +1248,20 @@ sfc_flow_parse_queue(struct sfc_adapter *sa, static int sfc_flow_parse_rss(struct sfc_adapter *sa, - const struct rte_flow_action_rss *rss, + const struct rte_flow_action_rss *action_rss, struct rte_flow *flow) { + struct sfc_rss *rss = &sa->rss; unsigned int rxq_sw_index; struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; unsigned int rxq_hw_index_max; + uint64_t rss_hf; const uint8_t *rss_key; struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf; unsigned int i; - if (rss->queue_num == 0) + if (action_rss->queue_num == 0) return -EINVAL; rxq_sw_index = sa->rxq_count - 1; @@ -1267,8 +1269,8 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, rxq_hw_index_min = rxq->hw_index; rxq_hw_index_max = 0; - for (i = 0; i < rss->queue_num; ++i) { - rxq_sw_index = rss->queue[i]; + for (i = 0; i < action_rss->queue_num; ++i) { + rxq_sw_index = action_rss->queue[i]; if (rxq_sw_index >= sa->rxq_count) return -EINVAL; @@ -1282,7 +1284,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, rxq_hw_index_max = rxq->hw_index; } - switch (rss->func) { + switch (action_rss->func) { case RTE_ETH_HASH_FUNCTION_DEFAULT: case RTE_ETH_HASH_FUNCTION_TOEPLITZ: break; @@ -1290,30 +1292,32 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, return -EINVAL; } - if (rss->level) + if (action_rss->level) return -EINVAL; - if ((rss->types & ~SFC_RSS_OFFLOADS) != 0) + rss_hf = action_rss->types; + if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0) return -EINVAL; - if (rss->key_len) { - if (rss->key_len != sizeof(sa->rss_key)) + if (action_rss->key_len) { + if (action_rss->key_len != sizeof(rss->key)) return -EINVAL; - rss_key = rss->key; + rss_key = action_rss->key; } else { - rss_key = sa->rss_key; + rss_key = rss->key; } flow->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 = sfc_rte_to_efx_hash_type(rss->types); - rte_memcpy(sfc_rss_conf->rss_key, rss_key, sizeof(sa->rss_key)); + sfc_rss_conf->rss_hash_types = sfc_rte_to_efx_hash_type(rss_hf); + 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 rxq_sw_index = rss->queue[i % rss->queue_num]; + unsigned int nb_queues = action_rss->queue_num; + unsigned int rxq_sw_index = action_rss->queue[i % nb_queues]; struct sfc_rxq *rxq = sa->rxq_info[rxq_sw_index].rxq; sfc_rss_conf->rss_tbl[i] = rxq->hw_index - rxq_hw_index_min; @@ -1370,14 +1374,15 @@ static int sfc_flow_filter_insert(struct sfc_adapter *sa, struct rte_flow *flow) { - struct sfc_flow_rss *rss = &flow->rss_conf; + struct sfc_rss *rss = &sa->rss; + struct sfc_flow_rss *flow_rss = &flow->rss_conf; uint32_t efs_rss_context = EFX_RSS_CONTEXT_DEFAULT; unsigned int i; int rc = 0; if (flow->rss) { - unsigned int rss_spread = MIN(rss->rxq_hw_index_max - - rss->rxq_hw_index_min + 1, + unsigned int rss_spread = MIN(flow_rss->rxq_hw_index_max - + flow_rss->rxq_hw_index_min + 1, EFX_MAXRSS); rc = efx_rx_scale_context_alloc(sa->nic, @@ -1389,13 +1394,13 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, EFX_RX_HASHALG_TOEPLITZ, - rss->rss_hash_types, B_TRUE); + flow_rss->rss_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; rc = efx_rx_scale_key_set(sa->nic, efs_rss_context, - rss->rss_key, - sizeof(sa->rss_key)); + flow_rss->rss_key, + sizeof(rss->key)); if (rc != 0) goto fail_scale_key_set; @@ -1409,7 +1414,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, efx_filter_spec_t *spec = &flow->spec.filters[i]; spec->efs_rss_context = efs_rss_context; - spec->efs_dmaq_id = rss->rxq_hw_index_min; + spec->efs_dmaq_id = flow_rss->rxq_hw_index_min; spec->efs_flags |= EFX_FILTER_FLAG_RX_RSS; } } @@ -1428,7 +1433,8 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, * the table entries, and the operation will succeed */ rc = efx_rx_scale_tbl_set(sa->nic, efs_rss_context, - rss->rss_tbl, RTE_DIM(rss->rss_tbl)); + flow_rss->rss_tbl, + RTE_DIM(flow_rss->rss_tbl)); if (rc != 0) goto fail_scale_tbl_set; } diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index c30f2309e..816436a6c 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -608,7 +608,8 @@ sfc_rx_qflush(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_default_rxq_set_filter(struct sfc_adapter *sa, struct sfc_rxq *rxq) { - boolean_t rss = (sa->rss_channels > 0) ? B_TRUE : B_FALSE; + struct sfc_rss *rss = &sa->rss; + boolean_t need_rss = (rss->channels > 0) ? B_TRUE : B_FALSE; struct sfc_port *port = &sa->port; int rc; @@ -620,7 +621,7 @@ sfc_rx_default_rxq_set_filter(struct sfc_adapter *sa, struct sfc_rxq *rxq) * repeat this step without promiscuous and all-multicast flags set */ retry: - rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common, rss); + rc = efx_mac_filter_default_rxq_set(sa->nic, rxq->common, need_rss); if (rc == 0) return 0; else if (rc != EOPNOTSUPP) @@ -970,6 +971,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, struct rte_mempool *mb_pool) { const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + struct sfc_rss *rss = &sa->rss; int rc; unsigned int rxq_entries; unsigned int evq_entries; @@ -1059,7 +1061,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, unsigned int sw_index, info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; - if (sa->hash_support == EFX_RX_HASH_AVAILABLE && sa->rss_channels > 0) + if (rss->hash_support == EFX_RX_HASH_AVAILABLE && rss->channels > 0) info.flags |= SFC_RXQ_FLAG_RSS_HASH; info.rxq_entries = rxq_info->entries; @@ -1178,9 +1180,10 @@ static int sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, struct rte_eth_rss_conf *conf) { - efx_rx_hash_type_t efx_hash_types = sa->rss_hash_types; + struct sfc_rss *rss = &sa->rss; + efx_rx_hash_type_t efx_hash_types = rss->hash_types; - if (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE) { + if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || conf->rss_key != NULL) return EINVAL; @@ -1196,15 +1199,15 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, } if (conf->rss_key != NULL) { - if (conf->rss_key_len != sizeof(sa->rss_key)) { + if (conf->rss_key_len != sizeof(rss->key)) { sfc_err(sa, "RSS key size is wrong (should be %lu)", - sizeof(sa->rss_key)); + sizeof(rss->key)); return EINVAL; } - rte_memcpy(sa->rss_key, conf->rss_key, sizeof(sa->rss_key)); + rte_memcpy(rss->key, conf->rss_key, sizeof(rss->key)); } - sa->rss_hash_types = efx_hash_types; + rss->hash_types = efx_hash_types; return 0; } @@ -1212,23 +1215,23 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, static int sfc_rx_rss_config(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; int rc = 0; - if (sa->rss_channels > 0) { + if (rss->channels > 0) { rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, EFX_RX_HASHALG_TOEPLITZ, - sa->rss_hash_types, B_TRUE); + rss->hash_types, B_TRUE); if (rc != 0) goto finish; rc = efx_rx_scale_key_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - sa->rss_key, - sizeof(sa->rss_key)); + rss->key, sizeof(rss->key)); if (rc != 0) goto finish; rc = efx_rx_scale_tbl_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - sa->rss_tbl, RTE_DIM(sa->rss_tbl)); + rss->tbl, RTE_DIM(rss->tbl)); } finish: @@ -1307,6 +1310,7 @@ sfc_rx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index) static int sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) { + struct sfc_rss *rss = &sa->rss; uint64_t offloads_supported = sfc_rx_get_dev_offload_caps(sa) | sfc_rx_get_queue_offload_caps(sa); uint64_t offloads_rejected = rxmode->offloads & ~offloads_supported; @@ -1317,7 +1321,7 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode) /* No special checks are required */ break; case ETH_MQ_RX_RSS: - if (sa->rss_support == EFX_RX_SCALE_UNAVAILABLE) { + if (rss->context_type == EFX_RX_SCALE_UNAVAILABLE) { sfc_err(sa, "RSS is not available"); rc = EINVAL; } @@ -1374,6 +1378,7 @@ sfc_rx_fini_queues(struct sfc_adapter *sa, unsigned int nb_rx_queues) int sfc_rx_configure(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; struct rte_eth_conf *dev_conf = &sa->eth_dev->data->dev_conf; const unsigned int nb_rx_queues = sa->eth_dev->data->nb_rx_queues; int rc; @@ -1423,15 +1428,15 @@ sfc_rx_configure(struct sfc_adapter *sa) sa->rxq_count++; } - sa->rss_channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? - MIN(sa->rxq_count, EFX_MAXRSS) : 0; + rss->channels = (dev_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) ? + MIN(sa->rxq_count, EFX_MAXRSS) : 0; - if (sa->rss_channels > 0) { + if (rss->channels > 0) { struct rte_eth_rss_conf *adv_conf_rss; unsigned int sw_index; for (sw_index = 0; sw_index < EFX_RSS_TBL_SIZE; ++sw_index) - sa->rss_tbl[sw_index] = sw_index % sa->rss_channels; + rss->tbl[sw_index] = sw_index % rss->channels; adv_conf_rss = &dev_conf->rx_adv_conf.rss_conf; rc = sfc_rx_process_adv_conf_rss(sa, adv_conf_rss); @@ -1461,9 +1466,11 @@ sfc_rx_configure(struct sfc_adapter *sa) void sfc_rx_close(struct sfc_adapter *sa) { + struct sfc_rss *rss = &sa->rss; + sfc_rx_fini_queues(sa, 0); - sa->rss_channels = 0; + rss->channels = 0; rte_free(sa->rxq_info); sa->rxq_info = NULL; -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* [dpdk-dev] [PATCH v3 8/8] net/sfc: convert to the advanced EFX RSS interface 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko ` (6 preceding siblings ...) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 7/8] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko @ 2018-04-25 17:51 ` Andrew Rybchenko 2018-04-25 23:19 ` [dpdk-dev] [PATCH v3 0/8] net/sfc: RSS improvements Ferruh Yigit 8 siblings, 0 replies; 29+ messages in thread From: Andrew Rybchenko @ 2018-04-25 17:51 UTC (permalink / raw) To: dev; +Cc: Ivan Malov From: Ivan Malov <ivan.malov@oktetlabs.ru> The current code has the following drawbacks: - It is assumed that TCP 4-tuple hash is always supported, which is untrue in the case of packed stream FW variant. - The driver is unaware of UDP hash support available with latest firmware. In order to cope with the mentioned issues, this patch implements the new approach to handle hash settings using the advanced EFX RSS interface. Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> --- drivers/net/sfc/sfc.c | 24 ++++-- drivers/net/sfc/sfc.h | 12 ++- drivers/net/sfc/sfc_ethdev.c | 23 +++--- drivers/net/sfc/sfc_flow.c | 23 ++++-- drivers/net/sfc/sfc_rx.c | 191 ++++++++++++++++++++++++++++++++++--------- drivers/net/sfc/sfc_rx.h | 8 +- 6 files changed, 217 insertions(+), 64 deletions(-) diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 1066a5edb..37248bccc 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -638,7 +638,7 @@ static const uint8_t default_rss_key[EFX_RSS_KEY_SIZE] = { }; static int -sfc_set_rss_defaults(struct sfc_adapter *sa) +sfc_rss_attach(struct sfc_adapter *sa) { struct sfc_rss *rss = &sa->rss; int rc; @@ -663,16 +663,19 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) if (rc != 0) goto fail_hash_support_get; + rc = sfc_rx_hash_init(sa); + if (rc != 0) + goto fail_rx_hash_init; + efx_rx_fini(sa->nic); efx_ev_fini(sa->nic); efx_intr_fini(sa->nic); - rss->hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS); - rte_memcpy(rss->key, default_rss_key, sizeof(rss->key)); return 0; +fail_rx_hash_init: fail_hash_support_get: fail_scale_support_get: efx_rx_fini(sa->nic); @@ -687,6 +690,12 @@ sfc_set_rss_defaults(struct sfc_adapter *sa) return rc; } +static void +sfc_rss_detach(struct sfc_adapter *sa) +{ + sfc_rx_hash_fini(sa); +} + int sfc_attach(struct sfc_adapter *sa) { @@ -744,9 +753,9 @@ sfc_attach(struct sfc_adapter *sa) if (rc != 0) goto fail_port_attach; - rc = sfc_set_rss_defaults(sa); + rc = sfc_rss_attach(sa); if (rc != 0) - goto fail_set_rss_defaults; + goto fail_rss_attach; rc = sfc_filter_attach(sa); if (rc != 0) @@ -763,7 +772,9 @@ sfc_attach(struct sfc_adapter *sa) return 0; fail_filter_attach: -fail_set_rss_defaults: + sfc_rss_detach(sa); + +fail_rss_attach: sfc_port_detach(sa); fail_port_attach: @@ -795,6 +806,7 @@ sfc_detach(struct sfc_adapter *sa) sfc_flow_fini(sa); sfc_filter_detach(sa); + sfc_rss_detach(sa); sfc_port_detach(sa); sfc_ev_detach(sa); sfc_intr_detach(sa); diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 9c76d7fa4..3a5f6dcb2 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -27,9 +27,6 @@ extern "C" { #endif -/** RSS hash offloads mask */ -#define SFC_RSS_OFFLOADS (ETH_RSS_IP | ETH_RSS_TCP) - /* * +---------------+ * | UNINITIALIZED |<-----------+ @@ -154,10 +151,19 @@ struct sfc_port { uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES]; }; +struct sfc_rss_hf_rte_to_efx { + uint64_t rte; + efx_rx_hash_type_t efx; +}; + struct sfc_rss { unsigned int channels; efx_rx_scale_context_type_t context_type; efx_rx_hash_support_t hash_support; + efx_rx_hash_alg_t hash_alg; + unsigned int hf_map_nb_entries; + struct sfc_rss_hf_rte_to_efx *hf_map; + efx_rx_hash_type_t hash_types; unsigned int tbl[EFX_RSS_TBL_SIZE]; uint8_t key[EFX_RSS_KEY_SIZE]; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 359d6d2f3..35a8301a9 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -153,9 +153,15 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOREFCOUNT; if (rss->context_type != EFX_RX_SCALE_UNAVAILABLE) { + uint64_t rte_hf = 0; + unsigned int i; + + for (i = 0; i < rss->hf_map_nb_entries; ++i) + rte_hf |= rss->hf_map[i].rte; + dev_info->reta_size = EFX_RSS_TBL_SIZE; dev_info->hash_key_size = EFX_RSS_KEY_SIZE; - dev_info->flow_type_rss_offloads = SFC_RSS_OFFLOADS; + dev_info->flow_type_rss_offloads = rte_hf; } /* Initialize to hardware limits */ @@ -1378,7 +1384,7 @@ sfc_dev_rss_hash_conf_get(struct rte_eth_dev *dev, * flags which corresponds to the active EFX configuration stored * locally in 'sfc_adapter' and kept up-to-date */ - rss_conf->rss_hf = sfc_efx_to_rte_hash_type(rss->hash_types); + rss_conf->rss_hf = sfc_rx_hf_efx_to_rte(sa, rss->hash_types); rss_conf->rss_key_len = EFX_RSS_KEY_SIZE; if (rss_conf->rss_key != NULL) rte_memcpy(rss_conf->rss_key, rss->key, EFX_RSS_KEY_SIZE); @@ -1418,18 +1424,14 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, return -EINVAL; } - if ((rss_conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { - sfc_err(sa, "unsupported hash functions requested"); - return -EINVAL; - } - sfc_adapter_lock(sa); - efx_hash_types = sfc_rte_to_efx_hash_type(rss_conf->rss_hf); + rc = sfc_rx_hf_rte_to_efx(sa, rss_conf->rss_hf, &efx_hash_types); + if (rc != 0) + goto fail_rx_hf_rte_to_efx; rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - EFX_RX_HASHALG_TOEPLITZ, - efx_hash_types, B_TRUE); + rss->hash_alg, efx_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; @@ -1459,6 +1461,7 @@ sfc_dev_rss_hash_update(struct rte_eth_dev *dev, sfc_err(sa, "failed to restore RSS mode"); fail_scale_mode_set: +fail_rx_hf_rte_to_efx: sfc_adapter_unlock(sa); return -rc; } diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index fb9c5bfe2..41b5987b2 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1256,7 +1256,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, struct sfc_rxq *rxq; unsigned int rxq_hw_index_min; unsigned int rxq_hw_index_max; - uint64_t rss_hf; + efx_rx_hash_type_t efx_hash_types; const uint8_t *rss_key; struct sfc_flow_rss *sfc_rss_conf = &flow->rss_conf; unsigned int i; @@ -1295,9 +1295,20 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, if (action_rss->level) return -EINVAL; - rss_hf = action_rss->types; - if ((rss_hf & ~SFC_RSS_OFFLOADS) != 0) - return -EINVAL; + 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)) @@ -1312,7 +1323,7 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, 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 = sfc_rte_to_efx_hash_type(rss_hf); + 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) { @@ -1393,7 +1404,7 @@ sfc_flow_filter_insert(struct sfc_adapter *sa, goto fail_scale_context_alloc; rc = efx_rx_scale_mode_set(sa->nic, efs_rss_context, - EFX_RX_HASHALG_TOEPLITZ, + rss->hash_alg, flow_rss->rss_hash_types, B_TRUE); if (rc != 0) goto fail_scale_mode_set; diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 816436a6c..a4aae1bab 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -1132,48 +1132,166 @@ sfc_rx_qfini(struct sfc_adapter *sa, unsigned int sw_index) rte_free(rxq); } -efx_rx_hash_type_t -sfc_rte_to_efx_hash_type(uint64_t rss_hf) +/* + * Mapping between RTE RSS hash functions and their EFX counterparts. + */ +struct sfc_rss_hf_rte_to_efx sfc_rss_hf_map[] = { + { ETH_RSS_NONFRAG_IPV4_TCP, + EFX_RX_HASH(IPV4_TCP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV4_UDP, + EFX_RX_HASH(IPV4_UDP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX, + EFX_RX_HASH(IPV6_TCP, 4TUPLE) }, + { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_IPV6_UDP_EX, + EFX_RX_HASH(IPV6_UDP, 4TUPLE) }, + { ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_OTHER, + EFX_RX_HASH(IPV4_TCP, 2TUPLE) | EFX_RX_HASH(IPV4_UDP, 2TUPLE) | + EFX_RX_HASH(IPV4, 2TUPLE) }, + { ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | ETH_RSS_NONFRAG_IPV6_OTHER | + ETH_RSS_IPV6_EX, + EFX_RX_HASH(IPV6_TCP, 2TUPLE) | EFX_RX_HASH(IPV6_UDP, 2TUPLE) | + EFX_RX_HASH(IPV6, 2TUPLE) } +}; + +static efx_rx_hash_type_t +sfc_rx_hash_types_mask_supp(efx_rx_hash_type_t hash_type, + unsigned int *hash_type_flags_supported, + unsigned int nb_hash_type_flags_supported) { - efx_rx_hash_type_t efx_hash_types = 0; + efx_rx_hash_type_t hash_type_masked = 0; + unsigned int i, j; + + for (i = 0; i < nb_hash_type_flags_supported; ++i) { + unsigned int class_tuple_lbn[] = { + EFX_RX_CLASS_IPV4_TCP_LBN, + EFX_RX_CLASS_IPV4_UDP_LBN, + EFX_RX_CLASS_IPV4_LBN, + EFX_RX_CLASS_IPV6_TCP_LBN, + EFX_RX_CLASS_IPV6_UDP_LBN, + EFX_RX_CLASS_IPV6_LBN + }; + + for (j = 0; j < RTE_DIM(class_tuple_lbn); ++j) { + unsigned int tuple_mask = EFX_RX_CLASS_HASH_4TUPLE; + unsigned int flag; + + tuple_mask <<= class_tuple_lbn[j]; + flag = hash_type & tuple_mask; + + if (flag == hash_type_flags_supported[i]) + hash_type_masked |= flag; + } + } + + return hash_type_masked; +} + +int +sfc_rx_hash_init(struct sfc_adapter *sa) +{ + struct sfc_rss *rss = &sa->rss; + const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + uint32_t alg_mask = encp->enc_rx_scale_hash_alg_mask; + efx_rx_hash_alg_t alg; + unsigned int flags_supp[EFX_RX_HASH_NFLAGS]; + unsigned int nb_flags_supp; + struct sfc_rss_hf_rte_to_efx *hf_map; + struct sfc_rss_hf_rte_to_efx *entry; + efx_rx_hash_type_t efx_hash_types; + unsigned int i; + int rc; - if ((rss_hf & (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | - ETH_RSS_NONFRAG_IPV4_OTHER)) != 0) - efx_hash_types |= EFX_RX_HASH_IPV4; + if (alg_mask & (1U << EFX_RX_HASHALG_TOEPLITZ)) + alg = EFX_RX_HASHALG_TOEPLITZ; + else if (alg_mask & (1U << EFX_RX_HASHALG_PACKED_STREAM)) + alg = EFX_RX_HASHALG_PACKED_STREAM; + else + return EINVAL; - if ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != 0) - efx_hash_types |= EFX_RX_HASH_TCPIPV4; + rc = efx_rx_scale_hash_flags_get(sa->nic, alg, flags_supp, + &nb_flags_supp); + if (rc != 0) + return rc; - if ((rss_hf & (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | - ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX)) != 0) - efx_hash_types |= EFX_RX_HASH_IPV6; + hf_map = rte_calloc_socket("sfc-rss-hf-map", + RTE_DIM(sfc_rss_hf_map), + sizeof(*hf_map), 0, sa->socket_id); + if (hf_map == NULL) + return ENOMEM; + + entry = hf_map; + efx_hash_types = 0; + for (i = 0; i < RTE_DIM(sfc_rss_hf_map); ++i) { + efx_rx_hash_type_t ht; + + ht = sfc_rx_hash_types_mask_supp(sfc_rss_hf_map[i].efx, + flags_supp, nb_flags_supp); + if (ht != 0) { + entry->rte = sfc_rss_hf_map[i].rte; + entry->efx = ht; + efx_hash_types |= ht; + ++entry; + } + } - if ((rss_hf & (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX)) != 0) - efx_hash_types |= EFX_RX_HASH_TCPIPV6; + rss->hash_alg = alg; + rss->hf_map_nb_entries = (unsigned int)(entry - hf_map); + rss->hf_map = hf_map; + rss->hash_types = efx_hash_types; - return efx_hash_types; + return 0; } -uint64_t -sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types) +void +sfc_rx_hash_fini(struct sfc_adapter *sa) { - uint64_t rss_hf = 0; + struct sfc_rss *rss = &sa->rss; - if ((efx_hash_types & EFX_RX_HASH_IPV4) != 0) - rss_hf |= (ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | - ETH_RSS_NONFRAG_IPV4_OTHER); + rte_free(rss->hf_map); +} - if ((efx_hash_types & EFX_RX_HASH_TCPIPV4) != 0) - rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; +int +sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte, + efx_rx_hash_type_t *efx) +{ + struct sfc_rss *rss = &sa->rss; + efx_rx_hash_type_t hash_types = 0; + unsigned int i; - if ((efx_hash_types & EFX_RX_HASH_IPV6) != 0) - rss_hf |= (ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | - ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_IPV6_EX); + for (i = 0; i < rss->hf_map_nb_entries; ++i) { + uint64_t rte_mask = rss->hf_map[i].rte; - if ((efx_hash_types & EFX_RX_HASH_TCPIPV6) != 0) - rss_hf |= (ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_IPV6_TCP_EX); + if ((rte & rte_mask) != 0) { + rte &= ~rte_mask; + hash_types |= rss->hf_map[i].efx; + } + } + + if (rte != 0) { + sfc_err(sa, "unsupported hash functions requested"); + return EINVAL; + } - return rss_hf; + *efx = hash_types; + + return 0; +} + +uint64_t +sfc_rx_hf_efx_to_rte(struct sfc_adapter *sa, efx_rx_hash_type_t efx) +{ + struct sfc_rss *rss = &sa->rss; + uint64_t rte = 0; + unsigned int i; + + for (i = 0; i < rss->hf_map_nb_entries; ++i) { + efx_rx_hash_type_t hash_type = rss->hf_map[i].efx; + + if ((efx & hash_type) == hash_type) + rte |= rss->hf_map[i].rte; + } + + return rte; } static int @@ -1182,20 +1300,19 @@ sfc_rx_process_adv_conf_rss(struct sfc_adapter *sa, { struct sfc_rss *rss = &sa->rss; efx_rx_hash_type_t efx_hash_types = rss->hash_types; + uint64_t rss_hf = sfc_rx_hf_efx_to_rte(sa, efx_hash_types); + int rc; if (rss->context_type != EFX_RX_SCALE_EXCLUSIVE) { - if ((conf->rss_hf != 0 && conf->rss_hf != SFC_RSS_OFFLOADS) || + if ((conf->rss_hf != 0 && conf->rss_hf != rss_hf) || conf->rss_key != NULL) return EINVAL; } if (conf->rss_hf != 0) { - if ((conf->rss_hf & ~SFC_RSS_OFFLOADS) != 0) { - sfc_err(sa, "unsupported hash functions requested"); - return EINVAL; - } - - efx_hash_types = sfc_rte_to_efx_hash_type(conf->rss_hf); + rc = sfc_rx_hf_rte_to_efx(sa, conf->rss_hf, &efx_hash_types); + if (rc != 0) + return rc; } if (conf->rss_key != NULL) { @@ -1220,8 +1337,8 @@ sfc_rx_rss_config(struct sfc_adapter *sa) if (rss->channels > 0) { rc = efx_rx_scale_mode_set(sa->nic, EFX_RSS_CONTEXT_DEFAULT, - EFX_RX_HASHALG_TOEPLITZ, - rss->hash_types, B_TRUE); + rss->hash_alg, rss->hash_types, + B_TRUE); if (rc != 0) goto finish; diff --git a/drivers/net/sfc/sfc_rx.h b/drivers/net/sfc/sfc_rx.h index ea911be58..d9e7b0b18 100644 --- a/drivers/net/sfc/sfc_rx.h +++ b/drivers/net/sfc/sfc_rx.h @@ -152,8 +152,12 @@ unsigned int sfc_rx_qdesc_npending(struct sfc_adapter *sa, unsigned int sw_index); int sfc_rx_qdesc_done(struct sfc_dp_rxq *dp_rxq, unsigned int offset); -efx_rx_hash_type_t sfc_rte_to_efx_hash_type(uint64_t rss_hf); -uint64_t sfc_efx_to_rte_hash_type(efx_rx_hash_type_t efx_hash_types); +int sfc_rx_hash_init(struct sfc_adapter *sa); +void sfc_rx_hash_fini(struct sfc_adapter *sa); +int sfc_rx_hf_rte_to_efx(struct sfc_adapter *sa, uint64_t rte, + efx_rx_hash_type_t *efx); +uint64_t sfc_rx_hf_efx_to_rte(struct sfc_adapter *sa, + efx_rx_hash_type_t efx); #ifdef __cplusplus } -- 2.14.1 ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [dpdk-dev] [PATCH v3 0/8] net/sfc: RSS improvements 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko ` (7 preceding siblings ...) 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 8/8] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko @ 2018-04-25 23:19 ` Ferruh Yigit 8 siblings, 0 replies; 29+ messages in thread From: Ferruh Yigit @ 2018-04-25 23:19 UTC (permalink / raw) To: Andrew Rybchenko, dev On 4/25/2018 6:51 PM, Andrew Rybchenko wrote: > The patch series should be applied on top of [1]. > > checkpatches.sh warnings are bacause of positive errno used inside > the driver. checkpatches.sh checks are OK. > > [1] https://dpdk.org/ml/archives/dev/2018-April/099188.html > > v2 -> v3: > - fix processing of legacy hash type flags in base driver > > v1 -> v2: > - add patch to fix clang build > > > Andrew Rybchenko (1): > net/sfc/base: cope with clang warning on negative shift > > Ivan Malov (7): > net/sfc/base: add a new means to control RSS hash > net/sfc/base: support more RSS hash configurations > net/sfc/base: honour packed stream RSS restriction > net/sfc: process RSS settings on Rx configure step > net/sfc: remove conditional compilation for RSS > net/sfc: factor out RSS fields from adapter info > net/sfc: convert to the advanced EFX RSS interface Series applied to dpdk-next-net/master, thanks. ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2018-04-25 23:20 UTC | newest] Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-04-06 17:21 [dpdk-dev] [PATCH 0/7] net/sfc: RSS improvements Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 1/7] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko 2018-04-19 16:17 ` Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 2/7] net/sfc/base: support more RSS hash configurations Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 3/7] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 4/7] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 5/7] net/sfc: remove conditional compilation for RSS Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 6/7] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko 2018-04-06 17:21 ` [dpdk-dev] [PATCH 7/7] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 2/8] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 3/8] net/sfc/base: support more RSS hash configurations Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 4/8] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 5/8] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 6/8] net/sfc: remove conditional compilation for RSS Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 7/8] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko 2018-04-19 16:41 ` [dpdk-dev] [PATCH v2 8/8] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko 2018-04-25 17:41 ` [dpdk-dev] [PATCH v2 0/8] net/sfc: RSS improvements Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 " Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 1/8] net/sfc/base: cope with clang warning on negative shift Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 2/8] net/sfc/base: add a new means to control RSS hash Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 3/8] net/sfc/base: support more RSS hash configurations Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 4/8] net/sfc/base: honour packed stream RSS restriction Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 5/8] net/sfc: process RSS settings on Rx configure step Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 6/8] net/sfc: remove conditional compilation for RSS Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 7/8] net/sfc: factor out RSS fields from adapter info Andrew Rybchenko 2018-04-25 17:51 ` [dpdk-dev] [PATCH v3 8/8] net/sfc: convert to the advanced EFX RSS interface Andrew Rybchenko 2018-04-25 23:19 ` [dpdk-dev] [PATCH v3 0/8] net/sfc: RSS improvements Ferruh Yigit
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).