From: Andrew Melnychenko <hidden> Date: 2022-02-08 18:15:51
Virtio-net supports "hardware" RSS with toeplitz key.
Also, it allows receiving calculated hash in vheader
that may be used with RPS.
Added ethtools callbacks to manipulate RSS.
Technically hash calculation may be set only for
SRC+DST and SRC+DST+PORTSRC+PORTDST hashflows.
The completely disabling hash calculation for TCP or UDP
would disable hash calculation for IP.
RSS/RXHASH is disabled by default.
Changes since v2:
* Fixed issue with calculating padded header length.
During review/tests, there was found an issue that
will crash the kernel if VIRTIO_NET_F_MRG_RXBUF
was not set. (thx to Jason Wang [off-list ref])
* Refactored the code according to review.
Changes since v1:
* Refactored virtnet_set_hashflow.
* Refactored virtio_net_ctrl_rss.
* Moved hunks between patches a bit.
Changes since rfc:
* Code refactored.
* Patches reformatted.
* Added feature validation.
Andrew Melnychenko (4):
drivers/net/virtio_net: Fixed padded vheader to use v1 with hash.
drivers/net/virtio_net: Added basic RSS support.
drivers/net/virtio_net: Added RSS hash report.
drivers/net/virtio_net: Added RSS hash report control.
drivers/net/virtio_net.c | 382 +++++++++++++++++++++++++++++++++++++--
1 file changed, 369 insertions(+), 13 deletions(-)
--
2.34.1
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
From: Andrew Melnychenko <hidden> Date: 2022-02-08 18:15:56
The header v1 provides additional info about RSS.
Added changes to computing proper header length.
In the next patches, the header may contain RSS hash info
for the hash population.
Signed-off-by: Andrew Melnychenko <redacted>
---
drivers/net/virtio_net.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
@@ -169,6 +169,24 @@ struct receive_queue {structxdp_rxq_infoxdp_rxq;};+/* This structure can contain rss message with maximum settings for indirection table and keysize+*Note,thatdefaultstructurethatdescribesRSSconfigurationvirtio_net_rss_config+*containssameinfobutcan'thandletablevalues.+*Inanycase,structurewouldbepassedtovirtiohwthroughsg_bufsplitbyparts+*becausetablesizesmaybedifferaccordingtothedeviceconfiguration.+*/+#define VIRTIO_NET_RSS_MAX_KEY_SIZE 40+#define VIRTIO_NET_RSS_MAX_TABLE_LEN 128+structvirtio_net_ctrl_rss{+u32hash_types;+u16indirection_table_mask;+u16unclassified_queue;+u16indirection_table[VIRTIO_NET_RSS_MAX_TABLE_LEN];+u16max_tx_vq;+u8hash_key_length;+u8key[VIRTIO_NET_RSS_MAX_KEY_SIZE];+};+/* Control VQ buffers: protected by the rtnl lock */structcontrol_buf{structvirtio_net_ctrl_hdrhdr;
@@ -3113,13 +3270,14 @@ static int virtnet_probe(struct virtio_device *vdev)u16max_queue_pairs;intmtu;-/* Find if host supports multiqueue virtio_net device */-err=virtio_cread_feature(vdev,VIRTIO_NET_F_MQ,-structvirtio_net_config,-max_virtqueue_pairs,&max_queue_pairs);+/* Find if host supports multiqueue/rss virtio_net device */+max_queue_pairs=1;+if(virtio_has_feature(vdev,VIRTIO_NET_F_MQ)||virtio_has_feature(vdev,VIRTIO_NET_F_RSS))+max_queue_pairs=+virtio_cread16(vdev,offsetof(structvirtio_net_config,max_virtqueue_pairs));/* We need at least 2 queue's */-if(err||max_queue_pairs<VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN||+if(max_queue_pairs<VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN||max_queue_pairs>VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX||!virtio_has_feature(vdev,VIRTIO_NET_F_CTRL_VQ))max_queue_pairs=1;
@@ -3207,6 +3365,23 @@ static int virtnet_probe(struct virtio_device *vdev)if(virtio_has_feature(vdev,VIRTIO_NET_F_MRG_RXBUF))vi->mergeable_rx_bufs=true;+if(virtio_has_feature(vdev,VIRTIO_NET_F_RSS)){+vi->has_rss=true;+vi->rss_indir_table_size=+virtio_cread16(vdev,offsetof(structvirtio_net_config,+rss_max_indirection_table_length));+vi->rss_key_size=+virtio_cread8(vdev,offsetof(structvirtio_net_config,rss_max_key_size));++vi->rss_hash_types_supported=+virtio_cread32(vdev,offsetof(structvirtio_net_config,supported_hash_types));+vi->rss_hash_types_supported&=+~(VIRTIO_NET_RSS_HASH_TYPE_IP_EX|+VIRTIO_NET_RSS_HASH_TYPE_TCP_EX|+VIRTIO_NET_RSS_HASH_TYPE_UDP_EX);++dev->hw_features|=NETIF_F_RXHASH;+}if(virtio_has_feature(vdev,VIRTIO_NET_F_MRG_RXBUF)||virtio_has_feature(vdev,VIRTIO_F_VERSION_1))vi->hdr_len=sizeof(structvirtio_net_hdr_mrg_rxbuf);
From: Andrew Melnychenko <hidden> Date: 2022-02-08 18:16:02
Added features for RSS hash report.
If hash is provided - it sets to skb.
Added checks if rss and/or hash are enabled together.
Signed-off-by: Andrew Melnychenko <redacted>
---
drivers/net/virtio_net.c | 51 ++++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 7 deletions(-)
@@ -2286,6 +2288,121 @@ static void virtnet_init_default_rss(struct virtnet_info *vi)netdev_rss_key_fill(vi->ctrl->rss.key,vi->rss_key_size);}+staticvoidvirtnet_get_hashflow(conststructvirtnet_info*vi,structethtool_rxnfc*info)+{+info->data=0;+switch(info->flow_type){+caseTCP_V4_FLOW:+if(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_TCPv4){+info->data=RXH_IP_SRC|RXH_IP_DST|+RXH_L4_B_0_1|RXH_L4_B_2_3;+}elseif(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_IPv4){+info->data=RXH_IP_SRC|RXH_IP_DST;+}+break;+caseTCP_V6_FLOW:+if(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_TCPv6){+info->data=RXH_IP_SRC|RXH_IP_DST|+RXH_L4_B_0_1|RXH_L4_B_2_3;+}elseif(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_IPv6){+info->data=RXH_IP_SRC|RXH_IP_DST;+}+break;+caseUDP_V4_FLOW:+if(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_UDPv4){+info->data=RXH_IP_SRC|RXH_IP_DST|+RXH_L4_B_0_1|RXH_L4_B_2_3;+}elseif(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_IPv4){+info->data=RXH_IP_SRC|RXH_IP_DST;+}+break;+caseUDP_V6_FLOW:+if(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_UDPv6){+info->data=RXH_IP_SRC|RXH_IP_DST|+RXH_L4_B_0_1|RXH_L4_B_2_3;+}elseif(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_IPv6){+info->data=RXH_IP_SRC|RXH_IP_DST;+}+break;+caseIPV4_FLOW:+if(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_IPv4)+info->data=RXH_IP_SRC|RXH_IP_DST;++break;+caseIPV6_FLOW:+if(vi->rss_hash_types_saved&VIRTIO_NET_RSS_HASH_TYPE_IPv6)+info->data=RXH_IP_SRC|RXH_IP_DST;++break;+default:+info->data=0;+break;+}+}++staticboolvirtnet_set_hashflow(structvirtnet_info*vi,structethtool_rxnfc*info)+{+u32new_hashtypes=vi->rss_hash_types_saved;+boolis_disable=info->data&RXH_DISCARD;+boolis_l4=info->data==(RXH_IP_SRC|RXH_IP_DST|RXH_L4_B_0_1|RXH_L4_B_2_3);++/* supports only 'sd', 'sdfn' and 'r' */+if(!((info->data==(RXH_IP_SRC|RXH_IP_DST))|is_l4|is_disable))+returnfalse;++switch(info->flow_type){+caseTCP_V4_FLOW:+new_hashtypes&=~(VIRTIO_NET_RSS_HASH_TYPE_IPv4|VIRTIO_NET_RSS_HASH_TYPE_TCPv4);+if(!is_disable)+new_hashtypes|=VIRTIO_NET_RSS_HASH_TYPE_IPv4+|(is_l4?VIRTIO_NET_RSS_HASH_TYPE_TCPv4:0);+break;+caseUDP_V4_FLOW:+new_hashtypes&=~(VIRTIO_NET_RSS_HASH_TYPE_IPv4|VIRTIO_NET_RSS_HASH_TYPE_UDPv4);+if(!is_disable)+new_hashtypes|=VIRTIO_NET_RSS_HASH_TYPE_IPv4+|(is_l4?VIRTIO_NET_RSS_HASH_TYPE_UDPv4:0);+break;+caseIPV4_FLOW:+new_hashtypes&=~VIRTIO_NET_RSS_HASH_TYPE_IPv4;+if(!is_disable)+new_hashtypes=VIRTIO_NET_RSS_HASH_TYPE_IPv4;+break;+caseTCP_V6_FLOW:+new_hashtypes&=~(VIRTIO_NET_RSS_HASH_TYPE_IPv6|VIRTIO_NET_RSS_HASH_TYPE_TCPv6);+if(!is_disable)+new_hashtypes|=VIRTIO_NET_RSS_HASH_TYPE_IPv6+|(is_l4?VIRTIO_NET_RSS_HASH_TYPE_TCPv6:0);+break;+caseUDP_V6_FLOW:+new_hashtypes&=~(VIRTIO_NET_RSS_HASH_TYPE_IPv6|VIRTIO_NET_RSS_HASH_TYPE_UDPv6);+if(!is_disable)+new_hashtypes|=VIRTIO_NET_RSS_HASH_TYPE_IPv6+|(is_l4?VIRTIO_NET_RSS_HASH_TYPE_UDPv6:0);+break;+caseIPV6_FLOW:+new_hashtypes&=~VIRTIO_NET_RSS_HASH_TYPE_IPv6;+if(!is_disable)+new_hashtypes=VIRTIO_NET_RSS_HASH_TYPE_IPv6;+break;+default:+/* unsupported flow */+returnfalse;+}++/* if unsupported hashtype was set */+if(new_hashtypes!=(new_hashtypes&vi->rss_hash_types_supported))+returnfalse;++if(new_hashtypes!=vi->rss_hash_types_saved){+vi->rss_hash_types_saved=new_hashtypes;+vi->ctrl->rss.hash_types=vi->rss_hash_types_saved;+if(vi->dev->features&NETIF_F_RXHASH)+returnvirtnet_commit_rss_command(vi);+}++returntrue;+}staticvoidvirtnet_get_drvinfo(structnet_device*dev,structethtool_drvinfo*info)
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Date: 2022-02-08 22:29:35
On Tue, Feb 8, 2022 at 1:19 PM Andrew Melnychenko [off-list ref] wrote:
quoted hunk
Added features for RSS hash report.
If hash is provided - it sets to skb.
Added checks if rss and/or hash are enabled together.
Signed-off-by: Andrew Melnychenko <redacted>
---
drivers/net/virtio_net.c | 51 ++++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 7 deletions(-)
@@ -169,6 +169,24 @@ struct receive_queue {structxdp_rxq_infoxdp_rxq;};+/* This structure can contain rss message with maximum settings for indirection table and keysize+*Note,thatdefaultstructurethatdescribesRSSconfigurationvirtio_net_rss_config+*containssameinfobutcan'thandletablevalues.+*Inanycase,structurewouldbepassedtovirtiohwthroughsg_bufsplitbyparts+*becausetablesizesmaybedifferaccordingtothedeviceconfiguration.+*/+#define VIRTIO_NET_RSS_MAX_KEY_SIZE 40
Future proof, may want to support larger sizes.
netdevice.h defines NETDEV_RSS_KEY_LEN at 52.
tools/testing/selftests/net/toeplitz.c supports up to 60
Only make the feature visible when the hash is actually reported in
the skb, patch 3.
Also, clearly separate the feature patches (2) rss, (3) rxhash, (4)
rxhash config.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
@@ -169,6 +169,24 @@ struct receive_queue {structxdp_rxq_infoxdp_rxq;};+/* This structure can contain rss message with maximum settings for indirection table and keysize+*Note,thatdefaultstructurethatdescribesRSSconfigurationvirtio_net_rss_config+*containssameinfobutcan'thandletablevalues.+*Inanycase,structurewouldbepassedtovirtiohwthroughsg_bufsplitbyparts+*becausetablesizesmaybedifferaccordingtothedeviceconfiguration.+*/+#define VIRTIO_NET_RSS_MAX_KEY_SIZE 40
Future proof, may want to support larger sizes.
netdevice.h defines NETDEV_RSS_KEY_LEN at 52.
tools/testing/selftests/net/toeplitz.c supports up to 60
According to virtio specification, the length of the key is
40bytes(and an indirection table is 128 entries max).
So for now, we support a maximum of the spec regardless of what the
kernel is capable of.
Only make the feature visible when the hash is actually reported in
the skb, patch 3.
VirtioNET has two features: RSS(steering only) and hash(hash report in
vnet header)
Both features may be enabled/disabled separately:
1. rss on and hash off - packets steered to the corresponding vqs
2. rss off and hash on - packets steered by tap(like mq) but headers
have properly calculated hash.
3. rss on and hash on - packets steered to corresponding vqs and hash
is present in the header.
RXHASH feature allows the user to enable/disable the rss/hash(any combination).
I think it's a good idea to leave RXHASH in patch 2/4 to give the user
ability to manipulate the rss only feature.
But, if you think that it requires to move it to the 3/4, I'll do it.
Also, clearly separate the feature patches (2) rss, (3) rxhash, (4)
rxhash config.
Currently:
Patch 2/4 - adds VirtioNet rss feature.
Patch 3/4 - adds VirtioNet hash report feature.
Patch 4/4 - adds the ability to manipulate supported hash types.
Can you provide more detailed suggestions on how to move hunks?
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
From: Andrew Melnichenko <hidden> Date: 2022-02-13 17:08:38
Hi all,
On Tue, Feb 8, 2022 at 10:55 PM Willem de Bruijn
[off-list ref] wrote:
On Tue, Feb 8, 2022 at 1:19 PM Andrew Melnychenko [off-list ref] wrote:
quoted
Added features for RSS hash report.
If hash is provided - it sets to skb.
Added checks if rss and/or hash are enabled together.
Signed-off-by: Andrew Melnychenko <redacted>
---
drivers/net/virtio_net.c | 51 ++++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 7 deletions(-)
@@ -3365,8 +3394,13 @@ static int virtnet_probe(struct virtio_device *vdev) if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) vi->mergeable_rx_bufs = true;- if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) {+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT))+ vi->has_rss_hash_report = true;++ if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) vi->has_rss = true;++ if (vi->has_rss || vi->has_rss_hash_report) { vi->rss_indir_table_size = virtio_cread16(vdev, offsetof(struct virtio_net_config,
should indir table size be zero if only hash report is enabled?
Not really - but of course, for hash only, the table is not necessary.
(Qemu always provides the table with size 1, I'll add checks for zero sizes
in case of hardware implementation.)
From: Andrew Melnichenko <hidden> Date: 2022-02-13 17:22:38
Hi all,
On Tue, Feb 8, 2022 at 10:59 PM Willem de Bruijn
[off-list ref] wrote:
On Tue, Feb 8, 2022 at 1:19 PM Andrew Melnychenko [off-list ref] wrote:
quoted
Now it's possible to control supported hashflows.
Added hashflow set/get callbacks.
Also, disabling RXH_IP_SRC/DST for TCP would disable then for UDP.
I don't follow this comment. Can you elaborate?
I'll rephrase it in next version of patches.
The idea is that VirtioNet RSS doesn't distinguish IP hashes between
TCP and UDP.
For TCP and UDP it's possible to set IP+PORT hashes.
But disabling IP hashes will disable them for TCP and UDP simultaneously.
It's possible to set IP+PORT for TCP and IP for everything else(UDP, ICMP etc.)
I think "hash_types_saved" is more suitable for the current field.
Idea is that the user may disable RSS/HASH and we need to save
what hash type configurations previously were enabled.
So, we can restore it when the user will enable RSS/HASH back.
should only be updated if the commit function returned success?
Not really, we already made all checks against "supported" hash types.
Also, the commit function may not be called if RSS is disabled by the user.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Only make the feature visible when the hash is actually reported in
the skb, patch 3.
VirtioNET has two features: RSS(steering only) and hash(hash report in
vnet header)
Both features may be enabled/disabled separately:
1. rss on and hash off - packets steered to the corresponding vqs
2. rss off and hash on - packets steered by tap(like mq) but headers
have properly calculated hash.
3. rss on and hash on - packets steered to corresponding vqs and hash
is present in the header.
RXHASH feature allows the user to enable/disable the rss/hash(any combination).
I find that confusing, but.. I see that there is prior art where some
drivers enable/disable entire RSS load balancing based on this flag.
So ok.
I think it's a good idea to leave RXHASH in patch 2/4 to give the user
ability to manipulate the rss only feature.
But, if you think that it requires to move it to the 3/4, I'll do it.
quoted
Also, clearly separate the feature patches (2) rss, (3) rxhash, (4)
rxhash config.
Currently:
Patch 2/4 - adds VirtioNet rss feature.
Patch 3/4 - adds VirtioNet hash report feature.
Patch 4/4 - adds the ability to manipulate supported hash types.
Can you provide more detailed suggestions on how to move hunks?
I gave one in the follow-on patch, to which you responded. That's probably it.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Only make the feature visible when the hash is actually reported in
the skb, patch 3.
VirtioNET has two features: RSS(steering only) and hash(hash report in
vnet header)
Both features may be enabled/disabled separately:
1. rss on and hash off - packets steered to the corresponding vqs
2. rss off and hash on - packets steered by tap(like mq) but headers
have properly calculated hash.
3. rss on and hash on - packets steered to corresponding vqs and hash
is present in the header.
RXHASH feature allows the user to enable/disable the rss/hash(any combination).
I find that confusing, but.. I see that there is prior art where some
drivers enable/disable entire RSS load balancing based on this flag.
So ok.
quoted
I think it's a good idea to leave RXHASH in patch 2/4 to give the user
ability to manipulate the rss only feature.
But, if you think that it requires to move it to the 3/4, I'll do it.
quoted
Also, clearly separate the feature patches (2) rss, (3) rxhash, (4)
rxhash config.
Currently:
Patch 2/4 - adds VirtioNet rss feature.
Patch 3/4 - adds VirtioNet hash report feature.
Patch 4/4 - adds the ability to manipulate supported hash types.
Can you provide more detailed suggestions on how to move hunks?
I gave one in the follow-on patch, to which you responded. That's probably it.
I'll add zero size table check and move hunk for padded header length
from 3/4 to 1/4.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Instead of testing either feature and treating them as somewhat equal,
shouldn't RSS be dependent on MQ?
No, RSS is dependent on CTRL_VQ. Technically RSS and MQ are similar features.
RSS depends on having multiple queues.
What would enabling VIRTIO_NET_F_RSS without VIRTIO_NET_F_MQ do?
RSS would work.
What does that mean, exactly? RSS is load balancing, does that not
require multi-queue?
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Instead of testing either feature and treating them as somewhat equal,
shouldn't RSS be dependent on MQ?
No, RSS is dependent on CTRL_VQ. Technically RSS and MQ are similar features.
RSS depends on having multiple queues.
What would enabling VIRTIO_NET_F_RSS without VIRTIO_NET_F_MQ do?
RSS would work.
What does that mean, exactly? RSS is load balancing, does that not
require multi-queue?
It does, but VIRTIO_NET_F_MQ is a misnomer.
\item[VIRTIO_NET_F_MQ(22)] Device supports multiqueue with automatic
receive steering.
VIRTIO_NET_F_RSS implies multi queue and does not depend on VIRTIO_NET_F_MQ.
--
MST
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization