The helper called before NIC string creation. eBPF fds passed to the child process through
qmp.
Qemu should support "ebpf_rss_fds" and return path to the helper.
Also added check for device "update".
Signed-off-by: Andrew Melnychenko <andrew(a)daynix.com>
---
src/qemu/qemu_hotplug.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6743a8a742..6dd8e7dad4 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1205,6 +1205,9 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
g_autofree char *netdev_name = NULL;
g_autoptr(virConnect) conn = NULL;
virErrorPtr save_err = NULL;
+ char **ebpfRSSfdsName = NULL;
+ int ebpfRSSfds[16] = {};
+ int ebpfRSSnfds = 0;
/* If appropriate, grab a physical device from the configured
* network's pool of devices, or resolve bridge device name
@@ -1495,8 +1498,23 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
for (i = 0; i < vhostfdSize; i++)
VIR_FORCE_CLOSE(vhostfd[i]);
+ if (net->driver.virtio.rss == VIR_TRISTATE_SWITCH_ON
+ && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_EBPF_RSS_FDS))
{
+ ebpfRSSnfds = qemuEbpfRssHelper(virQEMUCapsGetEBPFHelperPath(priv->qemuCaps),
ebpfRSSfds, 16);
+ if (ebpfRSSnfds > 0) {
+ ebpfRSSfdsName = g_new0(char *, ebpfRSSnfds);
+ for (i = 0; i < ebpfRSSnfds; ++i) {
+ ebpfRSSfdsName[i] = g_strdup_printf("ebpfrssfd-%s%zu",
net->info.alias, i);
+ if (qemuMonitorSendFileHandle(priv->mon, NULL, ebpfRSSfds[i])) {
+ ebpfRSSnfds = 0;
+ break;
+ }
+ }
+ }
+ }
+
if (!(nicstr = qemuBuildNicDevStr(vm->def, net, 0,
- queueSize, priv->qemuCaps)))
+ queueSize, ebpfRSSfdsName, ebpfRSSnfds,
priv->qemuCaps)))
goto try_remove;
qemuDomainObjEnterMonitor(driver, vm);
@@ -1599,6 +1617,12 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
}
VIR_FREE(vhostfd);
VIR_FREE(vhostfdName);
+ for (i = 0; ret < 0 && ebpfRSSfds[i] && i < 16; i++) {
+ VIR_FORCE_CLOSE(ebpfRSSfds[i]);
+ if (ebpfRSSfdsName)
+ VIR_FREE(ebpfRSSfdsName[i]);
+ }
+ VIR_FREE(ebpfRSSfdsName);
virDomainCCWAddressSetFree(ccwaddrs);
VIR_FORCE_CLOSE(slirpfd);
VIR_FORCE_CLOSE(vdpafd);
@@ -3624,7 +3648,9 @@ qemuDomainChangeNet(virQEMUDriver *driver,
olddev->driver.virtio.guest.tso4 != newdev->driver.virtio.guest.tso4 ||
olddev->driver.virtio.guest.tso6 != newdev->driver.virtio.guest.tso6 ||
olddev->driver.virtio.guest.ecn != newdev->driver.virtio.guest.ecn ||
- olddev->driver.virtio.guest.ufo != newdev->driver.virtio.guest.ufo)) {
+ olddev->driver.virtio.guest.ufo != newdev->driver.virtio.guest.ufo ||
+ olddev->driver.virtio.rss != newdev->driver.virtio.rss ||
+ olddev->driver.virtio.rss_hash_report !=
newdev->driver.virtio.rss_hash_report)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot modify virtio network device driver
attributes"));
goto cleanup;
--
2.31.1