* [PATCH 0/6] net/vhost-vdpa: Report hashing capability
@ 2025-05-30 4:33 Akihiko Odaki
2025-05-30 4:33 ` [PATCH 1/6] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
This patch series was extracted from:
https://lore.kernel.org/qemu-devel/20250313-hash-v4-0-c75c494b495e@daynix.com/
("[PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF")
According to the specification, virtio-net devices with VIRTIO_NET_F_RSS
or VIRTIO_NET_F_HASH_REPORT can report supported hash types:
https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-2230004
vDPA also implements the same functionality, but QEMU currently does not
respect it. Ensure that the vDPA device satisfies the requirements of
the VM by checking the supported hash types. This also helps add another
hashing mechanism proposed by the patch series mentioned earlier.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
Akihiko Odaki (6):
qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
net/vhost-vdpa: Report hashing capability
virtio-net: Move virtio_net_get_features() down
virtio-net: Retrieve peer hashing capability
net/vhost-vdpa: Remove dummy SetSteeringEBPF
virtio-net: Add hash type options
include/hw/qdev-properties.h | 18 +++
include/hw/virtio/virtio-net.h | 6 +-
include/net/net.h | 3 +
hw/core/qdev-properties.c | 67 ++++++++++-
hw/net/virtio-net.c | 254 +++++++++++++++++++++++++++--------------
net/net.c | 9 ++
net/vhost-vdpa.c | 34 ++++--
7 files changed, 298 insertions(+), 93 deletions(-)
---
base-commit: 5f90d272553ca0d18ac2457a993febdba9e840e3
change-id: 20250530-vdpa-2c481c64ce45
Best regards,
--
Akihiko Odaki <akihiko.odaki@daynix.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/6] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
@ 2025-05-30 4:33 ` Akihiko Odaki
2025-05-30 4:33 ` [PATCH 2/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
DEFINE_PROP_ON_OFF_AUTO_BIT64() corresponds to DEFINE_PROP_ON_OFF_AUTO()
as DEFINE_PROP_BIT64() corresponds to DEFINE_PROP_BOOL(). The difference
is that DEFINE_PROP_ON_OFF_AUTO_BIT64() exposes OnOffAuto instead of
bool.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
include/hw/qdev-properties.h | 18 ++++++++++++
hw/core/qdev-properties.c | 67 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 2c99856caacb..0197aa4995e6 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -43,11 +43,22 @@ struct PropertyInfo {
ObjectPropertyRelease *release;
};
+/**
+ * struct OnOffAutoBit64 - OnOffAuto storage with 64 elements.
+ * @on_bits: Bitmap of elements with "on".
+ * @auto_bits: Bitmap of elements with "auto".
+ */
+typedef struct OnOffAutoBit64 {
+ uint64_t on_bits;
+ uint64_t auto_bits;
+} OnOffAutoBit64;
+
/*** qdev-properties.c ***/
extern const PropertyInfo qdev_prop_bit;
extern const PropertyInfo qdev_prop_bit64;
+extern const PropertyInfo qdev_prop_on_off_auto_bit64;
extern const PropertyInfo qdev_prop_bool;
extern const PropertyInfo qdev_prop_uint8;
extern const PropertyInfo qdev_prop_uint16;
@@ -100,6 +111,13 @@ extern const PropertyInfo qdev_prop_link;
.set_default = true, \
.defval.u = (bool)_defval)
+#define DEFINE_PROP_ON_OFF_AUTO_BIT64(_name, _state, _field, _bit, _defval) \
+ DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit64, \
+ OnOffAutoBit64, \
+ .bitnr = (_bit), \
+ .set_default = true, \
+ .defval.i = (OnOffAuto)_defval)
+
#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \
DEFINE_PROP(_name, _state, _field, qdev_prop_bool, bool, \
.set_default = true, \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 147b3ffd16e2..b7e8a89ba5cd 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -2,6 +2,7 @@
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-visit-common.h"
#include "qobject/qlist.h"
#include "qemu/ctype.h"
#include "qemu/error-report.h"
@@ -180,7 +181,8 @@ const PropertyInfo qdev_prop_bit = {
static uint64_t qdev_get_prop_mask64(const Property *prop)
{
- assert(prop->info == &qdev_prop_bit64);
+ assert(prop->info == &qdev_prop_bit64 ||
+ prop->info == &qdev_prop_on_off_auto_bit64);
return 0x1ull << prop->bitnr;
}
@@ -225,6 +227,69 @@ const PropertyInfo qdev_prop_bit64 = {
.set_default_value = set_default_value_bool,
};
+static void prop_get_on_off_auto_bit64(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ Property *prop = opaque;
+ OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
+ OnOffAuto value;
+ uint64_t mask = qdev_get_prop_mask64(prop);
+
+ if (p->auto_bits & mask) {
+ value = ON_OFF_AUTO_AUTO;
+ } else if (p->on_bits & mask) {
+ value = ON_OFF_AUTO_ON;
+ } else {
+ value = ON_OFF_AUTO_OFF;
+ }
+
+ visit_type_OnOffAuto(v, name, &value, errp);
+}
+
+static void prop_set_on_off_auto_bit64(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ Property *prop = opaque;
+ OnOffAutoBit64 *p = object_field_prop_ptr(obj, prop);
+ OnOffAuto value;
+ uint64_t mask = qdev_get_prop_mask64(prop);
+
+ if (!visit_type_OnOffAuto(v, name, &value, errp)) {
+ return;
+ }
+
+ switch (value) {
+ case ON_OFF_AUTO_AUTO:
+ p->on_bits &= ~mask;
+ p->auto_bits |= mask;
+ break;
+
+ case ON_OFF_AUTO_ON:
+ p->on_bits |= mask;
+ p->auto_bits &= ~mask;
+ break;
+
+ case ON_OFF_AUTO_OFF:
+ p->on_bits &= ~mask;
+ p->auto_bits &= ~mask;
+ break;
+
+ case ON_OFF_AUTO__MAX:
+ g_assert_not_reached();
+ }
+}
+
+const PropertyInfo qdev_prop_on_off_auto_bit64 = {
+ .type = "OnOffAuto",
+ .description = "on/off/auto",
+ .enum_table = &OnOffAuto_lookup,
+ .get = prop_get_on_off_auto_bit64,
+ .set = prop_set_on_off_auto_bit64,
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
/* --- bool --- */
static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/6] net/vhost-vdpa: Report hashing capability
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
2025-05-30 4:33 ` [PATCH 1/6] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
@ 2025-05-30 4:33 ` Akihiko Odaki
2025-05-30 4:33 ` [PATCH 3/6] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
Report hashing capability so that virtio-net can deliver the correct
capability information to the guest.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
include/net/net.h | 3 +++
net/net.c | 9 +++++++++
net/vhost-vdpa.c | 28 ++++++++++++++++++++++++++++
3 files changed, 40 insertions(+)
diff --git a/include/net/net.h b/include/net/net.h
index cdd5b109b0d2..545f4339cec8 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -60,6 +60,7 @@ typedef bool (HasVnetHdrLen)(NetClientState *, int);
typedef void (SetOffload)(NetClientState *, int, int, int, int, int, int, int);
typedef int (GetVnetHdrLen)(NetClientState *);
typedef void (SetVnetHdrLen)(NetClientState *, int);
+typedef bool (GetVnetHashSupportedTypes)(NetClientState *, uint32_t *);
typedef int (SetVnetLE)(NetClientState *, bool);
typedef int (SetVnetBE)(NetClientState *, bool);
typedef struct SocketReadState SocketReadState;
@@ -89,6 +90,7 @@ typedef struct NetClientInfo {
SetVnetHdrLen *set_vnet_hdr_len;
SetVnetLE *set_vnet_le;
SetVnetBE *set_vnet_be;
+ GetVnetHashSupportedTypes *get_vnet_hash_supported_types;
NetAnnounce *announce;
SetSteeringEBPF *set_steering_ebpf;
NetCheckPeerType *check_peer_type;
@@ -189,6 +191,7 @@ void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
int ecn, int ufo, int uso4, int uso6);
int qemu_get_vnet_hdr_len(NetClientState *nc);
void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
+bool qemu_get_vnet_hash_supported_types(NetClientState *nc, uint32_t *types);
int qemu_set_vnet_le(NetClientState *nc, bool is_le);
int qemu_set_vnet_be(NetClientState *nc, bool is_be);
void qemu_macaddr_default_if_unset(MACAddr *macaddr);
diff --git a/net/net.c b/net/net.c
index 39d6f28158a3..d0ae3db0d864 100644
--- a/net/net.c
+++ b/net/net.c
@@ -573,6 +573,15 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
nc->info->set_vnet_hdr_len(nc, len);
}
+bool qemu_get_vnet_hash_supported_types(NetClientState *nc, uint32_t *types)
+{
+ if (!nc || !nc->info->get_vnet_hash_supported_types) {
+ return false;
+ }
+
+ return nc->info->get_vnet_hash_supported_types(nc, types);
+}
+
int qemu_set_vnet_le(NetClientState *nc, bool is_le)
{
#if HOST_BIG_ENDIAN
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 7ca8b46eee77..1493b08792ea 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -251,6 +251,32 @@ static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc)
return true;
}
+static bool vhost_vdpa_get_vnet_hash_supported_types(NetClientState *nc,
+ uint32_t *types)
+{
+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
+ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+ uint64_t features = s->vhost_vdpa.dev->features;
+ int fd = s->vhost_vdpa.shared->device_fd;
+ struct {
+ struct vhost_vdpa_config hdr;
+ uint32_t supported_hash_types;
+ } config;
+
+ if (!virtio_has_feature(features, VIRTIO_NET_F_HASH_REPORT) &&
+ !virtio_has_feature(features, VIRTIO_NET_F_RSS)) {
+ return false;
+ }
+
+ config.hdr.off = offsetof(struct virtio_net_config, supported_hash_types);
+ config.hdr.len = sizeof(config.supported_hash_types);
+
+ assert(!ioctl(fd, VHOST_VDPA_GET_CONFIG, &config));
+ *types = le32_to_cpu(config.supported_hash_types);
+
+ return true;
+}
+
static bool vhost_vdpa_has_ufo(NetClientState *nc)
{
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
@@ -440,6 +466,7 @@ static NetClientInfo net_vhost_vdpa_info = {
.stop = vhost_vdpa_net_client_stop,
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
+ .get_vnet_hash_supported_types = vhost_vdpa_get_vnet_hash_supported_types,
.has_ufo = vhost_vdpa_has_ufo,
.set_vnet_le = vhost_vdpa_set_vnet_le,
.check_peer_type = vhost_vdpa_check_peer_type,
@@ -1314,6 +1341,7 @@ static NetClientInfo net_vhost_vdpa_cvq_info = {
.stop = vhost_vdpa_net_cvq_stop,
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
+ .get_vnet_hash_supported_types = vhost_vdpa_get_vnet_hash_supported_types,
.has_ufo = vhost_vdpa_has_ufo,
.check_peer_type = vhost_vdpa_check_peer_type,
.set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/6] virtio-net: Move virtio_net_get_features() down
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
2025-05-30 4:33 ` [PATCH 1/6] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
2025-05-30 4:33 ` [PATCH 2/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
@ 2025-05-30 4:33 ` Akihiko Odaki
2025-05-30 4:33 ` [PATCH 4/6] virtio-net: Retrieve peer hashing capability Akihiko Odaki
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
Move virtio_net_get_features() to the later part of the file so that
it can call other functions.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 146 ++++++++++++++++++++++++++--------------------------
1 file changed, 73 insertions(+), 73 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 221252e00a50..4ebe7f93f5c3 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -752,79 +752,6 @@ static void virtio_net_set_queue_pairs(VirtIONet *n)
static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue);
-static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
- Error **errp)
-{
- VirtIONet *n = VIRTIO_NET(vdev);
- NetClientState *nc = qemu_get_queue(n->nic);
-
- /* Firstly sync all virtio-net possible supported features */
- features |= n->host_features;
-
- virtio_add_feature(&features, VIRTIO_NET_F_MAC);
-
- if (!peer_has_vnet_hdr(n)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
- virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
- virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
- virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
-
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
-
- virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
-
- virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
- }
-
- if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
- virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
- }
-
- if (!peer_has_uso(n)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
- }
-
- if (!get_vhost_net(nc->peer)) {
- return features;
- }
-
- if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
- }
- features = vhost_net_get_features(get_vhost_net(nc->peer), features);
- vdev->backend_features = features;
-
- if (n->mtu_bypass_backend &&
- (n->host_features & 1ULL << VIRTIO_NET_F_MTU)) {
- features |= (1ULL << VIRTIO_NET_F_MTU);
- }
-
- /*
- * Since GUEST_ANNOUNCE is emulated the feature bit could be set without
- * enabled. This happens in the vDPA case.
- *
- * Make sure the feature set is not incoherent, as the driver could refuse
- * to start.
- *
- * TODO: QEMU is able to emulate a CVQ just for guest_announce purposes,
- * helping guest to notify the new location with vDPA devices that does not
- * support it.
- */
- if (!virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_CTRL_VQ)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ANNOUNCE);
- }
-
- return features;
-}
-
static uint64_t virtio_net_bad_features(VirtIODevice *vdev)
{
uint64_t features = 0;
@@ -3076,6 +3003,79 @@ static int virtio_net_pre_load_queues(VirtIODevice *vdev)
return 0;
}
+static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
+ Error **errp)
+{
+ VirtIONet *n = VIRTIO_NET(vdev);
+ NetClientState *nc = qemu_get_queue(n->nic);
+
+ /* Firstly sync all virtio-net possible supported features */
+ features |= n->host_features;
+
+ virtio_add_feature(&features, VIRTIO_NET_F_MAC);
+
+ if (!peer_has_vnet_hdr(n)) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
+
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
+
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
+
+ virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
+ }
+
+ if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
+ }
+
+ if (!peer_has_uso(n)) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
+ }
+
+ if (!get_vhost_net(nc->peer)) {
+ return features;
+ }
+
+ if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
+ }
+ features = vhost_net_get_features(get_vhost_net(nc->peer), features);
+ vdev->backend_features = features;
+
+ if (n->mtu_bypass_backend &&
+ (n->host_features & 1ULL << VIRTIO_NET_F_MTU)) {
+ features |= (1ULL << VIRTIO_NET_F_MTU);
+ }
+
+ /*
+ * Since GUEST_ANNOUNCE is emulated the feature bit could be set without
+ * enabled. This happens in the vDPA case.
+ *
+ * Make sure the feature set is not incoherent, as the driver could refuse
+ * to start.
+ *
+ * TODO: QEMU is able to emulate a CVQ just for guest_announce purposes,
+ * helping guest to notify the new location with vDPA devices that does not
+ * support it.
+ */
+ if (!virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_CTRL_VQ)) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ANNOUNCE);
+ }
+
+ return features;
+}
+
static int virtio_net_post_load_device(void *opaque, int version_id)
{
VirtIONet *n = opaque;
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/6] virtio-net: Retrieve peer hashing capability
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
` (2 preceding siblings ...)
2025-05-30 4:33 ` [PATCH 3/6] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
@ 2025-05-30 4:33 ` Akihiko Odaki
2025-05-30 4:33 ` [PATCH 5/6] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
2025-05-30 4:33 ` [PATCH 6/6] virtio-net: Add hash type options Akihiko Odaki
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
Retrieve peer hashing capability instead of hardcoding.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
include/hw/virtio/virtio-net.h | 5 ++-
hw/net/virtio-net.c | 71 ++++++++++++++++++++++++++++++++++--------
net/vhost-vdpa.c | 4 +--
3 files changed, 64 insertions(+), 16 deletions(-)
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index b9ea9e824e3c..c4957c44c06e 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -144,7 +144,10 @@ typedef struct VirtioNetRssData {
bool enabled_software_rss;
bool redirect;
bool populate_hash;
- uint32_t hash_types;
+ bool peer_hash_available;
+ uint32_t runtime_hash_types;
+ uint32_t supported_hash_types;
+ uint32_t peer_hash_types;
uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE];
uint16_t indirections_len;
uint16_t *indirections_table;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 4ebe7f93f5c3..cd5a632596b1 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -158,7 +158,7 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config)
virtio_host_has_feature(vdev, VIRTIO_NET_F_RSS) ?
VIRTIO_NET_RSS_MAX_TABLE_LEN : 1);
virtio_stl_p(vdev, &netcfg.supported_hash_types,
- VIRTIO_NET_RSS_SUPPORTED_HASHES);
+ n->rss_data.supported_hash_types);
memcpy(config, &netcfg, n->config_size);
/*
@@ -1178,7 +1178,7 @@ static void rss_data_to_rss_config(struct VirtioNetRssData *data,
{
config->redirect = data->redirect;
config->populate_hash = data->populate_hash;
- config->hash_types = data->hash_types;
+ config->hash_types = data->runtime_hash_types;
config->indirections_len = data->indirections_len;
config->default_queue = data->default_queue;
}
@@ -1213,6 +1213,10 @@ static void virtio_net_detach_ebpf_rss(VirtIONet *n)
static void virtio_net_commit_rss_config(VirtIONet *n)
{
+ if (n->rss_data.peer_hash_available) {
+ return;
+ }
+
if (n->rss_data.enabled) {
n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
if (n->rss_data.populate_hash) {
@@ -1227,7 +1231,7 @@ static void virtio_net_commit_rss_config(VirtIONet *n)
}
trace_virtio_net_rss_enable(n,
- n->rss_data.hash_types,
+ n->rss_data.runtime_hash_types,
n->rss_data.indirections_len,
sizeof(n->rss_data.key));
} else {
@@ -1338,7 +1342,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
err_value = (uint32_t)s;
goto error;
}
- n->rss_data.hash_types = virtio_ldl_p(vdev, &cfg.hash_types);
+ n->rss_data.runtime_hash_types = virtio_ldl_p(vdev, &cfg.hash_types);
n->rss_data.indirections_len =
virtio_lduw_p(vdev, &cfg.indirection_table_mask);
if (!do_rss) {
@@ -1401,12 +1405,12 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
err_value = temp.b;
goto error;
}
- if (!temp.b && n->rss_data.hash_types) {
+ if (!temp.b && n->rss_data.runtime_hash_types) {
err_msg = "No key provided";
err_value = 0;
goto error;
}
- if (!temp.b && !n->rss_data.hash_types) {
+ if (!temp.b && !n->rss_data.runtime_hash_types) {
virtio_net_disable_rss(n);
return queue_pairs;
}
@@ -1808,7 +1812,7 @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
net_rx_pkt_set_protocols(pkt, &iov, 1, n->host_hdr_len);
net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, l4hdr_proto,
- n->rss_data.hash_types);
+ n->rss_data.runtime_hash_types);
if (net_hash_type > NetPktRssIpV6UdpEx) {
if (n->rss_data.populate_hash) {
hdr->hash_value = VIRTIO_NET_HASH_REPORT_NONE;
@@ -3008,6 +3012,14 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
{
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_queue(n->nic);
+ uint32_t supported_hash_types = n->rss_data.supported_hash_types;
+ uint32_t peer_hash_types = n->rss_data.peer_hash_types;
+ bool use_own_hash =
+ (supported_hash_types & VIRTIO_NET_RSS_SUPPORTED_HASHES) ==
+ supported_hash_types;
+ bool use_peer_hash =
+ n->rss_data.peer_hash_available &&
+ (supported_hash_types & peer_hash_types) == supported_hash_types;
/* Firstly sync all virtio-net possible supported features */
features |= n->host_features;
@@ -3044,12 +3056,28 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
}
if (!get_vhost_net(nc->peer)) {
+ if (!use_own_hash) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
+ virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
+ } else if (virtio_has_feature(features, VIRTIO_NET_F_RSS)) {
+ virtio_net_load_ebpf(n, errp);
+ }
+
return features;
}
- if (!ebpf_rss_is_loaded(&n->ebpf_rss)) {
- virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
+ if (!use_peer_hash) {
+ virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
+
+ if (!use_own_hash || !virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
+ if (!virtio_net_load_ebpf(n, errp)) {
+ return features;
+ }
+
+ virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
+ }
}
+
features = vhost_net_get_features(get_vhost_net(nc->peer), features);
vdev->backend_features = features;
@@ -3314,6 +3342,17 @@ static const VMStateDescription vmstate_virtio_net_has_vnet = {
},
};
+static int virtio_net_rss_post_load(void *opaque, int version_id)
+{
+ VirtIONet *n = VIRTIO_NET(opaque);
+
+ if (version_id == 1) {
+ n->rss_data.supported_hash_types = VIRTIO_NET_RSS_SUPPORTED_HASHES;
+ }
+
+ return 0;
+}
+
static bool virtio_net_rss_needed(void *opaque)
{
return VIRTIO_NET(opaque)->rss_data.enabled;
@@ -3321,14 +3360,16 @@ static bool virtio_net_rss_needed(void *opaque)
static const VMStateDescription vmstate_virtio_net_rss = {
.name = "virtio-net-device/rss",
- .version_id = 1,
+ .version_id = 2,
.minimum_version_id = 1,
+ .post_load = virtio_net_rss_post_load,
.needed = virtio_net_rss_needed,
.fields = (const VMStateField[]) {
VMSTATE_BOOL(rss_data.enabled, VirtIONet),
VMSTATE_BOOL(rss_data.redirect, VirtIONet),
VMSTATE_BOOL(rss_data.populate_hash, VirtIONet),
- VMSTATE_UINT32(rss_data.hash_types, VirtIONet),
+ VMSTATE_UINT32(rss_data.runtime_hash_types, VirtIONet),
+ VMSTATE_UINT32_V(rss_data.supported_hash_types, VirtIONet, 2),
VMSTATE_UINT16(rss_data.indirections_len, VirtIONet),
VMSTATE_UINT16(rss_data.default_queue, VirtIONet),
VMSTATE_UINT8_ARRAY(rss_data.key, VirtIONet,
@@ -3915,8 +3956,12 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
net_rx_pkt_init(&n->rx_pkt);
- if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
- virtio_net_load_ebpf(n, errp);
+ if (qemu_get_vnet_hash_supported_types(qemu_get_queue(n->nic)->peer,
+ &n->rss_data.peer_hash_types)) {
+ n->rss_data.peer_hash_available = true;
+ n->rss_data.supported_hash_types = n->rss_data.peer_hash_types;
+ } else {
+ n->rss_data.supported_hash_types = VIRTIO_NET_RSS_SUPPORTED_HASHES;
}
}
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 1493b08792ea..4f63ded40d47 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -895,13 +895,13 @@ static int vhost_vdpa_net_load_rss(VhostVDPAState *s, const VirtIONet *n,
* configuration only at live migration.
*/
if (!n->rss_data.enabled ||
- n->rss_data.hash_types == VIRTIO_NET_HASH_REPORT_NONE) {
+ n->rss_data.runtime_hash_types == VIRTIO_NET_HASH_REPORT_NONE) {
return 0;
}
table = g_malloc_n(n->rss_data.indirections_len,
sizeof(n->rss_data.indirections_table[0]));
- cfg.hash_types = cpu_to_le32(n->rss_data.hash_types);
+ cfg.hash_types = cpu_to_le32(n->rss_data.runtime_hash_types);
if (do_rss) {
/*
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/6] net/vhost-vdpa: Remove dummy SetSteeringEBPF
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
` (3 preceding siblings ...)
2025-05-30 4:33 ` [PATCH 4/6] virtio-net: Retrieve peer hashing capability Akihiko Odaki
@ 2025-05-30 4:33 ` Akihiko Odaki
2025-05-30 4:33 ` [PATCH 6/6] virtio-net: Add hash type options Akihiko Odaki
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
It is no longer used.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
net/vhost-vdpa.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 4f63ded40d47..149c0f7f1766 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -238,12 +238,6 @@ static void vhost_vdpa_cleanup(NetClientState *nc)
g_free(s->vhost_vdpa.shared);
}
-/** Dummy SetSteeringEBPF to support RSS for vhost-vdpa backend */
-static bool vhost_vdpa_set_steering_ebpf(NetClientState *nc, int prog_fd)
-{
- return true;
-}
-
static bool vhost_vdpa_has_vnet_hdr(NetClientState *nc)
{
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
@@ -470,7 +464,6 @@ static NetClientInfo net_vhost_vdpa_info = {
.has_ufo = vhost_vdpa_has_ufo,
.set_vnet_le = vhost_vdpa_set_vnet_le,
.check_peer_type = vhost_vdpa_check_peer_type,
- .set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
};
static int64_t vhost_vdpa_get_vring_group(int device_fd, unsigned vq_index,
@@ -1344,7 +1337,6 @@ static NetClientInfo net_vhost_vdpa_cvq_info = {
.get_vnet_hash_supported_types = vhost_vdpa_get_vnet_hash_supported_types,
.has_ufo = vhost_vdpa_has_ufo,
.check_peer_type = vhost_vdpa_check_peer_type,
- .set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
};
/*
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 6/6] virtio-net: Add hash type options
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
` (4 preceding siblings ...)
2025-05-30 4:33 ` [PATCH 5/6] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
@ 2025-05-30 4:33 ` Akihiko Odaki
5 siblings, 0 replies; 7+ messages in thread
From: Akihiko Odaki @ 2025-05-30 4:33 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, Paolo Abeni, devel,
Akihiko Odaki
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 | 45 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index c4957c44c06e..73fdefc0dcb8 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -148,6 +148,7 @@ typedef struct VirtioNetRssData {
uint32_t runtime_hash_types;
uint32_t supported_hash_types;
uint32_t peer_hash_types;
+ OnOffAutoBit64 specified_hash_types;
uint8_t key[VIRTIO_NET_RSS_MAX_KEY_SIZE];
uint16_t indirections_len;
uint16_t *indirections_table;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index cd5a632596b1..52fe404b3431 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3959,9 +3959,14 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
if (qemu_get_vnet_hash_supported_types(qemu_get_queue(n->nic)->peer,
&n->rss_data.peer_hash_types)) {
n->rss_data.peer_hash_available = true;
- n->rss_data.supported_hash_types = n->rss_data.peer_hash_types;
+ n->rss_data.supported_hash_types =
+ n->rss_data.specified_hash_types.on_bits |
+ (n->rss_data.specified_hash_types.auto_bits &
+ n->rss_data.peer_hash_types);
} else {
- n->rss_data.supported_hash_types = VIRTIO_NET_RSS_SUPPORTED_HASHES;
+ n->rss_data.supported_hash_types =
+ n->rss_data.specified_hash_types.on_bits |
+ n->rss_data.specified_hash_types.auto_bits;
}
}
@@ -4178,6 +4183,42 @@ static const Property virtio_net_properties[] = {
VIRTIO_NET_F_GUEST_USO6, true),
DEFINE_PROP_BIT64("host_uso", VirtIONet, host_features,
VIRTIO_NET_F_HOST_USO, true),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-ipv4", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_IPv4 - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-tcp4", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_TCPv4 - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-udp4", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_UDPv4 - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-ipv6", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_IPv6 - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-tcp6", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_TCPv6 - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-udp6", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_UDPv6 - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-ipv6ex", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_IPv6_EX - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-tcp6ex", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_TCPv6_EX - 1,
+ ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_ON_OFF_AUTO_BIT64("hash-udp6ex", VirtIONet,
+ rss_data.specified_hash_types,
+ VIRTIO_NET_HASH_REPORT_UDPv6_EX - 1,
+ ON_OFF_AUTO_AUTO),
};
static void virtio_net_class_init(ObjectClass *klass, const void *data)
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-05-30 4:35 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-30 4:33 [PATCH 0/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
2025-05-30 4:33 ` [PATCH 1/6] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
2025-05-30 4:33 ` [PATCH 2/6] net/vhost-vdpa: Report hashing capability Akihiko Odaki
2025-05-30 4:33 ` [PATCH 3/6] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
2025-05-30 4:33 ` [PATCH 4/6] virtio-net: Retrieve peer hashing capability Akihiko Odaki
2025-05-30 4:33 ` [PATCH 5/6] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
2025-05-30 4:33 ` [PATCH 6/6] virtio-net: Add hash type options Akihiko Odaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).