If mlock is required either due to use of VFIO hostdevs or due to the
fact that it's enabled it needs to be tweaked prior to adding new memory
or after removing a module. Add a helper to determine when it's
necessary and reuse it both on hotplug and hotunplug.
Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1273491
---
src/qemu/qemu_domain.c | 27 +++++++++++++++++++++++++++
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_hotplug.c | 15 +++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8441d7a..6f82081 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3633,3 +3633,30 @@ qemuDomainGetMlockLimitBytes(virDomainDefPtr def)
return memKB << 10;
}
+
+
+/**
+ * @def: domain definition
+ *
+ * Returns ture if the locked memory limit needs to be set or updated due to
+ * configuration or passthrough devices.
+ * */
+bool
+qemuDomainRequiresMlock(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;
+ }
+
+ return false;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index e34370b..4be998c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -483,5 +483,6 @@ int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
virDomainObjPtr vm);
unsigned long long qemuDomainGetMlockLimitBytes(virDomainDefPtr def);
+bool qemuDomainRequiresMlock(virDomainDefPtr def);
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e7fc036..d4cacc0 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1768,6 +1768,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
virJSONValuePtr props = NULL;
virObjectEventPtr event;
bool fix_balloon = false;
+ bool mlock = false;
int id;
int ret = -1;
@@ -1802,6 +1803,11 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
goto cleanup;
}
+ mlock = qemuDomainRequiresMlock(vm->def);
+
+ if (mlock)
+ virProcessSetMaxMemLock(vm->pid, qemuDomainGetMlockLimitBytes(vm->def));
+
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorAddObject(priv->mon, backendType, objalias, props) < 0)
goto removedef;
@@ -1856,6 +1862,10 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
else
mem = NULL;
+ /* reset the mlock limit */
+ if (mlock)
+ virProcessSetMaxMemLock(vm->pid, qemuDomainGetMlockLimitBytes(vm->def));
+
goto audit;
}
@@ -2947,6 +2957,11 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
virDomainMemoryRemove(vm->def, idx);
virDomainMemoryDefFree(mem);
+
+ /* decrease the mlock limit after memory unplug if necessary */
+ if (qemuDomainRequiresMlock(vm->def))
+ virProcessSetMaxMemLock(vm->pid, qemuDomainGetMlockLimitBytes(vm->def));
+
return 0;
}
--
2.6.2