1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu: Remove qemuDomainRequiresMemLock()

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.
This commit is contained in:
Andrea Bolognani 2017-03-21 19:52:50 +01:00
parent 4b67e7a377
commit 1f7661af8c
3 changed files with 25 additions and 43 deletions

View File

@ -9789,7 +9789,6 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
unsigned int bootHostdevNet = 0; unsigned int bootHostdevNet = 0;
VIR_DEBUG("driver=%p def=%p mon=%p json=%d " VIR_DEBUG("driver=%p def=%p mon=%p json=%d "
"qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d", "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d",
driver, def, monitor_chr, monitor_json, driver, def, monitor_chr, monitor_json,
@ -10015,8 +10014,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
/* In some situations, eg. VFIO passthrough, QEMU might need to lock a /* In some situations, eg. VFIO passthrough, QEMU might need to lock a
* significant amount of memory, so we need to set the limit accordingly */ * 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) && if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
cfg->logTimestamp) cfg->logTimestamp)

View File

@ -6202,18 +6202,20 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
/** /**
* qemuDomainGetMemLockLimitBytes: * qemuDomainGetMemLockLimitBytes:
*
* @def: domain definition * @def: domain definition
* *
* Returns the size of the memory in bytes that needs to be set as * Calculate the memory locking limit that needs to be set in order for
* RLIMIT_MEMLOCK for the QEMU process. * the guest to operate properly. The limit depends on a number of factors,
* If a mem.hard_limit is set, then that value is preferred; otherwise, the * including certain configuration options and less immediately apparent ones
* value returned may depend upon the architecture or devices present. * 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 unsigned long long
qemuDomainGetMemLockLimitBytes(virDomainDefPtr def) qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
{ {
unsigned long long memKB; unsigned long long memKB = 0;
size_t i;
/* prefer the hard limit */ /* prefer the hard limit */
if (virMemoryLimitIsSet(def->mem.hard_limit)) { if (virMemoryLimitIsSet(def->mem.hard_limit)) {
@ -6221,13 +6223,17 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
goto done; 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 maxMemory;
unsigned long long memory; unsigned long long memory;
unsigned long long baseLimit; unsigned long long baseLimit;
unsigned long long passthroughLimit; unsigned long long passthroughLimit;
size_t nPCIHostBridges; size_t nPCIHostBridges;
size_t i;
bool usesVFIO = false; bool usesVFIO = false;
/* TODO: Detect at runtime once we start using more than just /* TODO: Detect at runtime once we start using more than just
@ -6317,45 +6323,23 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
* *
* Note that this may not be valid for all platforms. * 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++) { for (i = 0; i < def->nhostdevs; i++) {
virDomainHostdevSubsysPtr subsys = &def->hostdevs[i]->source.subsys; virDomainHostdevSubsysPtr subsys = &def->hostdevs[i]->source.subsys;
if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
(subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV || (subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV ||
(subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && (subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
subsys->u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO))) subsys->u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO))) {
return true; memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
goto done;
}
} }
/* ppc64 KVM domains need to lock some memory even when VFIO is not used */ done:
if (ARCH_IS_PPC64(def->os.arch) && def->virtType == VIR_DOMAIN_VIRT_KVM) return memKB << 10;
return true;
return false;
} }
/** /**
* qemuDomainAdjustMaxMemLock: * qemuDomainAdjustMaxMemLock:
* @vm: domain * @vm: domain
@ -6376,7 +6360,9 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
unsigned long long bytes = 0; unsigned long long bytes = 0;
int ret = -1; 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 /* 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 * value so that we can restore it once memory locking is no longer
* required. Failing to obtain the current limit is not a critical * required. Failing to obtain the current limit is not a critical
@ -6385,7 +6371,6 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
if (virProcessGetMaxMemLock(vm->pid, &(vm->original_memlock)) < 0) if (virProcessGetMaxMemLock(vm->pid, &(vm->original_memlock)) < 0)
vm->original_memlock = 0; vm->original_memlock = 0;
} }
bytes = qemuDomainGetMemLockLimitBytes(vm->def);
} else { } else {
/* Once memory locking is no longer required, we can restore the /* Once memory locking is no longer required, we can restore the
* original, usually very low, limit */ * original, usually very low, limit */

View File

@ -691,7 +691,6 @@ int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
virDomainObjPtr vm); virDomainObjPtr vm);
unsigned long long qemuDomainGetMemLockLimitBytes(virDomainDefPtr def); unsigned long long qemuDomainGetMemLockLimitBytes(virDomainDefPtr def);
bool qemuDomainRequiresMemLock(virDomainDefPtr def);
int qemuDomainAdjustMaxMemLock(virDomainObjPtr vm); int qemuDomainAdjustMaxMemLock(virDomainObjPtr vm);
int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,