提交 ec90b34a 编写于 作者: P Peter Krempa

qemu: hotplug: Fix mlock limit handling on memory hotplug

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
上级 fbc58cfc
...@@ -3643,3 +3643,30 @@ qemuDomainGetMlockLimitBytes(virDomainDefPtr def) ...@@ -3643,3 +3643,30 @@ qemuDomainGetMlockLimitBytes(virDomainDefPtr def)
return memKB << 10; 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;
}
...@@ -483,5 +483,6 @@ int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, ...@@ -483,5 +483,6 @@ int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
virDomainObjPtr vm); virDomainObjPtr vm);
unsigned long long qemuDomainGetMlockLimitBytes(virDomainDefPtr def); unsigned long long qemuDomainGetMlockLimitBytes(virDomainDefPtr def);
bool qemuDomainRequiresMlock(virDomainDefPtr def);
#endif /* __QEMU_DOMAIN_H__ */ #endif /* __QEMU_DOMAIN_H__ */
...@@ -1768,6 +1768,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, ...@@ -1768,6 +1768,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
virJSONValuePtr props = NULL; virJSONValuePtr props = NULL;
virObjectEventPtr event; virObjectEventPtr event;
bool fix_balloon = false; bool fix_balloon = false;
bool mlock = false;
int id; int id;
int ret = -1; int ret = -1;
...@@ -1802,16 +1803,26 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, ...@@ -1802,16 +1803,26 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
mlock = qemuDomainRequiresMlock(vm->def);
if (mlock &&
virProcessSetMaxMemLock(vm->pid,
qemuDomainGetMlockLimitBytes(vm->def)) < 0) {
mlock = false;
virJSONValueFree(props);
goto removedef;
}
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
if (qemuMonitorAddObject(priv->mon, backendType, objalias, props) < 0) if (qemuMonitorAddObject(priv->mon, backendType, objalias, props) < 0)
goto removedef; goto exit_monitor;
if (qemuMonitorAddDevice(priv->mon, devstr) < 0) { if (qemuMonitorAddDevice(priv->mon, devstr) < 0) {
virErrorPtr err = virSaveLastError(); virErrorPtr err = virSaveLastError();
ignore_value(qemuMonitorDelObject(priv->mon, objalias)); ignore_value(qemuMonitorDelObject(priv->mon, objalias));
virSetError(err); virSetError(err);
virFreeError(err); virFreeError(err);
goto removedef; goto exit_monitor;
} }
if (qemuDomainObjExitMonitor(driver, vm) < 0) { if (qemuDomainObjExitMonitor(driver, vm) < 0) {
...@@ -1845,17 +1856,27 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, ...@@ -1845,17 +1856,27 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
virDomainMemoryDefFree(mem); virDomainMemoryDefFree(mem);
return ret; return ret;
removedef: exit_monitor:
if (qemuDomainObjExitMonitor(driver, vm) < 0) { if (qemuDomainObjExitMonitor(driver, vm) < 0) {
mem = NULL; mem = NULL;
goto audit; goto audit;
} }
removedef:
if ((id = virDomainMemoryFindByDef(vm->def, mem)) >= 0) if ((id = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
mem = virDomainMemoryRemove(vm->def, id); mem = virDomainMemoryRemove(vm->def, id);
else else
mem = NULL; 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; goto audit;
} }
...@@ -2947,6 +2968,12 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver, ...@@ -2947,6 +2968,12 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
virDomainMemoryRemove(vm->def, idx); virDomainMemoryRemove(vm->def, idx);
virDomainMemoryDefFree(mem); 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; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册