virtio-net implements software RSS but does not enable it. Enable it
when RSS is requested, but the eBPF implementation is not available.
We also check if vhost is in use in such a case since software RSS is
incompatible with vhost. A warning will be emitted when falling back to
software RSS since it provides no performance benefit.
Can you please elaborate what is wrong from your point of view in the existing implementation?
In general it does (IMO) what you describe.
I'd like to note several things:
- The "vhost=off" is in fact the fallback mode (libvirt default is vhost=on)
- The main goal of software RSS was to provide a reference for RSS implementation for future virtio-net hardware
- Performance benefit of software RSS (as well as implementation in EBPF) is delivery of each packet to proper virtqueue/CPU and avoiding packet rescheduling in the guest
- The best thing (IMO) would be to implement hash delivery with vhost=on, i.e. in EBPF and as soon as this is possible - rely on the hardware/host capabilities and stop calculating the hash in the guest driver (as we do today in Windows)
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
hw/net/virtio-net.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 7bb91617d0..1fa020d905 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1260,10 +1260,12 @@ static bool virtio_net_attach_epbf_rss(VirtIONet *n)
if (!ebpf_rss_set_all(&n->ebpf_rss, &config,
n->rss_data.indirections_table, n->rss_data.key)) {
+ warn_report("Failed to configure eBPF RSS");
return false;
}
if (!virtio_net_attach_ebpf_to_backend(n->nic, n->ebpf_rss.program_fd)) {
+ warn_report("Failed to attach eBPF to backend");
return false;
}
@@ -1278,16 +1280,10 @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
static void virtio_net_commit_rss_config(VirtIONet *n)
{
if (n->rss_data.enabled) {
- n->rss_data.enabled_software_rss = n->rss_data.populate_hash;
+ n->rss_data.enabled_software_rss = n->rss_data.populate_hash ||
+ !virtio_net_attach_epbf_rss(n);
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;
- }
}
trace_virtio_net_rss_enable(n->rss_data.hash_types,
@@ -3747,8 +3743,13 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS) &&
!virtio_net_load_ebpf(n)) {
- error_setg(errp, "Can't load eBPF RSS");
- virtio_net_device_unrealize(dev);
+ if (get_vhost_net(nc->peer)) {
+ error_setg(errp, "Can't load eBPF RSS for vhost");
+ virtio_net_device_unrealize(dev);
+ return;
+ }
+
+ warn_report_once("Can't load eBPF RSS - fallback to software RSS");
}
}
--
2.42.0