netkvm: define VIRTIO_NET_F_HASH_REPORT and ack it

When this feature is acked this changes the layout of
virtio header. It contains additional 8 bytes where
the device reports hash and hash type.

Signed-off-by: Yuri Benditovich <[email protected]>
This commit is contained in:
Yuri Benditovich authored and Yan Vugenfirer committed 2020-05-04 16:41:00 +03:00
1 parent 6ce66b5625
commit 6fa4db059d
5 files changed
+60 -12

No files matched your search

+16 -3
View File
@@ -409,6 +409,7 @@ static void DumpVirtIOFeatures(PPARANDIS_ADAPTER pContext)
{VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, "VIRTIO_NET_F_CTRL_GUEST_OFFLOADS" },
{VIRTIO_NET_F_RSC_EXT, "VIRTIO_NET_F_RSC_EXT" },
{VIRTIO_NET_F_RSS, "VIRTIO_NET_F_RSS" },
{VIRTIO_NET_F_HASH_REPORT, "VIRTIO_NET_F_HASH_REPORT" },
};
UINT i;
for (i = 0; i < sizeof(Features)/sizeof(Features[0]); ++i)
@@ -816,18 +817,28 @@ NDIS_STATUS ParaNdis_InitializeContext(
#if PARANDIS_SUPPORT_RSS
pContext->bMultiQueue = pContext->bControlQueueSupported && AckFeature(pContext, VIRTIO_NET_F_MQ);
if (virtio_is_feature_enabled(pContext->u64HostFeatures, VIRTIO_NET_F_RSS) && pContext->bControlQueueSupported)
bool bRSS = virtio_is_feature_enabled(pContext->u64HostFeatures, VIRTIO_NET_F_RSS);
bool bHash = virtio_is_feature_enabled(pContext->u64HostFeatures, VIRTIO_NET_F_HASH_REPORT);
if ((bHash || bRSS) && pContext->bControlQueueSupported && virtio_is_feature_enabled(pContext->u64HostFeatures, VIRTIO_F_VERSION_1))
{
struct virtio_net_config cfg = {};
virtio_get_config(&pContext->IODevice, FIELD_OFFSET(struct virtio_net_config, duplex), &cfg.duplex, 8);
pContext->DeviceRSSCapabilities.SupportedHashes = cfg.supported_hash_types;
pContext->DeviceRSSCapabilities.MaxKeySize = cfg.rss_max_key_size;
pContext->DeviceRSSCapabilities.MaxIndirectEntries = cfg.rss_max_indirection_table_length;
if (ParaNdis6_IsDeviceRSSCapable(pContext))
ParaNdis6_CheckDeviceRSSCapabilities(pContext, bRSS, bHash);
if (bRSS)
{
pContext->bRSSSupportedByDevice = AckFeature(pContext, VIRTIO_NET_F_RSS);
pContext->bRSSSupportedByDevicePersistent = pContext->bRSSSupportedByDevice;
}
if (bHash)
{
pContext->bHashReportedByDevice = AckFeature(pContext, VIRTIO_NET_F_HASH_REPORT);
}
}
if (pContext->bRSSSupportedByDevice)
{
@@ -877,7 +888,9 @@ NDIS_STATUS ParaNdis_InitializeContext(
pContext->bAnyLayout = AckFeature(pContext, VIRTIO_F_ANY_LAYOUT);
if (AckFeature(pContext, VIRTIO_F_VERSION_1))
{
pContext->nVirtioHeaderSize = sizeof(virtio_net_hdr_v1);
pContext->nVirtioHeaderSize = pContext->bHashReportedByDevice ?
sizeof(virtio_net_hdr_v1_hash) : sizeof(virtio_net_hdr_v1);
pContext->bAnyLayout = true;
DPrintf(0, "[%s] Assuming VIRTIO_F_ANY_LAYOUT for V1 device\n", __FUNCTION__);
if (AckFeature(pContext, VIRTIO_F_RING_PACKED))
+1 -1
View File
@@ -79,7 +79,7 @@ NDIS_STATUS ParaNdis6_RSSSetReceiveHash(PARANDIS_ADAPTER *pContext,
UINT ParamsLength,
PUINT ParamsBytesRead);
BOOLEAN ParaNdis6_IsDeviceRSSCapable(PARANDIS_ADAPTER *pContext);
void ParaNdis6_CheckDeviceRSSCapabilities(PARANDIS_ADAPTER *pContext, bool& bRss, bool& bHash);
/* for engineering tests only */
void ParaNdis6_EnableDeviceRssSupport(PARANDIS_ADAPTER *pContext, BOOLEAN b);
+1
View File
@@ -500,6 +500,7 @@ typedef struct _tagPARANDIS_ADAPTER
BOOLEAN bDeviceInitialized;
BOOLEAN bRSSSupportedByDevice;
BOOLEAN bRSSSupportedByDevicePersistent;
BOOLEAN bHashReportedByDevice;
#if PARANDIS_SUPPORT_RSS
BOOLEAN bRSSOffloadSupported;
+20
View File
@@ -59,6 +59,7 @@
#define VIRTIO_NET_F_GUEST_RSC4_DONT_USE 41 /* reserved */
#define VIRTIO_NET_F_GUEST_RSC6_DONT_USE 42 /* reserved */
#define VIRTIO_NET_F_HASH_REPORT 57
#define VIRTIO_NET_F_RSS 60
#define VIRTIO_NET_F_RSC_EXT 61
@@ -116,6 +117,18 @@ struct virtio_net_config {
#define VIRTIO_NET_RSS_HASH_TYPE_TCP_EX (1 << 7)
#define VIRTIO_NET_RSS_HASH_TYPE_UDP_EX (1 << 8)
#define VIRTIO_NET_HASH_REPORT_NONE 0
#define VIRTIO_NET_HASH_REPORT_IPv4 1
#define VIRTIO_NET_HASH_REPORT_TCPv4 2
#define VIRTIO_NET_HASH_REPORT_UDPv4 3
#define VIRTIO_NET_HASH_REPORT_IPv6 4
#define VIRTIO_NET_HASH_REPORT_TCPv6 5
#define VIRTIO_NET_HASH_REPORT_UDPv6 6
#define VIRTIO_NET_HASH_REPORT_IPv6_EX 7
#define VIRTIO_NET_HASH_REPORT_TCPv6_EX 8
#define VIRTIO_NET_HASH_REPORT_UDPv6_EX 9
#define VIRTIO_NET_HASH_REPORT_MAX VIRTIO_NET_HASH_REPORT_UDPv6_EX
/*
* This header comes first in the scatter-gather list. If you don't
* specify GSO or CSUM features, you can simply ignore the header.
@@ -143,6 +156,12 @@ struct virtio_net_hdr_v1 {
#define rsc_ext_num_packets csum_start
#define rsc_ext_num_dupacks csum_offset
struct virtio_net_hdr_v1_hash {
struct virtio_net_hdr_v1 h;
__virtio32 hash_value;
__virtio16 hash_report;
__virtio16 reserved;
};
#ifndef VIRTIO_NET_NO_LEGACY
/* This header comes first in the scatter-gather list.
@@ -267,6 +286,7 @@ struct virtio_net_ctrl_mac {
#define VIRTIO_NET_CTRL_MQ 4
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0
#define VIRTIO_NET_CTRL_MQ_RSS_CONFIG 1
#define VIRTIO_NET_CTRL_MQ_HASH_CONFIG 2
/* for VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET */
struct virtio_net_ctrl_mq {
+22 -8
View File
@@ -119,17 +119,31 @@ static VOID InitRSSCapabilities(PARANDIS_ADAPTER *pContext)
#endif
}
BOOLEAN ParaNdis6_IsDeviceRSSCapable(PARANDIS_ADAPTER *pContext)
void ParaNdis6_CheckDeviceRSSCapabilities(PARANDIS_ADAPTER *pContext, bool& bRss, bool& bHash)
{
if (bHash || bRss)
{
DPrintf(0, "[%s] Device supports %s %s: key of %d, table of %d, hashes %X\n", __FUNCTION__,
bHash ? "Hash" : " ", bRss ? "RSS" : " ",
pContext->DeviceRSSCapabilities.MaxKeySize,
pContext->DeviceRSSCapabilities.MaxIndirectEntries,
pContext->DeviceRSSCapabilities.SupportedHashes);
}
BOOLEAN bResult = (pContext->DeviceRSSCapabilities.SupportedHashes & VIRTIO_NET_RSS_HASH_TYPE_IPv4) &&
pContext->DeviceRSSCapabilities.MaxIndirectEntries >= NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 / sizeof(PROCESSOR_NUMBER) &&
pContext->DeviceRSSCapabilities.MaxKeySize >= NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2;
DPrintf(0, "[%s] Device RSS support: key of %d, table of %d, hashes %X = %s\n", __FUNCTION__,
pContext->DeviceRSSCapabilities.MaxKeySize,
pContext->DeviceRSSCapabilities.MaxIndirectEntries,
pContext->DeviceRSSCapabilities.SupportedHashes,
bResult ? "OK" : "Not enough");
return bResult;
if (!bResult)
{
bRss = false;
bHash = false;
}
bResult = bResult && pContext->DeviceRSSCapabilities.MaxIndirectEntries >= NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 / sizeof(PROCESSOR_NUMBER);
if (!bResult)
{
bRss = false;
}
DPrintf(0, "[%s] Driver will use: %s %s\n", __FUNCTION__, bHash ? "Hash" : " ", bRss ? "RSS" : " ");
}
NDIS_RECEIVE_SCALE_CAPABILITIES* ParaNdis6_RSSCreateConfiguration(PARANDIS_ADAPTER *pContext)