From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id CC1354C93 for ; Mon, 10 Sep 2018 11:33:55 +0200 (CEST) X-Virus-Scanned: Proofpoint Essentials engine Received: from webmail.solarflare.com (webmail.solarflare.com [12.187.104.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us1.ppe-hosted.com (Proofpoint Essentials ESMTP Server) with ESMTPS id BAF41780055; Mon, 10 Sep 2018 09:33:54 +0000 (UTC) Received: from ocex03.SolarFlarecom.com (10.20.40.36) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 10 Sep 2018 02:33:49 -0700 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4 via Frontend Transport; Mon, 10 Sep 2018 02:33:48 -0700 Received: from ukv-loginhost.uk.solarflarecom.com (ukv-loginhost.uk.solarflarecom.com [10.17.10.39]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id w8A9XlLU023888; Mon, 10 Sep 2018 10:33:47 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1]) by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id 32F5D1626D1; Mon, 10 Sep 2018 10:33:47 +0100 (BST) From: Andrew Rybchenko To: CC: Ivan Malov Date: Mon, 10 Sep 2018 10:33:33 +0100 Message-ID: <1536572016-18134-35-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1536572016-18134-1-git-send-email-arybchenko@solarflare.com> References: <1536572016-18134-1-git-send-email-arybchenko@solarflare.com> MIME-Version: 1.0 Content-Type: text/plain X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.5.1010-24084.005 X-TM-AS-Result: No-8.007000-4.000000-10 X-TMASE-MatchedRID: iQrkRPi2z4Oij3mVveD3jkf49ONH0RaScbniFtnyrsgcZFsYO/SuCItG OKQ7HhnlwQTsYEGvCCFK6v/k7v1MvX45uBZmw2094Tzr6T25NkcWTveLitVUgX5ydmNMNXqDzEV DGnc+EfJ58+KA2Q9fh7eZ8aseN9WR4Yh4UkkUHv4mZusHWPhfCiseSAhqf1rRh8BhJvgqWBmUfD H3TE2AyKhWUh6TDC8ZlVYqtnwyOe0yRohotsnq5x+WEMjoO9WWI9yVcHNDU7a5ZjHyzYrpGvpjH Y4YxLsFFpeo9dvWKT4sEvH5fPCQRce4Woyb+kVFV6iWWmDPLEAEa8g1x8eqF5kAaRmG5uDt7kOM rBz6LknBfckTvtJ5PBbvx69eBi51yO17Z2gPUCsHwuCWPSIIAFPgO2JKQydYBqAOEFOvViSjxYy RBa/qJcFwgTvxipFajoczmuoPCq0tQ2+F5ZLu4w5Byn4a83A79JO4dXxmj4XrVsWEA4hPh7HcdP +wtRZZ X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--8.007000-4.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.5.1010-24084.005 X-MDID: 1536572035-K8WctJd5l-TM Subject: [dpdk-dev] [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Sep 2018 09:33:56 -0000 From: Ivan Malov Client drivers may use either legacy flags, for example, EFX_RX_HASH_TCPIPV4, or generalised flags, for example, EFX_RX_HASH(IPV4_TCP, 4TUPLE), to configure RSS hash. The libefx is able to recognise what scheme is used. Legacy flags may be consumed directly by a chip-specific handler to configure the NIC, that is, on EF10, these flags can be used to fill in legacy RSS mode field in MCDI request. Generalised flags can also be directly used in EF10-specific handler as they are fully compatible with additional fields of the same MCDI request. Legacy flags undergo conversion to generalised flags before they are consumed by a chip-specific handler. This conversion is used to make sure that chip-specific handlers expect only generalised flags in the input for the sake of clarity of the code. Depending on firmware capabilities, a chip-specififc handler either supplies the input to the NIC directly, for example, EFX_RX_HASH(IPV4_TCP, 4TUPLE) flag will enable 4 bits in RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE field on EF10, or takes the opportunity to translate the input to enable bits which don't map to the generic flag, like setting RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN on EF10 when the firmware claims no support for additional modes. However, this approach has introduced a severe problem which can be reproduced with ultra-low-latency firmware variant. In order to enable IP hash, EF10-specific handler requires the user to request 2-tuple hash for IP-other, TCP and UDP traffic classes, unconditionally. In example, IPv4 hash can be enabled using the following input: EFX_RX_HASH(IPV4_TCP, 2TUPLE) | EFX_RX_HASH(IPV4_UDP, 2TUPLE) | EFX_RX_HASH(IPV4, 2TUPLE). At the same time, on ultra-low-latency firmware, the common code will never report support for any UDP tuple to the client driver. That is, in the same example, the driver will use EFX_RX_HASH(IPV4_TCP, 2TUPLE) | EFX_RX_HASH(IPV4, 2TUPLE). This input will not be recognised by EF10-specific handler, and RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN bit will not be set in the MCDI request. In order to solve the problem, the patch removes conversion code from chip-specific handlers and adds appropriate code to convert EFX_RX_HASH() flags to their legacy counterparts to the common scale mode set function. If the firmware does not support additional modes, the function will convert generalised flags to legacy flags correctly without any demand for UDP flags and pass the result to a chip-specific handler. Signed-off-by: Ivan Malov Signed-off-by: Andrew Rybchenko --- drivers/net/sfc/base/ef10_rx.c | 42 ++++----------- drivers/net/sfc/base/efx_rx.c | 94 ++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 74 deletions(-) diff --git a/drivers/net/sfc/base/ef10_rx.c b/drivers/net/sfc/base/ef10_rx.c index 1444eca81..3c8f4f3b9 100644 --- a/drivers/net/sfc/base/ef10_rx.c +++ b/drivers/net/sfc/base/ef10_rx.c @@ -314,11 +314,6 @@ efx_mcdi_rss_context_set_flags( __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; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN, MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN); @@ -355,53 +350,38 @@ 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) | - 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) | - EFX_RX_HASH(IPV6_UDP, 2TUPLE); - type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); - - /* - * 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; + type &= EFX_RX_HASH_LEGACY_MASK; 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, + (type & EFX_RX_HASH_IPV4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN, - ((type & type_ipv4_tcp) == type_ipv4_tcp) ? 1 : 0, + (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN, - ((type & type_ipv6) == type_ipv6) ? 1 : 0, + (type & EFX_RX_HASH_IPV6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN, - ((type & type_ipv6_tcp) == type_ipv6_tcp) ? 1 : 0, + (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0, RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE, - (modes >> EFX_RX_CLASS_IPV4_TCP_LBN) & + (type >> EFX_RX_CLASS_IPV4_TCP_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4_TCP), RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE, - (modes >> EFX_RX_CLASS_IPV4_UDP_LBN) & + (type >> EFX_RX_CLASS_IPV4_UDP_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4_UDP), RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE, - (modes >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4), + (type >> EFX_RX_CLASS_IPV4_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV4), RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE, - (modes >> EFX_RX_CLASS_IPV6_TCP_LBN) & + (type >> EFX_RX_CLASS_IPV6_TCP_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6_TCP), RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE, - (modes >> EFX_RX_CLASS_IPV6_UDP_LBN) & + (type >> EFX_RX_CLASS_IPV6_UDP_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6_UDP), RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE, - (modes >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6)); + (type >> EFX_RX_CLASS_IPV6_LBN) & EFX_MASK32(EFX_RX_CLASS_IPV6)); efx_mcdi_execute(enp, &req); diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c index bb0c144d7..04bc7aed8 100644 --- a/drivers/net/sfc/base/efx_rx.c +++ b/drivers/net/sfc/base/efx_rx.c @@ -532,9 +532,8 @@ efx_rx_scale_mode_set( __in efx_rx_hash_type_t type, __in boolean_t insert) { + efx_nic_cfg_t *encp = &enp->en_nic_cfg; 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; @@ -553,47 +552,60 @@ efx_rx_scale_mode_set( } /* - * Translate legacy flags to the new representation - * so that chip-specific handlers will consider the - * new flags only. + * If RSS hash type is represented by additional bits + * in the value, the latter need to be verified since + * not all bit combinations are valid RSS modes. Also, + * depending on the firmware, some valid combinations + * may be unsupported. Discern additional bits in the + * type value and try to recognise valid combinations. + * If some bits remain unrecognised, report the error. */ - 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) - type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE); + type_check = type & ~EFX_RX_HASH_LEGACY_MASK; + if (type_check != 0) { + unsigned int type_flags[EFX_RX_HASH_NFLAGS]; + unsigned int type_nflags; - 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); - } + rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, + EFX_ARRAY_SIZE(type_flags), &type_nflags); + if (rc != 0) + goto fail2; - if (type & EFX_RX_HASH_TCPIPV6) - type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE); + for (i = 0; i < type_nflags; ++i) { + if ((type_check & type_flags[i]) == type_flags[i]) + type_check &= ~(type_flags[i]); + } - type &= ~EFX_RX_HASH_LEGACY_MASK; - type_check = type; + if (type_check != 0) { + rc = EINVAL; + goto fail3; + } + } /* - * Get the list of supported hash flags and sanitise the input. + * Translate EFX_RX_HASH() flags to their legacy counterparts + * provided that the FW claims no support for additional modes. */ - rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, - EFX_ARRAY_SIZE(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 (encp->enc_rx_scale_additional_modes_supported == B_FALSE) { + efx_rx_hash_type_t t_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) | + EFX_RX_HASH(IPV4_TCP, 2TUPLE); + efx_rx_hash_type_t t_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) | + EFX_RX_HASH(IPV6_TCP, 2TUPLE); + efx_rx_hash_type_t t_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE); + efx_rx_hash_type_t t_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE); + + if ((type & t_ipv4) == t_ipv4) + type |= EFX_RX_HASH_IPV4; + if ((type & t_ipv6) == t_ipv6) + type |= EFX_RX_HASH_IPV6; + + if (encp->enc_rx_scale_l4_hash_supported == B_TRUE) { + if ((type & t_ipv4_tcp) == t_ipv4_tcp) + type |= EFX_RX_HASH_TCPIPV4; + if ((type & t_ipv6_tcp) == t_ipv6_tcp) + type |= EFX_RX_HASH_TCPIPV6; + } - if (type_check != 0) { - rc = EINVAL; - goto fail3; + type &= EFX_RX_HASH_LEGACY_MASK; } if (erxop->erxo_scale_mode_set != NULL) { @@ -1111,10 +1123,6 @@ 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) { @@ -1129,12 +1137,12 @@ siena_rx_scale_mode_set( case EFX_RX_HASHALG_TOEPLITZ: EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert, - (type & type_ipv4) == type_ipv4, - (type & type_ipv4_tcp) == type_ipv4_tcp); + (type & EFX_RX_HASH_IPV4) ? B_TRUE : B_FALSE, + (type & EFX_RX_HASH_TCPIPV4) ? B_TRUE : B_FALSE); EFX_RX_TOEPLITZ_IPV6_HASH(enp, - (type & type_ipv6) == type_ipv6, - (type & type_ipv6_tcp) == type_ipv6_tcp, + (type & EFX_RX_HASH_IPV6) ? B_TRUE : B_FALSE, + (type & EFX_RX_HASH_TCPIPV6) ? B_TRUE : B_FALSE, rc); if (rc != 0) goto fail2; -- 2.17.1