* [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF
@ 2025-03-13 6:55 Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 01/11] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: Akihiko Odaki
I'm proposing to add a feature to offload virtio-net RSS/hash report to
Linux. This series contain patches to utilize the proposed Linux feature.
The patches for Linux are available at:
https://lore.kernel.org/r/20250307-rss-v9-0-df76624025eb@daynix.com/
This work was presented at LPC 2024:
https://lpc.events/event/18/contributions/1963/
Patch "docs/devel/ebpf_rss.rst: Update for peer RSS" provides comparion
of existing RSS mechanism and the new one (called "peer RSS") and
explains how QEMU selects one.
---
Changes in v4:
- Rebased.
- Added a reference to the documentation to the cover letter.
- Link to v3: https://lore.kernel.org/r/20240915-hash-v3-0-79cb08d28647@daynix.com
---
Akihiko Odaki (11):
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
net: Allow configuring virtio hashing
virtio-net: Use qemu_set_vnet_hash()
virtio-net: Offload hashing without vhost
tap: Report virtio-net hashing support on Linux
docs/devel/ebpf_rss.rst: Update for peer RSS
docs/devel/ebpf_rss.rst | 23 ++-
include/hw/qdev-properties.h | 18 +++
include/hw/virtio/virtio-net.h | 6 +-
include/net/net.h | 20 +++
net/tap-linux.h | 2 +
net/tap_int.h | 3 +
hw/core/qdev-properties.c | 67 ++++++++-
hw/net/virtio-net.c | 331 +++++++++++++++++++++++++++++------------
net/net.c | 14 ++
net/tap-bsd.c | 10 ++
net/tap-linux.c | 18 +++
net/tap-solaris.c | 10 ++
net/tap-stub.c | 10 ++
net/tap.c | 15 ++
net/vhost-vdpa.c | 41 ++++-
15 files changed, 478 insertions(+), 110 deletions(-)
---
base-commit: 825b96dbcee23d134b691fc75618b59c5f53da32
change-id: 20240828-hash-628329a45d4d
Best regards,
--
Akihiko Odaki <akihiko.odaki@daynix.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH RFC v4 01/11] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64()
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 02/11] net/vhost-vdpa: Report hashing capability Akihiko Odaki
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: 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 15fcec5260c7..61f13aca6cf4 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;
@@ -99,6 +110,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 c04df3b337ae..05a627030141 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.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 02/11] net/vhost-vdpa: Report hashing capability
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 01/11] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 03/11] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: 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 f7a54f46aa72..de006f3a2265 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);
@@ -428,6 +454,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,
.check_peer_type = vhost_vdpa_check_peer_type,
.set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
@@ -1301,6 +1328,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.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 03/11] virtio-net: Move virtio_net_get_features() down
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 01/11] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 02/11] net/vhost-vdpa: Report hashing capability Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 04/11] virtio-net: Retrieve peer hashing capability Akihiko Odaki
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: 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 de87cfadffe1..df8de1148ba4 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -751,79 +751,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;
@@ -3080,6 +3007,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.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 04/11] virtio-net: Retrieve peer hashing capability
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (2 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 03/11] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: 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 df8de1148ba4..133317d8c358 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);
/*
@@ -1177,7 +1177,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;
}
@@ -1212,6 +1212,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) {
@@ -1226,7 +1230,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 {
@@ -1337,7 +1341,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) {
@@ -1400,12 +1404,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;
}
@@ -1810,7 +1814,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;
@@ -3012,6 +3016,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;
@@ -3048,12 +3060,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;
@@ -3318,6 +3346,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;
@@ -3325,14 +3364,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,
@@ -3919,8 +3960,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 de006f3a2265..0e9f4482ce7a 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -882,13 +882,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.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (3 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 04/11] virtio-net: Retrieve peer hashing capability Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 06/11] virtio-net: Add hash type options Akihiko Odaki
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: 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 0e9f4482ce7a..d35348b1e742 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);
@@ -457,7 +451,6 @@ static NetClientInfo net_vhost_vdpa_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,
};
static int64_t vhost_vdpa_get_vring_group(int device_fd, unsigned vq_index,
@@ -1331,7 +1324,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.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 06/11] virtio-net: Add hash type options
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (4 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 07/11] net: Allow configuring virtio hashing Akihiko Odaki
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: 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 133317d8c358..b0f2ad78cb39 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3963,9 +3963,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;
}
}
@@ -4182,6 +4187,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, void *data)
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 07/11] net: Allow configuring virtio hashing
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (5 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 06/11] virtio-net: Add hash type options Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 08/11] virtio-net: Use qemu_set_vnet_hash() Akihiko Odaki
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: Akihiko Odaki
This adds set_vnet_hash() to configure virtio hashing and implements it
for Linux's tap. vDPA will have an empty function as configuring virtio
hashing is done with the load().
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
include/net/net.h | 17 +++++++++++++++++
net/tap-linux.h | 1 +
net/tap_int.h | 2 ++
net/net.c | 5 +++++
net/tap-bsd.c | 5 +++++
net/tap-linux.c | 5 +++++
net/tap-solaris.c | 5 +++++
net/tap-stub.c | 5 +++++
net/tap.c | 7 +++++++
net/vhost-vdpa.c | 7 +++++++
10 files changed, 59 insertions(+)
diff --git a/include/net/net.h b/include/net/net.h
index 545f4339cec8..fa69e14c9829 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -35,6 +35,20 @@ typedef struct NICConf {
int32_t bootindex;
} NICConf;
+#define NET_VNET_HASH_REPORT 1
+#define NET_VNET_HASH_RSS 2
+
+typedef struct NetVnetHash {
+ uint16_t flags;
+ uint8_t pad[2];
+ uint32_t types;
+} NetVnetHash;
+
+typedef struct NetVnetHashRss {
+ uint16_t indirection_table_mask;
+ uint16_t unclassified_queue;
+} NetVnetHashRss;
+
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
@@ -61,6 +75,7 @@ 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 void (SetVnetHash)(NetClientState *, const NetVnetHash *);
typedef int (SetVnetLE)(NetClientState *, bool);
typedef int (SetVnetBE)(NetClientState *, bool);
typedef struct SocketReadState SocketReadState;
@@ -91,6 +106,7 @@ typedef struct NetClientInfo {
SetVnetLE *set_vnet_le;
SetVnetBE *set_vnet_be;
GetVnetHashSupportedTypes *get_vnet_hash_supported_types;
+ SetVnetHash *set_vnet_hash;
NetAnnounce *announce;
SetSteeringEBPF *set_steering_ebpf;
NetCheckPeerType *check_peer_type;
@@ -192,6 +208,7 @@ void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
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);
+void qemu_set_vnet_hash(NetClientState *nc, const NetVnetHash *hash);
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/tap-linux.h b/net/tap-linux.h
index 9a58cecb7f47..5fac64c24f99 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -32,6 +32,7 @@
#define TUNSETVNETLE _IOW('T', 220, int)
#define TUNSETVNETBE _IOW('T', 222, int)
#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
+#define TUNSETVNETHASH _IOW('T', 229, NetVnetHash)
#endif
diff --git a/net/tap_int.h b/net/tap_int.h
index 8857ff299d22..e1b53e343397 100644
--- a/net/tap_int.h
+++ b/net/tap_int.h
@@ -27,6 +27,7 @@
#define NET_TAP_INT_H
#include "qapi/qapi-types-net.h"
+#include "net/net.h"
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
int vnet_hdr_required, int mq_required, Error **errp);
@@ -40,6 +41,7 @@ int tap_probe_has_uso(int fd);
void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
int uso4, int uso6);
void tap_fd_set_vnet_hdr_len(int fd, int len);
+void tap_fd_set_vnet_hash(int fd, const NetVnetHash *hash);
int tap_fd_set_vnet_le(int fd, int vnet_is_le);
int tap_fd_set_vnet_be(int fd, int vnet_is_be);
int tap_fd_enable(int fd);
diff --git a/net/net.c b/net/net.c
index d0ae3db0d864..eaf82082137d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -582,6 +582,11 @@ bool qemu_get_vnet_hash_supported_types(NetClientState *nc, uint32_t *types)
return nc->info->get_vnet_hash_supported_types(nc, types);
}
+void qemu_set_vnet_hash(NetClientState *nc, const NetVnetHash *hash)
+{
+ nc->info->set_vnet_hash(nc, hash);
+}
+
int qemu_set_vnet_le(NetClientState *nc, bool is_le)
{
#if HOST_BIG_ENDIAN
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index b4c84441ba8b..2eee0c0a0ec5 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -221,6 +221,11 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
{
}
+void tap_fd_set_vnet_hash(int fd, const NetVnetHash *hash)
+{
+ g_assert_not_reached();
+}
+
int tap_fd_set_vnet_le(int fd, int is_le)
{
return -EINVAL;
diff --git a/net/tap-linux.c b/net/tap-linux.c
index 22ec2f45d2b7..c053828b056b 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -205,6 +205,11 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
}
}
+void tap_fd_set_vnet_hash(int fd, const NetVnetHash *hash)
+{
+ assert(!ioctl(fd, TUNSETVNETHASH, hash));
+}
+
int tap_fd_set_vnet_le(int fd, int is_le)
{
int arg = is_le ? 1 : 0;
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index 51b7830bef1d..c65104b84e93 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -225,6 +225,11 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
{
}
+void tap_fd_set_vnet_hash(int fd, const NetVnetHash *hash)
+{
+ g_assert_not_reached();
+}
+
int tap_fd_set_vnet_le(int fd, int is_le)
{
return -EINVAL;
diff --git a/net/tap-stub.c b/net/tap-stub.c
index 38673434cbd6..5bdc76216b7f 100644
--- a/net/tap-stub.c
+++ b/net/tap-stub.c
@@ -56,6 +56,11 @@ void tap_fd_set_vnet_hdr_len(int fd, int len)
{
}
+void tap_fd_set_vnet_hash(int fd, const NetVnetHash *hash)
+{
+ g_assert_not_reached();
+}
+
int tap_fd_set_vnet_le(int fd, int is_le)
{
return -EINVAL;
diff --git a/net/tap.c b/net/tap.c
index ae1c7e398321..1136018c1965 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -248,6 +248,12 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
s->using_vnet_hdr = true;
}
+static void tap_set_vnet_hash(NetClientState *nc, const NetVnetHash *hash)
+{
+ TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ return tap_fd_set_vnet_hash(s->fd, hash);
+}
+
static int tap_set_vnet_le(NetClientState *nc, bool is_le)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
@@ -344,6 +350,7 @@ static NetClientInfo net_tap_info = {
.has_vnet_hdr_len = tap_has_vnet_hdr_len,
.set_offload = tap_set_offload,
.set_vnet_hdr_len = tap_set_vnet_hdr_len,
+ .set_vnet_hash = tap_set_vnet_hash,
.set_vnet_le = tap_set_vnet_le,
.set_vnet_be = tap_set_vnet_be,
.set_steering_ebpf = tap_set_steering_ebpf,
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index d35348b1e742..e5ee7cd22d4f 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -271,6 +271,11 @@ static bool vhost_vdpa_get_vnet_hash_supported_types(NetClientState *nc,
return true;
}
+static void vhost_vdpa_set_vnet_hash(NetClientState *nc,
+ const NetVnetHash *hash)
+{
+}
+
static bool vhost_vdpa_has_ufo(NetClientState *nc)
{
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
@@ -449,6 +454,7 @@ static NetClientInfo net_vhost_vdpa_info = {
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
.get_vnet_hash_supported_types = vhost_vdpa_get_vnet_hash_supported_types,
+ .set_vnet_hash = vhost_vdpa_set_vnet_hash,
.has_ufo = vhost_vdpa_has_ufo,
.check_peer_type = vhost_vdpa_check_peer_type,
};
@@ -1322,6 +1328,7 @@ static NetClientInfo net_vhost_vdpa_cvq_info = {
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
.get_vnet_hash_supported_types = vhost_vdpa_get_vnet_hash_supported_types,
+ .set_vnet_hash = vhost_vdpa_set_vnet_hash,
.has_ufo = vhost_vdpa_has_ufo,
.check_peer_type = vhost_vdpa_check_peer_type,
};
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 08/11] virtio-net: Use qemu_set_vnet_hash()
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (6 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 07/11] net: Allow configuring virtio hashing Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 09/11] virtio-net: Offload hashing without vhost Akihiko Odaki
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: Akihiko Odaki
This is necessary to offload hashing to tap.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 77 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 64 insertions(+), 13 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index b0f2ad78cb39..e125478ae834 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1212,20 +1212,65 @@ 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) {
- virtio_net_detach_ebpf_rss(n);
- } else if (!virtio_net_attach_ebpf_rss(n)) {
- if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
- warn_report("Can't load eBPF RSS for vhost");
+ if (n->rss_data.peer_hash_available &&
+ (n->rss_data.peer_hash_types & n->rss_data.runtime_hash_types) ==
+ n->rss_data.runtime_hash_types) {
+ NetVnetHash hash = {
+ .flags = (n->rss_data.redirect ? NET_VNET_HASH_RSS : 0) |
+ (n->rss_data.populate_hash ? NET_VNET_HASH_REPORT : 0),
+ .types = n->rss_data.runtime_hash_types
+ };
+
+ if (n->rss_data.redirect) {
+ size_t indirection_table_size =
+ n->rss_data.indirections_len *
+ sizeof(*n->rss_data.indirections_table);
+
+ size_t hash_size = sizeof(NetVnetHash) +
+ sizeof(NetVnetHashRss) +
+ indirection_table_size +
+ sizeof(n->rss_data.key);
+
+ g_autofree struct {
+ NetVnetHash hdr;
+ NetVnetHashRss rss;
+ uint8_t footer[];
+ } *rss = g_malloc(hash_size);
+
+ rss->hdr = hash;
+ rss->rss.indirection_table_mask =
+ n->rss_data.indirections_len - 1;
+ rss->rss.unclassified_queue = n->rss_data.default_queue;
+
+ memcpy(rss->footer, n->rss_data.indirections_table,
+ indirection_table_size);
+
+ memcpy(rss->footer + indirection_table_size, n->rss_data.key,
+ sizeof(n->rss_data.key));
+
+ qemu_set_vnet_hash(qemu_get_queue(n->nic)->peer, &rss->hdr);
} else {
- warn_report("Can't load eBPF RSS - fallback to software RSS");
- n->rss_data.enabled_software_rss = true;
+ qemu_set_vnet_hash(qemu_get_queue(n->nic)->peer, &hash);
+ }
+
+ n->rss_data.enabled_software_rss = false;
+ } else {
+ if (n->rss_data.peer_hash_available) {
+ NetVnetHash hash = { .flags = 0 };
+ qemu_set_vnet_hash(qemu_get_queue(n->nic)->peer, &hash);
+ }
+
+ n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
+ if (n->rss_data.populate_hash) {
+ virtio_net_detach_ebpf_rss(n);
+ } else if (!virtio_net_attach_ebpf_rss(n)) {
+ if (get_vhost_net(qemu_get_queue(n->nic)->peer)) {
+ warn_report("Can't load eBPF RSS for vhost");
+ } else {
+ warn_report("Can't load eBPF RSS - fallback to software RSS");
+ n->rss_data.enabled_software_rss = true;
+ }
}
}
@@ -1234,7 +1279,13 @@ static void virtio_net_commit_rss_config(VirtIONet *n)
n->rss_data.indirections_len,
sizeof(n->rss_data.key));
} else {
- virtio_net_detach_ebpf_rss(n);
+ if (n->rss_data.peer_hash_available) {
+ NetVnetHash hash = { .flags = 0 };
+ qemu_set_vnet_hash(qemu_get_queue(n->nic)->peer, &hash);
+ } else {
+ virtio_net_detach_ebpf_rss(n);
+ }
+
trace_virtio_net_rss_disable(n);
}
}
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 09/11] virtio-net: Offload hashing without vhost
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (7 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 08/11] virtio-net: Use qemu_set_vnet_hash() Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 10/11] tap: Report virtio-net hashing support on Linux Akihiko Odaki
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: Akihiko Odaki
This is necessary to offload hashing to tap.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index e125478ae834..edfc76a5308e 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1712,7 +1712,11 @@ static size_t receive_header(VirtIONet *n, struct virtio_net_hdr *hdr,
{
size_t hdr_len = n->guest_hdr_len;
- memcpy(hdr, buf, sizeof(struct virtio_net_hdr));
+ memcpy(hdr, buf,
+ n->rss_data.populate_hash &&
+ n->rss_data.enabled && !n->rss_data.enabled_software_rss ?
+ sizeof(struct virtio_net_hdr_v1_hash) :
+ sizeof(struct virtio_net_hdr));
*buf_offset = n->host_hdr_len;
work_around_broken_dhclient(hdr, &hdr_len, buf, buf_size, buf_offset);
@@ -3111,11 +3115,13 @@ 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);
+ if (!use_peer_hash) {
+ 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;
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 10/11] tap: Report virtio-net hashing support on Linux
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (8 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 09/11] virtio-net: Offload hashing without vhost Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS Akihiko Odaki
2025-03-17 9:40 ` [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Lei Yang
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: Akihiko Odaki
This allows offloading virtio-net hashing to tap on Linux.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
net/tap-linux.h | 1 +
net/tap_int.h | 1 +
net/tap-bsd.c | 5 +++++
net/tap-linux.c | 13 +++++++++++++
net/tap-solaris.c | 5 +++++
net/tap-stub.c | 5 +++++
net/tap.c | 8 ++++++++
7 files changed, 38 insertions(+)
diff --git a/net/tap-linux.h b/net/tap-linux.h
index 5fac64c24f99..c773609c799e 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -32,6 +32,7 @@
#define TUNSETVNETLE _IOW('T', 220, int)
#define TUNSETVNETBE _IOW('T', 222, int)
#define TUNSETSTEERINGEBPF _IOR('T', 224, int)
+#define TUNGETVNETHASHCAP _IOR('T', 228, NetVnetHash)
#define TUNSETVNETHASH _IOW('T', 229, NetVnetHash)
#endif
diff --git a/net/tap_int.h b/net/tap_int.h
index e1b53e343397..84a88841b720 100644
--- a/net/tap_int.h
+++ b/net/tap_int.h
@@ -36,6 +36,7 @@ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
int tap_probe_vnet_hdr(int fd, Error **errp);
+bool tap_probe_vnet_hash_supported_types(int fd, uint32_t *types);
int tap_probe_has_ufo(int fd);
int tap_probe_has_uso(int fd);
void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 2eee0c0a0ec5..142e1abe0420 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -217,6 +217,11 @@ int tap_probe_has_uso(int fd)
return 0;
}
+bool tap_probe_vnet_hash_supported_types(int fd, uint32_t *types)
+{
+ return false;
+}
+
void tap_fd_set_vnet_hdr_len(int fd, int len)
{
}
diff --git a/net/tap-linux.c b/net/tap-linux.c
index c053828b056b..b45039ecbbb1 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -196,6 +196,19 @@ int tap_probe_has_uso(int fd)
return 1;
}
+bool tap_probe_vnet_hash_supported_types(int fd, uint32_t *types)
+{
+ NetVnetHash hash;
+
+ if (ioctl(fd, TUNGETVNETHASHCAP, &hash)) {
+ return false;
+ }
+
+ *types = hash.types;
+
+ return true;
+}
+
void tap_fd_set_vnet_hdr_len(int fd, int len)
{
if (ioctl(fd, TUNSETVNETHDRSZ, &len) == -1) {
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index c65104b84e93..00d1c850680d 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -221,6 +221,11 @@ int tap_probe_has_uso(int fd)
return 0;
}
+bool tap_probe_vnet_hash_supported_types(int fd, uint32_t *types)
+{
+ return false;
+}
+
void tap_fd_set_vnet_hdr_len(int fd, int len)
{
}
diff --git a/net/tap-stub.c b/net/tap-stub.c
index 5bdc76216b7f..a4718654fbeb 100644
--- a/net/tap-stub.c
+++ b/net/tap-stub.c
@@ -52,6 +52,11 @@ int tap_probe_has_uso(int fd)
return 0;
}
+bool tap_probe_vnet_hash_supported_types(int fd, uint32_t *types)
+{
+ return false;
+}
+
void tap_fd_set_vnet_hdr_len(int fd, int len)
{
}
diff --git a/net/tap.c b/net/tap.c
index 1136018c1965..98083bcd515e 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -248,6 +248,13 @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
s->using_vnet_hdr = true;
}
+static bool tap_get_vnet_hash_supported_types(NetClientState *nc,
+ uint32_t *types)
+{
+ TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ return tap_probe_vnet_hash_supported_types(s->fd, types);
+}
+
static void tap_set_vnet_hash(NetClientState *nc, const NetVnetHash *hash)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
@@ -350,6 +357,7 @@ static NetClientInfo net_tap_info = {
.has_vnet_hdr_len = tap_has_vnet_hdr_len,
.set_offload = tap_set_offload,
.set_vnet_hdr_len = tap_set_vnet_hdr_len,
+ .get_vnet_hash_supported_types = tap_get_vnet_hash_supported_types,
.set_vnet_hash = tap_set_vnet_hash,
.set_vnet_le = tap_set_vnet_le,
.set_vnet_be = tap_set_vnet_be,
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH RFC v4 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (9 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 10/11] tap: Report virtio-net hashing support on Linux Akihiko Odaki
@ 2025-03-13 6:55 ` Akihiko Odaki
2025-03-17 9:40 ` [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Lei Yang
11 siblings, 0 replies; 13+ messages in thread
From: Akihiko Odaki @ 2025-03-13 6:55 UTC (permalink / raw)
To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
Cc: Akihiko Odaki
eBPF RSS virtio-net support was written in assumption that there is only
one alternative RSS implementation: 'in-qemu' RSS. It is no longer true,
and we now have yet another implementation; namely the peer RSS.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
| 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
--git a/docs/devel/ebpf_rss.rst b/docs/devel/ebpf_rss.rst
index ed5d33767bd5..f128f0990905 100644
--- a/docs/devel/ebpf_rss.rst
+++ b/docs/devel/ebpf_rss.rst
@@ -7,9 +7,22 @@ eBPF RSS virtio-net support
RSS(Receive Side Scaling) is used to distribute network packets to guest virtqueues
by calculating packet hash. Usually every queue is processed then by a specific guest CPU core.
-For now there are 2 RSS implementations in qemu:
-- 'in-qemu' RSS (functions if qemu receives network packets, i.e. vhost=off)
-- eBPF RSS (can function with also with vhost=on)
+For now there are 3 RSS implementations in qemu:
+1. Peer RSS
+2. eBPF RSS
+3. 'In-QEMU' RSS
+
+'In-QEMU' RSS is incompatible with vhost since the packets are not routed to
+QEMU. eBPF RSS requires Linux 5.8+. Peer RSS requires the peer to implement RSS.
+Currently QEMU can use the RSS implementation of vDPA and Linux's TUN module
+with the following patch applied:
+https://lore.kernel.org/r/20240915-rss-v3-0-c630015db082@daynix.com/
+
+eBPF RSS does not support hash reporting. Peer RSS may support limited hash
+types.
+
+virtio-net automatically chooses the RSS implementation to use. Peer RSS is
+the most preferred, and 'in-QEMU' RSS is the least.
eBPF support (CONFIG_EBPF) is enabled by 'configure' script.
To enable eBPF RSS support use './configure --enable-bpf'.
@@ -49,9 +62,6 @@ eBPF RSS turned on by different combinations of vhost-net, vitrio-net and tap co
tap,vhost=on & virtio-net-pci,rss=on,hash=on
-If CONFIG_EBPF is not set then only 'in-qemu' RSS is supported.
-Also 'in-qemu' RSS, as a fallback, is used if the eBPF program failed to load or set to TUN.
-
RSS eBPF program
----------------
@@ -67,7 +77,6 @@ Prerequisites to recompile the eBPF program (regenerate ebpf/rss.bpf.skeleton.h)
$ make -f Makefile.ebpf
Current eBPF RSS implementation uses 'bounded loops' with 'backward jump instructions' which present in the last kernels.
-Overall eBPF RSS works on kernels 5.8+.
eBPF RSS implementation
-----------------------
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
` (10 preceding siblings ...)
2025-03-13 6:55 ` [PATCH RFC v4 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS Akihiko Odaki
@ 2025-03-17 9:40 ` Lei Yang
11 siblings, 0 replies; 13+ messages in thread
From: Lei Yang @ 2025-03-17 9:40 UTC (permalink / raw)
To: Akihiko Odaki
Cc: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
Michael S . Tsirkin, Jason Wang, devel
QE tested this RFC series of patches with virtio-net regression tests,
everything works fine.
Tested-by: Lei Yang <leiyang@redhat.com>
On Thu, Mar 13, 2025 at 2:56 PM Akihiko Odaki <akihiko.odaki@daynix.com> wrote:
>
> I'm proposing to add a feature to offload virtio-net RSS/hash report to
> Linux. This series contain patches to utilize the proposed Linux feature.
> The patches for Linux are available at:
> https://lore.kernel.org/r/20250307-rss-v9-0-df76624025eb@daynix.com/
>
> This work was presented at LPC 2024:
> https://lpc.events/event/18/contributions/1963/
>
> Patch "docs/devel/ebpf_rss.rst: Update for peer RSS" provides comparion
> of existing RSS mechanism and the new one (called "peer RSS") and
> explains how QEMU selects one.
>
> ---
> Changes in v4:
> - Rebased.
> - Added a reference to the documentation to the cover letter.
> - Link to v3: https://lore.kernel.org/r/20240915-hash-v3-0-79cb08d28647@daynix.com
>
> ---
> Akihiko Odaki (11):
> 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
> net: Allow configuring virtio hashing
> virtio-net: Use qemu_set_vnet_hash()
> virtio-net: Offload hashing without vhost
> tap: Report virtio-net hashing support on Linux
> docs/devel/ebpf_rss.rst: Update for peer RSS
>
> docs/devel/ebpf_rss.rst | 23 ++-
> include/hw/qdev-properties.h | 18 +++
> include/hw/virtio/virtio-net.h | 6 +-
> include/net/net.h | 20 +++
> net/tap-linux.h | 2 +
> net/tap_int.h | 3 +
> hw/core/qdev-properties.c | 67 ++++++++-
> hw/net/virtio-net.c | 331 +++++++++++++++++++++++++++++------------
> net/net.c | 14 ++
> net/tap-bsd.c | 10 ++
> net/tap-linux.c | 18 +++
> net/tap-solaris.c | 10 ++
> net/tap-stub.c | 10 ++
> net/tap.c | 15 ++
> net/vhost-vdpa.c | 41 ++++-
> 15 files changed, 478 insertions(+), 110 deletions(-)
> ---
> base-commit: 825b96dbcee23d134b691fc75618b59c5f53da32
> change-id: 20240828-hash-628329a45d4d
>
> Best regards,
> --
> Akihiko Odaki <akihiko.odaki@daynix.com>
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-03-17 9:42 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-13 6:55 [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 01/11] qdev-properties: Add DEFINE_PROP_ON_OFF_AUTO_BIT64() Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 02/11] net/vhost-vdpa: Report hashing capability Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 03/11] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 04/11] virtio-net: Retrieve peer hashing capability Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 06/11] virtio-net: Add hash type options Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 07/11] net: Allow configuring virtio hashing Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 08/11] virtio-net: Use qemu_set_vnet_hash() Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 09/11] virtio-net: Offload hashing without vhost Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 10/11] tap: Report virtio-net hashing support on Linux Akihiko Odaki
2025-03-13 6:55 ` [PATCH RFC v4 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS Akihiko Odaki
2025-03-17 9:40 ` [PATCH RFC v4 00/11] virtio-net: Offload hashing without eBPF Lei Yang
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).