[RFC PATCH 08/10] qemu_command: Added ebpf RSS helper call for NIC creation.

Andrew Melnychenko andrew at daynix.com
Wed Jul 28 08:17:12 UTC 2021


The helper called before NIC string creation. EBPF fds passed to the child process.
The helper called if qemu supports "ebpf_rss_fds" and returns the helper path.
If libvirt can't retrieve fds from the helper, qemu will be launched
without "ebpf_rss_fds" virtio-net property.

Signed-off-by: Andrew Melnychenko <andrew at daynix.com>
---
 src/qemu/qemu_command.c | 36 +++++++++++++++++++++++++++++++++++-
 src/qemu/qemu_command.h |  2 ++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 67a396a513..2fffcee609 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3377,11 +3377,14 @@ qemuBuildNicDevStr(virDomainDef *def,
                    virDomainNetDef *net,
                    unsigned int bootindex,
                    size_t vhostfdSize,
+                   char **ebpfRSSfds,
+                   size_t ebpfRSSnfds,
                    virQEMUCaps *qemuCaps)
 {
     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
     bool usingVirtio = false;
     char macaddr[VIR_MAC_STRING_BUFLEN];
+    size_t i = 0;
 
     if (virDomainNetIsVirtioModel(net)) {
         if (qemuBuildVirtioDevStr(&buf, "virtio-net", qemuCaps,
@@ -3498,6 +3501,15 @@ qemuBuildNicDevStr(virDomainDef *def,
         if (net->driver.virtio.rss == VIR_TRISTATE_SWITCH_ON) {
             virBufferAsprintf(&buf, ",rss=%s",
                     virTristateSwitchTypeToString(net->driver.virtio.rss));
+
+            if (ebpfRSSfds != NULL && ebpfRSSnfds)
+            {
+                virBufferAsprintf(&buf, ",ebpf_rss_fds=");
+                for (i = 0; i < (ebpfRSSnfds - 1); ++i) {
+                     virBufferAsprintf(&buf, "%s:",ebpfRSSfds[i]);
+                }
+                virBufferAsprintf(&buf, "%s",ebpfRSSfds[ebpfRSSnfds - 1]);
+            }
         }
 
         if (net->driver.virtio.rss_hash_report == VIR_TRISTATE_SWITCH_ON) {
@@ -8492,6 +8504,9 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
     qemuSlirp *slirp;
     size_t i;
     g_autoptr(virJSONValue) hostnetprops = NULL;
+    char **ebpfRSSfdsName = NULL;
+    int ebpfRSSfds[16] = {};
+    int ebpfRSSnfds = 0;
 
 
     if (!bootindex)
@@ -8744,8 +8759,20 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
         if (qemuCommandAddExtDevice(cmd, &net->info) < 0)
             goto cleanup;
 
+        if (net->driver.virtio.rss == VIR_TRISTATE_SWITCH_ON
+                && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_EBPF_RSS_FDS)) {
+            ebpfRSSnfds = qemuEbpfRssHelper(virQEMUCapsGetEBPFHelperPath(qemuCaps), ebpfRSSfds, 16);
+            if (ebpfRSSnfds > 0) {
+                ebpfRSSfdsName = g_new0(char *, ebpfRSSnfds);
+                for (i = 0; i < ebpfRSSnfds; ++i) {
+                    ebpfRSSfdsName[i] = g_strdup_printf("%d", ebpfRSSfds[i]);
+                    virCommandPassFD(cmd, ebpfRSSfds[i], VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+                }
+            }
+        }
+
         if (!(nic = qemuBuildNicDevStr(def, net, bootindex,
-                                       net->driver.virtio.queues, qemuCaps)))
+                                       net->driver.virtio.queues, ebpfRSSfdsName, ebpfRSSnfds, qemuCaps)))
             goto cleanup;
         virCommandAddArgList(cmd, "-device", nic, NULL);
     } else if (!requireNicdev) {
@@ -8785,6 +8812,13 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
     }
     VIR_FREE(tapfdName);
     VIR_FREE(vhostfd);
+    for (i = 0; ret < 0 && ebpfRSSfds[i] && i < 16; i++) {
+        if (ret < 0)
+            VIR_FORCE_CLOSE(ebpfRSSfds[i]);
+        if (ebpfRSSfdsName)
+            VIR_FREE(ebpfRSSfdsName[i]);
+    }
+    VIR_FREE(ebpfRSSfdsName);
     VIR_FREE(tapfd);
     VIR_FORCE_CLOSE(vdpafd);
     return ret;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 188e63ea1f..cab0bb7770 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -107,6 +107,8 @@ char *qemuBuildNicDevStr(virDomainDef *def,
                          virDomainNetDef *net,
                          unsigned int bootindex,
                          size_t vhostfdSize,
+                         char **ebpf_rss_fds,
+                         size_t nfds,
                          virQEMUCaps *qemuCaps);
 
 char *qemuDeviceDriveHostAlias(virDomainDiskDef *disk);
-- 
2.31.1




More information about the libvir-list mailing list