diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9519861e92..eec860382c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8267,6 +8267,8 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver, } } + qemuDomainInterfaceSetDefaultQDisc(driver, net); + if (net->mtu && virNetDevSetMTU(net->ifname, net->mtu) < 0) goto cleanup; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 2d7f61f5e9..5e603284be 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11049,3 +11049,39 @@ qemuDomainFileWrapperFDClose(virDomainObjPtr vm, } return ret; } + + +/** + * qemuDomainInterfaceSetDefaultQDisc: + * @driver: QEMU driver + * @net: domain interface + * + * Set the noqueue qdisc on @net if running as privileged. The + * noqueue qdisc is a lockless transmit and thus faster than the + * default pfifo_fast (at least in theory). But we can modify + * root qdisc only if we have CAP_NET_ADMIN. + * + * Returns: 0 on success, + * -1 otherwise. + */ +int +qemuDomainInterfaceSetDefaultQDisc(virQEMUDriverPtr driver, + virDomainNetDefPtr net) +{ + virDomainNetType actualType = virDomainNetGetActualType(net); + + if (!driver->privileged || !net->ifname) + return 0; + + /* We want only those types which are represented as TAP + * devices in the host. */ + if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET || + actualType == VIR_DOMAIN_NET_TYPE_NETWORK || + actualType == VIR_DOMAIN_NET_TYPE_BRIDGE || + actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { + if (virNetDevSetRootQDisc(net->ifname, "noqueue") < 0) + return -1; + } + + return 0; +} diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 9bf32e16c9..91b3b67cb6 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -1046,3 +1046,7 @@ qemuDomainOpenFile(virQEMUDriverPtr driver, int qemuDomainFileWrapperFDClose(virDomainObjPtr vm, virFileWrapperFdPtr fd); + +int +qemuDomainInterfaceSetDefaultQDisc(virQEMUDriverPtr driver, + virDomainNetDefPtr net); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 7a54fcb221..2c184b9ba0 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1368,6 +1368,8 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, virNetDevSetMTU(net->ifname, net->mtu) < 0) goto cleanup; + qemuDomainInterfaceSetDefaultQDisc(driver, net); + for (i = 0; i < tapfdSize; i++) { if (qemuSecuritySetTapFDLabel(driver->securityManager, vm->def, tapfd[i]) < 0) diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 82943b8e08..dfef49938f 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -313,6 +313,7 @@ int virNetDevRunEthernetScript(const char *ifname, const char *script) G_GNUC_NO_INLINE; int virNetDevSetRootQDisc(const char *ifname, - const char *qdisc); + const char *qdisc) + G_GNUC_NO_INLINE; G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevRxFilter, virNetDevRxFilterFree); diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c index 9bf4357b66..b9322f4f2a 100644 --- a/tests/qemuxml2argvmock.c +++ b/tests/qemuxml2argvmock.c @@ -286,3 +286,11 @@ qemuBuildTPMOpenBackendFDs(const char *tpmdev G_GNUC_UNUSED, *cancelfd = 1731; return 0; } + + +int +virNetDevSetRootQDisc(const char *ifname G_GNUC_UNUSED, + const char *qdisc G_GNUC_UNUSED) +{ + return 0; +}