This resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1035490
virProcessSetMaxMemLock() (which is a wrapper over prlimit(3)) expects
the memory size in bytes, but libvirt's domain definition (which was
being used by qemuDomainAttachHostPciDevice()) stores all memory
tuning parameters in KiB. This was being accounted for when setting
MaxMemLock at domain startup time (so cold-plugged devices would
work), but not for hotplug.
This patch simplifies the few lines that call
virProcessSetMemMaxLock(), and multiply the amount * 1024 so that
we're locking the correct amount of memory.
What remains a mystery to me is why hot-plug of a managed='no' device
would succeed (at least on my system) while managed='yes' would
fail. I guess in one case the memory was coincidentally already
resident and in the other it wasn't.
---
src/qemu/qemu_hotplug.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a375b6c..4a2c5ce 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1155,6 +1155,7 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
bool teardowncgroup = false;
bool teardownlabel = false;
int backend = hostdev->source.subsys.u.pci.backend;
+ unsigned long long memKB;
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
return -1;
@@ -1172,16 +1173,18 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
goto error;
}
- /* VFIO requires all of the guest's memory to be locked resident.
- * In this case, the guest's memory may already be locked, but it
+ /* VFIO requires all of the guest's memory to be locked
+ * resident (plus an additional 1GiB to cover IO space). During
+ * hotplug, the guest's memory may already be locked, but it
* doesn't hurt to "change" the limit to the same value.
+ * NB: the domain's memory tuning parameters are stored as
+ * Kibibytes, but virProcessSetMaxMemLock expects the value in
+ * bytes.
*/
- if (vm->def->mem.hard_limit)
- virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit);
- else
- virProcessSetMaxMemLock(vm->pid,
- vm->def->mem.max_balloon + (1024 * 1024));
-
+ memKB = vm->def->mem.hard_limit
+ ? vm->def->mem.hard_limit
+ : vm->def->mem.max_balloon + (1024 * 1024);
+ virProcessSetMaxMemLock(vm->pid, memKB * 1024);
break;
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
--
1.8.3.1