svn commit: r362530 - head/sys/dev/ena

Andriy Gapon avg at FreeBSD.org
Tue Jun 23 04:58:37 UTC 2020


Author: avg
Date: Tue Jun 23 04:58:36 2020
New Revision: 362530
URL: https://svnweb.freebsd.org/changeset/base/362530

Log:
  teach ena driver about RSS kernel option
  
  Networking is broken if the driver configures its (virtual) hardware to
  use a hash algorithm (or a key) different from the one that the network
  stack (software RSS) uses.  This can be seen with connections initiated
  from the host.  The PCB will be placed into the hash table based on the
  hash value calculated by the software.  The hardware-calculated hash
  value in reponse packets will be different, so the PCB won't be found.
  
  Tested with a kernel compiled with 'options RSS' on an instance with ena
  driver.
  
  Reviewed by:	mw, adrian
  MFC after:	2 weeks
  Sponsored by:	Panzura
  Differential Revision: https://reviews.freebsd.org/D24733

Modified:
  head/sys/dev/ena/ena.c
  head/sys/dev/ena/ena_datapath.c

Modified: head/sys/dev/ena/ena.c
==============================================================================
--- head/sys/dev/ena/ena.c	Tue Jun 23 03:32:58 2020	(r362529)
+++ head/sys/dev/ena/ena.c	Tue Jun 23 04:58:36 2020	(r362530)
@@ -30,6 +30,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_rss.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
@@ -61,6 +63,9 @@ __FBSDID("$FreeBSD$");
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/if_vlan_var.h>
+#ifdef RSS
+#include <net/rss_config.h>
+#endif
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -2700,6 +2705,16 @@ ena_rss_init_default(struct ena_adapter *adapter)
 		}
 	}
 
+#ifdef RSS
+	uint8_t rss_algo = rss_gethashalgo();
+	if (rss_algo == RSS_HASH_TOEPLITZ) {
+		uint8_t hash_key[RSS_KEYSIZE];
+
+		rss_getkey(hash_key);
+		rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ,
+		    hash_key, RSS_KEYSIZE, 0xFFFFFFFF);
+	} else
+#endif
 	rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL,
 	    ENA_HASH_KEY_SIZE, 0xFFFFFFFF);
 	if (unlikely((rc != 0) && (rc != EOPNOTSUPP))) {

Modified: head/sys/dev/ena/ena_datapath.c
==============================================================================
--- head/sys/dev/ena/ena_datapath.c	Tue Jun 23 03:32:58 2020	(r362529)
+++ head/sys/dev/ena/ena_datapath.c	Tue Jun 23 04:58:36 2020	(r362530)
@@ -30,6 +30,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_rss.h"
 #include "ena.h"
 #include "ena_datapath.h"
 #ifdef DEV_NETMAP
@@ -335,6 +336,19 @@ ena_rx_hash_mbuf(struct ena_ring *rx_ring, struct ena_
 
 	if (likely(ENA_FLAG_ISSET(ENA_FLAG_RSS_ACTIVE, adapter))) {
 		mbuf->m_pkthdr.flowid = ena_rx_ctx->hash;
+
+#ifdef RSS
+		/*
+		 * Hardware and software RSS are in agreement only when both are
+		 * configured to Toeplitz algorithm.  This driver configures
+		 * that algorithm only when software RSS is enabled and uses it.
+		 */
+		if (adapter->ena_dev->rss.hash_func != ENA_ADMIN_TOEPLITZ &&
+		    ena_rx_ctx->l3_proto != ENA_ETH_IO_L3_PROTO_UNKNOWN) {
+			M_HASHTYPE_SET(mbuf, M_HASHTYPE_OPAQUE_HASH);
+			return;
+		}
+#endif
 
 		if (ena_rx_ctx->frag &&
 		    (ena_rx_ctx->l3_proto != ENA_ETH_IO_L3_PROTO_UNKNOWN)) {


More information about the svn-src-head mailing list