DPDK patches and discussions
 help / color / mirror / Atom feed
From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
Cc: Ivan Malov <Ivan.Malov@oktetlabs.ru>
Subject: [dpdk-dev] [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags
Date: Mon, 10 Sep 2018 10:33:33 +0100	[thread overview]
Message-ID: <1536572016-18134-35-git-send-email-arybchenko@solarflare.com> (raw)
In-Reply-To: <1536572016-18134-1-git-send-email-arybchenko@solarflare.com>

From: Ivan Malov <Ivan.Malov@oktetlabs.ru>

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 <Ivan.Malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 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

  parent reply	other threads:[~2018-09-10  9:33 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-10  9:32 [dpdk-dev] [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 02/37] net/sfc/base: fix invalid order of memset arguments Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 03/37] net/sfc/base: fix output buffer SAL annotation Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 04/37] net/sfc/base: highlight that image layout header generated Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 05/37] net/sfc/base: fix erroneous SAL annotation for input buffers Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 06/37] net/sfc/base: properly align on line continuation Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 07/37] net/sfc/base: add space after sizeof Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 08/37] net/sfc/base: fix build failure because of no declaration Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 09/37] net/sfc/base: add more definitions of partitions Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 10/37] net/sfc/base: fix outer IPID field in TSO option descriptors Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 11/37] net/sfc/base: move empty efsys definitions to EFX headers Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 12/37] net/sfc/base: add check for TUNNEL module in NIC reset API Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 13/37] net/sfc/base: refactor monitors support Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 14/37] net/sfc/base: remove probes when a Tx queue is too full Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 15/37] net/sfc/base: add generated description of sensors Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 16/37] net/sfc/base: check size of memory to read sensors data to Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 18/37] net/sfc/base: add buffer editing functions to boot config Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 19/37] net/sfc/base: add accessor for default port mode Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 20/37] net/sfc/base: generalise EF10 NVRAM buffer interface Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 21/37] net/sfc/base: avoid usage of too big arrays on stack Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 22/37] net/sfc/base: add information if TSO workaround is required Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 23/37] net/sfc/base: fix out of bounds read when dereferencing sdup Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 24/37] net/sfc/base: add routine to check for hardware presence Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 25/37] net/sfc/base: add API to inform libefx of hardware removal Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 26/37] net/sfc/base: fix ID retrival in v3 licensing Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 27/37] net/sfc/base: prevent access to the NIC config before probe Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 28/37] net/sfc/base: fix name of the argument to store RSS flags Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 29/37] net/sfc/base: fix a typo in unicast filter insertion comment Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 30/37] net/sfc/base: add support to get active FEC type Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 31/37] net/sfc/base: use simpler code to check hash algorithm type Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 32/37] net/sfc/base: check buffer size for hash flags Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 33/37] net/sfc/base: simplify the code to parse RSS hash type Andrew Rybchenko
2018-09-10  9:33 ` Andrew Rybchenko [this message]
2018-09-10  9:33 ` [dpdk-dev] [PATCH 35/37] net/sfc/base: modify phy caps to indicate FEC request Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 36/37] net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 37/37] net/sfc/base: add helper API to make Geneve filter spec Andrew Rybchenko
2018-09-21 10:28 ` [dpdk-dev] [PATCH 00/37] net/sfc: update base driver Ferruh Yigit

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1536572016-18134-35-git-send-email-arybchenko@solarflare.com \
    --to=arybchenko@solarflare.com \
    --cc=Ivan.Malov@oktetlabs.ru \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

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

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