@@ -142,6 +142,7 @@ typedef struct VirtioNetRssData {
uint32_t runtime_hash_types;
uint32_t supported_hash_types;
uint32_t peer_hash_types;
+ OnOffAuto specified_hash_types[8];
uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE];
uint16_t indirections_len;
uint16_t *indirections_table;
@@ -1379,16 +1379,31 @@ static bool virtio_net_configure_rss_host(VirtIONet *n, Error **errp)
{
NetVnetHashCap cap;
+ n->rss_data.supported_hash_types = VIRTIO_NET_RSS_SUPPORTED_HASHES;
+
if (qemu_get_vnet_hash_cap(qemu_get_queue(n->nic)->peer, &cap) &&
cap.max_indirection_table_length >= VIRTIO_NET_RSS_MAX_TABLE_LEN) {
n->rss_data.peer_hash_available = true;
- n->rss_data.supported_hash_types = cap.types;
n->rss_data.peer_hash_types = cap.types;
- return true;
+ for (size_t i = 0; ; i++) {
+ if (i >= ARRAY_SIZE(n->rss_data.specified_hash_types)) {
+ n->rss_data.supported_hash_types = cap.types;
+ break;
+ }
+
+ if (n->rss_data.specified_hash_types[i] == ON_OFF_AUTO_ON &&
+ !(cap.types & BIT(i + 1))) {
+ break;
+ }
+ }
}
- n->rss_data.supported_hash_types = VIRTIO_NET_RSS_SUPPORTED_HASHES;
+ for (size_t i = 0; i < ARRAY_SIZE(n->rss_data.specified_hash_types); i++) {
+ if (n->rss_data.specified_hash_types[i] == ON_OFF_AUTO_OFF) {
+ n->rss_data.supported_hash_types &= ~BIT(i + 1);
+ }
+ }
return virtio_net_commit_rss_host_config(n, errp);
}
@@ -4013,6 +4028,33 @@ static Property virtio_net_properties[] = {
DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
DEFINE_PROP_BOOL("failover", VirtIONet, failover, false),
+ DEFINE_PROP_ON_OFF_AUTO("hash-ipv4", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_IPv4 - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-tcp4", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_TCPv4 - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-udp4", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_UDPv4 - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-ipv6", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_IPv6 - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-tcp6", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_TCPv6 - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-udp6", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_UDPv6 - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-ipv6ex", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_IPv6_EX - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-tcp6ex", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_TCPv6_EX - 1],
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO("hash-udp6ex", VirtIONet,
+ rss_data.specified_hash_types[VIRTIO_NET_HASH_REPORT_UDPv6_EX - 1],
+ ON_OFF_AUTO_AUTO),
DEFINE_PROP_END_OF_LIST(),
};
By default, virtio-net limits the hash types that will be advertised to the guest so that all hash types are covered by the offloading capability the client provides. This change allows to override this behavior and to advertise hash types that require user-space hash calculation by specifying "on" for the corresponding properties. Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> --- include/hw/virtio/virtio-net.h | 1 + hw/net/virtio-net.c | 48 +++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-)