[libvirt] [PATCH 2/8] qemu: Remove qemuDomainRequiresMemLock()
Martin Kletzander
mkletzan at redhat.com
Mon Mar 27 12:19:14 UTC 2017
On Thu, Mar 23, 2017 at 07:16:41PM +0100, Andrea Bolognani wrote:
>Instead of having a separate function, we can simply return
>zero from the existing qemuDomainGetMemLockLimitBytes() to
>signal the caller that the memory locking limit doesn't need
>to be set for the guest.
>
>Having a single function instead of two makes it less likely
>that we will use the wrong value, which is exactly what
>happened when we started applying the limit that was meant
>for VFIO-using guests to <memoryBacking><locked>-using
>guests.
>---
> src/qemu/qemu_command.c | 4 +---
> src/qemu/qemu_domain.c | 62 ++++++++++++++++++-------------------------------
> src/qemu/qemu_domain.h | 1 -
> 3 files changed, 24 insertions(+), 43 deletions(-)
>
>diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
>index 2045c2e..52f6e00 100644
>--- a/src/qemu/qemu_command.c
>+++ b/src/qemu/qemu_command.c
>@@ -9740,7 +9740,6 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> unsigned int bootHostdevNet = 0;
>
>-
> VIR_DEBUG("driver=%p def=%p mon=%p json=%d "
> "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d",
> driver, def, monitor_chr, monitor_json,
>@@ -9966,8 +9965,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
>
> /* In some situations, eg. VFIO passthrough, QEMU might need to lock a
> * significant amount of memory, so we need to set the limit accordingly */
>- if (qemuDomainRequiresMemLock(def))
>- virCommandSetMaxMemLock(cmd, qemuDomainGetMemLockLimitBytes(def));
>+ virCommandSetMaxMemLock(cmd, qemuDomainGetMemLockLimitBytes(def));
>
> if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
> cfg->logTimestamp)
>diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
>index 8fa43f2..2e2ba4f 100644
>--- a/src/qemu/qemu_domain.c
>+++ b/src/qemu/qemu_domain.c
>@@ -6199,18 +6199,20 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
>
> /**
> * qemuDomainGetMemLockLimitBytes:
>- *
> * @def: domain definition
> *
>- * Returns the size of the memory in bytes that needs to be set as
>- * RLIMIT_MEMLOCK for the QEMU process.
>- * If a mem.hard_limit is set, then that value is preferred; otherwise, the
>- * value returned may depend upon the architecture or devices present.
>+ * Calculate the memory locking limit that needs to be set in order for
>+ * the guest to operate properly. The limit depends on a number of factors,
>+ * including certain configuration options and less immediately apparent ones
>+ * such as the guest architecture or the use of certain devices.
>+ *
>+ * Returns: the memory locking limit, or 0 if setting the limit is not needed
> */
> unsigned long long
> qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
> {
>- unsigned long long memKB;
>+ unsigned long long memKB = 0;
>+ size_t i;
>
> /* prefer the hard limit */
> if (virMemoryLimitIsSet(def->mem.hard_limit)) {
>@@ -6218,13 +6220,17 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
> goto done;
> }
>
>- if (ARCH_IS_PPC64(def->os.arch)) {
>+ if (def->mem.locked) {
>+ memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
>+ goto done;
>+ }
>+
>+ if (ARCH_IS_PPC64(def->os.arch) && def->virtType == VIR_DOMAIN_VIRT_KVM) {
> unsigned long long maxMemory;
> unsigned long long memory;
> unsigned long long baseLimit;
> unsigned long long passthroughLimit;
> size_t nPCIHostBridges;
>- size_t i;
> bool usesVFIO = false;
>
> /* TODO: Detect at runtime once we start using more than just
>@@ -6314,44 +6320,21 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
> *
> * Note that this may not be valid for all platforms.
> */
>- memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
>-
>- done:
>- return memKB << 10;
>-}
>-
>-
>-/**
>- * @def: domain definition
>- *
>- * Returns true if the locked memory limit needs to be set or updated because
>- * of domain configuration, VFIO passthrough devices or architecture-specific
>- * requirements.
>- * */
>-bool
>-qemuDomainRequiresMemLock(virDomainDefPtr def)
>-{
>- size_t i;
>-
>- if (def->mem.locked)
>- return true;
>-
> for (i = 0; i < def->nhostdevs; i++) {
> virDomainHostdevDefPtr dev = def->hostdevs[i];
>
> if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
> dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
>- dev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
>- return true;
>+ dev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
>+ memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
Shouldn't this be raising memKB for _each_ host device?
>+ }
> }
>
>- /* ppc64 KVM domains need to lock some memory even when VFIO is not used */
>- if (ARCH_IS_PPC64(def->os.arch) && def->virtType == VIR_DOMAIN_VIRT_KVM)
>- return true;
>-
>- return false;
>+ done:
>+ return memKB << 10;
> }
>
>+
> /**
> * qemuDomainAdjustMaxMemLock:
> * @vm: domain
>@@ -6372,7 +6355,9 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
> unsigned long long bytes = 0;
> int ret = -1;
>
>- if (qemuDomainRequiresMemLock(vm->def)) {
>+ bytes = qemuDomainGetMemLockLimitBytes(vm->def);
>+
>+ if (bytes) {
> /* If this is the first time adjusting the limit, save the current
> * value so that we can restore it once memory locking is no longer
> * required. Failing to obtain the current limit is not a critical
>@@ -6381,7 +6366,6 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
> if (virProcessGetMaxMemLock(vm->pid, &(vm->original_memlock)) < 0)
> vm->original_memlock = 0;
> }
>- bytes = qemuDomainGetMemLockLimitBytes(vm->def);
> } else {
> /* Once memory locking is no longer required, we can restore the
> * original, usually very low, limit */
This function has weird behaviour, even when it's documented. But it
makes sense, it just takes a while.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170327/16f56a25/attachment-0001.sig>
More information about the libvir-list
mailing list