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
This commit is contained in:
Andriy Gapon 2020-06-23 04:58:36 +00:00
parent 5b750b9a68
commit b40dd828bd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362530
2 changed files with 29 additions and 0 deletions

View File

@ -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))) {

View File

@ -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);