qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF
@ 2024-09-15  1:23 Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 01/11] qdev-properties: DEFINE_PROP_ON_OFF_AUTO_BIT() Akihiko Odaki
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  Cc: Akihiko Odaki

Based-on: <20240915-queue-v1-0-b49bd49b926d@daynix.com>
("[PATCH 0/7] virtio-net fixes")

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/20240915-rss-v3-0-c630015db082@daynix.com/

This work will be presented at LPC 2024:
https://lpc.events/event/18/contributions/1963/

---
Akihiko Odaki (11):
      qdev-properties: DEFINE_PROP_ON_OFF_AUTO_BIT()
      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      |  66 ++++++++-
 hw/net/virtio-net.c            | 327 +++++++++++++++++++++++++++++------------
 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, 473 insertions(+), 110 deletions(-)
---
base-commit: decf357a35b1201b34cc37c47b4b027f9601855e
change-id: 20240828-hash-628329a45d4d

Best regards,
-- 
Akihiko Odaki <akihiko.odaki@daynix.com>



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 01/11] qdev-properties: DEFINE_PROP_ON_OFF_AUTO_BIT()
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 02/11] net/vhost-vdpa: Report hashing capability Akihiko Odaki
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  Cc: Akihiko Odaki

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 include/hw/qdev-properties.h | 18 ++++++++++++
 hw/core/qdev-properties.c    | 66 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 09aa04ca1e27..678837569784 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -43,10 +43,21 @@ struct PropertyInfo {
     ObjectPropertyRelease *release;
 };
 
+/**
+ * struct OnOffAutoBit - OnOffAuto storage with 64 elements.
+ * @on_bits: Bitmap of elements with "on".
+ * @auto_bits: Bitmap of elements with "auto".
+ */
+typedef struct OnOffAutoBit {
+    uint32_t on_bits;
+    uint32_t auto_bits;
+} OnOffAutoBit;
+
 
 /*** qdev-properties.c ***/
 
 extern const PropertyInfo qdev_prop_bit;
+extern const PropertyInfo qdev_prop_on_off_auto_bit;
 extern const PropertyInfo qdev_prop_bit64;
 extern const PropertyInfo qdev_prop_bool;
 extern const PropertyInfo qdev_prop_enum;
@@ -86,6 +97,13 @@ extern const PropertyInfo qdev_prop_link;
                 .set_default = true,                            \
                 .defval.u    = (bool)_defval)
 
+#define DEFINE_PROP_ON_OFF_AUTO_BIT(_name, _state, _field, _bit, _defval) \
+    DEFINE_PROP(_name, _state, _field, qdev_prop_on_off_auto_bit,         \
+                OnOffAutoBit,                                             \
+                .bitnr    = (_bit),                                       \
+                .set_default = true,                                      \
+                .defval.i = (OnOffAuto)_defval)
+
 #define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) \
     DEFINE_PROP(_name, _state, _field, _prop, _type,                       \
                 .set_default = true,                                       \
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 86a583574dd0..e1ff992e7177 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -133,7 +133,8 @@ const PropertyInfo qdev_prop_enum = {
 
 static uint32_t qdev_get_prop_mask(Property *prop)
 {
-    assert(prop->info == &qdev_prop_bit);
+    assert(prop->info == &qdev_prop_bit ||
+           prop->info == &qdev_prop_on_off_auto_bit);
     return 0x1 << prop->bitnr;
 }
 
@@ -183,6 +184,69 @@ const PropertyInfo qdev_prop_bit = {
     .set_default_value = set_default_value_bool,
 };
 
+static void prop_get_on_off_auto_bit(Object *obj, Visitor *v,
+                                     const char *name, void *opaque,
+                                     Error **errp)
+{
+    Property *prop = opaque;
+    OnOffAutoBit *p = object_field_prop_ptr(obj, prop);
+    int value;
+    uint32_t mask = qdev_get_prop_mask(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_enum(v, name, &value, &OnOffAuto_lookup, errp);
+}
+
+static void prop_set_on_off_auto_bit(Object *obj, Visitor *v,
+                                     const char *name, void *opaque,
+                                     Error **errp)
+{
+    Property *prop = opaque;
+    OnOffAutoBit *p = object_field_prop_ptr(obj, prop);
+    bool bool_value;
+    int value;
+    uint32_t mask = qdev_get_prop_mask(prop);
+
+    if (visit_type_bool(v, name, &bool_value, NULL)) {
+        value = bool_value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+    } else if (!visit_type_enum(v, name, &value, &OnOffAuto_lookup, 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;
+    }
+}
+
+const PropertyInfo qdev_prop_on_off_auto_bit = {
+    .name  = "OnOffAuto",
+    .description = "on/off/auto",
+    .enum_table = &OnOffAuto_lookup,
+    .get = prop_get_on_off_auto_bit,
+    .set = prop_set_on_off_auto_bit,
+    .set_default_value = qdev_propinfo_set_default_value_enum,
+};
+
 /* Bit64 */
 
 static uint64_t qdev_get_prop_mask64(Property *prop)

-- 
2.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 02/11] net/vhost-vdpa: Report hashing capability
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 01/11] qdev-properties: DEFINE_PROP_ON_OFF_AUTO_BIT() Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 03/11] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 c8f679761bf9..099616c8cbe3 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;
@@ -192,6 +194,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 6938da05e077..3b04f8fe5d6b 100644
--- a/net/net.c
+++ b/net/net.c
@@ -559,6 +559,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 03457ead663a..af0c3c448c1f 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -258,6 +258,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);
@@ -436,6 +462,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,
@@ -1303,6 +1330,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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 03/11] virtio-net: Move virtio_net_get_features() down
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 01/11] qdev-properties: DEFINE_PROP_ON_OFF_AUTO_BIT() Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 02/11] net/vhost-vdpa: Report hashing capability Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 04/11] virtio-net: Retrieve peer hashing capability Akihiko Odaki
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 b4a3fb575c7c..206b0335169d 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -750,79 +750,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;
@@ -3041,6 +2968,79 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
     virtio_net_set_queue_pairs(n);
 }
 
+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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 04/11] virtio-net: Retrieve peer hashing capability
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (2 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 03/11] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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            | 67 ++++++++++++++++++++++++++++++++++--------
 net/vhost-vdpa.c               |  4 +--
 3 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 060c23c04d2d..202016ec74fc 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 206b0335169d..3da15a60eaa5 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -157,7 +157,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);
 
     /*
@@ -1175,7 +1175,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;
 }
@@ -1209,6 +1209,10 @@ static void virtio_net_detach_epbf_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) {
@@ -1222,7 +1226,7 @@ static void virtio_net_commit_rss_config(VirtIONet *n)
             }
         }
 
-        trace_virtio_net_rss_enable(n->rss_data.hash_types,
+        trace_virtio_net_rss_enable(n->rss_data.runtime_hash_types,
                                     n->rss_data.indirections_len,
                                     sizeof(n->rss_data.key));
     } else {
@@ -1324,7 +1328,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);
     n->rss_data.indirections_len++;
@@ -1387,12 +1391,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;
     }
@@ -1793,7 +1797,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;
@@ -2973,6 +2977,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;
@@ -3009,12 +3021,24 @@ 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);
+        }
+
         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_load_ebpf(n)) {
+            virtio_clear_feature(&features, VIRTIO_NET_F_RSS);
+        }
     }
+
     features = vhost_net_get_features(get_vhost_net(nc->peer), features);
     vdev->backend_features = features;
 
@@ -3279,6 +3303,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;
@@ -3286,14 +3321,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,
@@ -3768,8 +3805,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);
+    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 af0c3c448c1f..4af87ea226b4 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -884,13 +884,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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (3 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 04/11] virtio-net: Retrieve peer hashing capability Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 06/11] virtio-net: Add hash type options Akihiko Odaki
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 4af87ea226b4..5d846db5e71f 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -245,12 +245,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);
@@ -465,7 +459,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,
@@ -1333,7 +1326,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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 06/11] virtio-net: Add hash type options
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (4 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 07/11] net: Allow configuring virtio hashing Akihiko Odaki
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 202016ec74fc..cc6da6ad6a1b 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;
+    OnOffAutoBit 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 3da15a60eaa5..38ccd706f956 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3808,9 +3808,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;
     }
 }
 
@@ -4035,6 +4040,42 @@ static 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_BIT("hash-ipv4", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_IPv4 - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-tcp4", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_TCPv4 - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-udp4", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_UDPv4 - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-ipv6", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_IPv6 - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-tcp6", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_TCPv6 - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-udp6", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_UDPv6 - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-ipv6ex", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_IPv6_EX - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-tcp6ex", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_TCPv6_EX - 1,
+                                ON_OFF_AUTO_AUTO),
+    DEFINE_PROP_ON_OFF_AUTO_BIT("hash-udp6ex", VirtIONet,
+                                rss_data.specified_hash_types,
+                                VIRTIO_NET_HASH_REPORT_UDPv6_EX - 1,
+                                ON_OFF_AUTO_AUTO),
     DEFINE_PROP_END_OF_LIST(),
 };
 

-- 
2.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 07/11] net: Allow configuring virtio hashing
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (5 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 06/11] virtio-net: Add hash type options Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 08/11] virtio-net: Use qemu_set_vnet_hash() Akihiko Odaki
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 099616c8cbe3..0c7e3513cf5f 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;
@@ -195,6 +211,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 3b04f8fe5d6b..db365b6ec211 100644
--- a/net/net.c
+++ b/net/net.c
@@ -568,6 +568,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 1226d5fda2d9..e96d38eec922 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -194,6 +194,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 51f7aec39d9e..8d451c745d70 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 5d846db5e71f..767fd8def468 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -278,6 +278,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);
@@ -457,6 +462,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,
 };
@@ -1324,6 +1330,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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 08/11] virtio-net: Use qemu_set_vnet_hash()
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (6 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 07/11] net: Allow configuring virtio hashing Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 09/11] virtio-net: Offload hashing without vhost Akihiko Odaki
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 38ccd706f956..be6759d1c0f4 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1209,20 +1209,65 @@ static void virtio_net_detach_epbf_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_epbf_rss(n);
-        } else if (!virtio_net_attach_epbf_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_epbf_rss(n);
+            } else if (!virtio_net_attach_epbf_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;
+                }
             }
         }
 
@@ -1230,7 +1275,13 @@ static void virtio_net_commit_rss_config(VirtIONet *n)
                                     n->rss_data.indirections_len,
                                     sizeof(n->rss_data.key));
     } else {
-        virtio_net_detach_epbf_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_epbf_rss(n);
+        }
+
         trace_virtio_net_rss_disable();
     }
 }

-- 
2.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 09/11] virtio-net: Offload hashing without vhost
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (7 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 08/11] virtio-net: Use qemu_set_vnet_hash() Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 10/11] tap: Report virtio-net hashing support on Linux Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS Akihiko Odaki
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 be6759d1c0f4..72493b652bf5 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1695,7 +1695,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);
@@ -3072,11 +3076,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);
+        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);
+            }
         }
 
         return features;

-- 
2.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 10/11] tap: Report virtio-net hashing support on Linux
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (8 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 09/11] virtio-net: Offload hashing without vhost Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  2024-09-15  1:23 ` [PATCH RFC v3 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS Akihiko Odaki
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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 e96d38eec922..a601cb1ed2d9 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -185,6 +185,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 8d451c745d70..e17565c2ac3c 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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH RFC v3 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS
  2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
                   ` (9 preceding siblings ...)
  2024-09-15  1:23 ` [PATCH RFC v3 10/11] tap: Report virtio-net hashing support on Linux Akihiko Odaki
@ 2024-09-15  1:23 ` Akihiko Odaki
  10 siblings, 0 replies; 12+ messages in thread
From: Akihiko Odaki @ 2024-09-15  1:23 UTC (permalink / raw)
  To: qemu-devel, Yuri Benditovich, Andrew Melnychenko,
	Michael S . Tsirkin, Jason Wang
  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>
---
 docs/devel/ebpf_rss.rst | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/docs/devel/ebpf_rss.rst b/docs/devel/ebpf_rss.rst
index 4a68682b31ac..06b09e8a3fed 100644
--- a/docs/devel/ebpf_rss.rst
+++ b/docs/devel/ebpf_rss.rst
@@ -5,9 +5,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'.
@@ -47,9 +60,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
 ----------------
 
@@ -65,7 +75,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.46.0



^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2024-09-15  1:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-15  1:23 [PATCH RFC v3 00/11] virtio-net: Offload hashing without eBPF Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 01/11] qdev-properties: DEFINE_PROP_ON_OFF_AUTO_BIT() Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 02/11] net/vhost-vdpa: Report hashing capability Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 03/11] virtio-net: Move virtio_net_get_features() down Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 04/11] virtio-net: Retrieve peer hashing capability Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 05/11] net/vhost-vdpa: Remove dummy SetSteeringEBPF Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 06/11] virtio-net: Add hash type options Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 07/11] net: Allow configuring virtio hashing Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 08/11] virtio-net: Use qemu_set_vnet_hash() Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 09/11] virtio-net: Offload hashing without vhost Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 10/11] tap: Report virtio-net hashing support on Linux Akihiko Odaki
2024-09-15  1:23 ` [PATCH RFC v3 11/11] docs/devel/ebpf_rss.rst: Update for peer RSS 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).