Added logic for loading the "RSS" eBPF program. eBPF file descriptors passed to the QEMU. Signed-off-by: Andrew Melnychenko <andrew@xxxxxxxxxx> --- src/qemu/qemu_command.c | 53 +++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.c | 4 ++++ src/qemu/qemu_domain.h | 3 +++ 3 files changed, 60 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8a7b80719f..ca6cb1bc7a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3786,6 +3786,23 @@ qemuBuildLegacyNicStr(virDomainNetDef *net) NULLSTR_EMPTY(net->info.alias)); } +static char *qemuBuildEbpfRssArg(virDomainNetDef *net) { + qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net); + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + size_t nfds; + GSList *n; + + if (netpriv->ebpfrssfds) { + nfds = 0; + for (n = netpriv->ebpfrssfds; n; n = n->next) { + virBufferAsprintf(&buf, "%s:", qemuFDPassDirectGetPath(n->data)); + nfds++; + } + } + virBufferTrim(&buf, ":"); + + return virBufferContentAndReset(&buf); +} virJSONValue * qemuBuildNicDevProps(virDomainDef *def, @@ -3871,6 +3888,11 @@ qemuBuildNicDevProps(virDomainDef *def, "T:failover", failover, NULL) < 0) return NULL; + if (net->driver.virtio.rss == VIR_TRISTATE_SWITCH_ON && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EBPF_RSS_FDS)){ + g_autofree char *ebpf = qemuBuildEbpfRssArg(net); + if (virJSONValueObjectAdd(&props, "S:ebpf_rss_fds", ebpf, NULL) < 0) + return NULL; + } } else { if (virJSONValueObjectAdd(&props, "s:driver", virDomainNetGetModelString(net), @@ -4152,6 +4174,33 @@ qemuBuildWatchdogDevProps(const virDomainDef *def, } +static void qemuOpenEbpfRssFds(virDomainNetDef *net, + virQEMUCaps *qemuCaps) { + const void *ebpfRSSObject = NULL; + size_t ebpfRSSObjectSize = 0; + int fds[16]; + int nfds = 0; + qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net); + + netpriv->libbpfRSSObject = NULL; + netpriv->ebpfrssfds = NULL; + + /* Add ebpf values */ + if (net->driver.virtio.rss == VIR_TRISTATE_SWITCH_ON && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EBPF_RSS_FDS)) { + ebpfRSSObject = virQEMUCapsGetEbpf(qemuCaps, "rss", &ebpfRSSObjectSize); + nfds = qemuInterfaceLoadEbpf(ebpfRSSObject, ebpfRSSObjectSize, &netpriv->libbpfRSSObject, fds, 16); + + if (nfds > 0) { + for (int i = 0; i < nfds; ++i) { + g_autofree char *name = g_strdup_printf("ebpfrssfd-%s-%u", net->info.alias, i); + netpriv->ebpfrssfds = g_slist_prepend(netpriv->ebpfrssfds, qemuFDPassDirectNew(name, fds + i)); + } + netpriv->ebpfrssfds = g_slist_reverse(netpriv->ebpfrssfds); + } + } +} + + static int qemuBuildWatchdogCommandLine(virCommand *cmd, const virDomainDef *def, @@ -8735,6 +8784,10 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, qemuFDPassDirectTransferCommand(netpriv->slirpfd, cmd); qemuFDPassTransferCommand(netpriv->vdpafd, cmd); + qemuOpenEbpfRssFds(net, qemuCaps); + for (n = netpriv->ebpfrssfds; n; n = n->next) + qemuFDPassDirectTransferCommand(n->data, cmd); + if (!(hostnetprops = qemuBuildHostNetProps(vm, net))) goto cleanup; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index eec7bed28b..c696482f29 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -38,6 +38,7 @@ #include "qemu_checkpoint.h" #include "qemu_validate.h" #include "qemu_namespace.h" +#include "qemu_interface.h" #include "viralloc.h" #include "virlog.h" #include "virerror.h" @@ -1078,6 +1079,7 @@ qemuDomainNetworkPrivateClearFDs(qemuDomainNetworkPrivate *priv) g_clear_pointer(&priv->vdpafd, qemuFDPassFree); g_slist_free_full(g_steal_pointer(&priv->vhostfds), (GDestroyNotify) qemuFDPassDirectFree); g_slist_free_full(g_steal_pointer(&priv->tapfds), (GDestroyNotify) qemuFDPassDirectFree); + g_slist_free_full(g_steal_pointer(&priv->ebpfrssfds), (GDestroyNotify) qemuFDPassDirectFree); } @@ -1089,6 +1091,8 @@ qemuDomainNetworkPrivateDispose(void *obj G_GNUC_UNUSED) qemuSlirpFree(priv->slirp); qemuDomainNetworkPrivateClearFDs(priv); + + qemuInterfaceCloseEbpf(priv->libbpfRSSObject); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index a3fc6acaaa..5e155b77cc 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -431,6 +431,9 @@ struct _qemuDomainNetworkPrivate { GSList *tapfds; /* qemuFDPassDirect */ GSList *vhostfds; /* qemuFDPassDirect */ qemuFDPass *vdpafd; + + void *libbpfRSSObject; + GSList *ebpfrssfds; /* qemuFDPassDirect eBPF RSS fds from helper */ }; -- 2.42.0