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;
+}
virJSONValuePtr props = NULL;
virObjectEventPtr event;
bool fix_balloon = false;
+ bool mlock = false;
int id;
int ret = -1;
goto cleanup;
}
+ mlock = qemuDomainRequiresMlock(vm->def);
+
+ if (mlock &&
+ virProcessSetMaxMemLock(vm->pid,
+ qemuDomainGetMlockLimitBytes(vm->def)) < 0) {
+ mlock = false;
+ virJSONValueFree(props);
+ goto removedef;
+ }
+
qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorAddObject(priv->mon, backendType, objalias, props) < 0)
- goto removedef;
+ goto exit_monitor;
if (qemuMonitorAddDevice(priv->mon, devstr) < 0) {
virErrorPtr err = virSaveLastError();
ignore_value(qemuMonitorDelObject(priv->mon, objalias));
virSetError(err);
virFreeError(err);
- goto removedef;
+ goto exit_monitor;
}
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
virDomainMemoryDefFree(mem);
return ret;
- removedef:
+ exit_monitor:
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
mem = NULL;
goto audit;
}
+ removedef:
if ((id = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
mem = virDomainMemoryRemove(vm->def, id);
else
mem = NULL;
+ /* reset the mlock limit */
+ if (mlock) {
+ virErrorPtr err = virSaveLastError();
+ ignore_value(virProcessSetMaxMemLock(vm->pid,
+ qemuDomainGetMlockLimitBytes(vm->def)));
+ virSetError(err);
+ virFreeError(err);
+ }
+
goto audit;
}
virDomainMemoryRemove(vm->def, idx);
virDomainMemoryDefFree(mem);
+
+ /* decrease the mlock limit after memory unplug if necessary */
+ if (qemuDomainRequiresMlock(vm->def))
+ ignore_value(virProcessSetMaxMemLock(vm->pid,
+ qemuDomainGetMlockLimitBytes(vm->def)));
+
return 0;
}