[RFC PATCH 08/10] qemu_command: Added ebpf RSS helper call for NIC creation.
Michal Prívozník
mprivozn at redhat.com
Fri Aug 20 12:57:09 UTC 2021
On 7/28/21 10:17 AM, Andrew Melnychenko wrote:
> 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)
> + {
I think it's sufficient to check just for ebpfRSSnfds > 0 because it
can't happen that these two variable disagree.
> + 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] = {};
This constant look magic.
> + 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]);
I'm this this ret < 0 check is duplicated. Also usually we write it like
this:
if (ret < 0) {
for ()
;
/* other cleanup code goes here */
}
Michal
More information about the libvir-list
mailing list