aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndriy Gapon <avg@FreeBSD.org>2020-06-23 04:58:36 +0000
committerAndriy Gapon <avg@FreeBSD.org>2020-06-23 04:58:36 +0000
commitb40dd828bdc96959cf5fa90d02fc00d96c54fbe4 (patch)
tree53dc16d114817be8626055546ccbf45b395c6b8b
parent5b750b9a6889dda96c02517133fd2237311ecbb4 (diff)
downloadsrc-b40dd828bdc96959cf5fa90d02fc00d96c54fbe4.tar.gz
src-b40dd828bdc96959cf5fa90d02fc00d96c54fbe4.zip
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
Notes
Notes: svn path=/head/; revision=362530
-rw-r--r--sys/dev/ena/ena.c15
-rw-r--r--sys/dev/ena/ena_datapath.c14
2 files changed, 29 insertions, 0 deletions
diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c
index bc21e77e59dc..d6ac5d208b4d 100644
--- a/sys/dev/ena/ena.c
+++ b/sys/dev/ena/ena.c
@@ -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))) {
diff --git a/sys/dev/ena/ena_datapath.c b/sys/dev/ena/ena_datapath.c
index 51beabc283f7..f95bab8dc1a5 100644
--- a/sys/dev/ena/ena_datapath.c
+++ b/sys/dev/ena/ena_datapath.c
@@ -30,6 +30,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_rss.h"
#include "ena.h"
#include "ena_datapath.h"
#ifdef DEV_NETMAP
@@ -336,6 +337,19 @@ ena_rx_hash_mbuf(struct ena_ring *rx_ring, struct ena_com_rx_ctx *ena_rx_ctx,
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)) {
M_HASHTYPE_SET(mbuf, M_HASHTYPE_OPAQUE_HASH);