c401cc
From 55b75332573754c82426a1baff5f66221557939b Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <55b75332573754c82426a1baff5f66221557939b.1389183248.git.jdenemar@redhat.com>
c401cc
From: Laine Stump <laine@laine.org>
c401cc
Date: Tue, 24 Dec 2013 04:24:02 -0700
c401cc
Subject: [PATCH] qemu: properly set MaxMemLock when hotplugging with VFIO
c401cc
c401cc
This resolves:
c401cc
c401cc
  https://bugzilla.redhat.com/show_bug.cgi?id=1035490
c401cc
c401cc
virProcessSetMaxMemLock() (which is a wrapper over prlimit(3)) expects
c401cc
the memory size in bytes, but libvirt's domain definition (which was
c401cc
being used by qemuDomainAttachHostPciDevice()) stores all memory
c401cc
tuning parameters in KiB. This was being accounted for when setting
c401cc
MaxMemLock at domain startup time (so cold-plugged devices would
c401cc
work), but not for hotplug.
c401cc
c401cc
This patch simplifies the few lines that call
c401cc
virProcessSetMemMaxLock(), and multiply the amount * 1024 so that
c401cc
we're locking the correct amount of memory.
c401cc
c401cc
Note that even without this patch, hot-plug of a managed='no' device
c401cc
would appear to succeed (at least on my system) while managed='yes'
c401cc
would fail. I guess in one case the memory was coincidentally already
c401cc
resident and in the other it wasn't. However, this apparently
c401cc
successful hotplug would result in a device that was not fully usable
c401cc
by the guest.
c401cc
c401cc
(cherry picked from commit 6d867f72f4f5fd75905e81b2d43350e7091fca64)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_hotplug.c | 19 +++++++++++--------
c401cc
 1 file changed, 11 insertions(+), 8 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
c401cc
index 24a2096..fae7e14 100644
c401cc
--- a/src/qemu/qemu_hotplug.c
c401cc
+++ b/src/qemu/qemu_hotplug.c
c401cc
@@ -1015,6 +1015,7 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
c401cc
     bool teardowncgroup = false;
c401cc
     bool teardownlabel = false;
c401cc
     int backend = hostdev->source.subsys.u.pci.backend;
c401cc
+    unsigned long long memKB;
c401cc
 
c401cc
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
c401cc
         return -1;
c401cc
@@ -1032,16 +1033,18 @@ int qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
c401cc
             goto error;
c401cc
         }
c401cc
 
c401cc
-        /* VFIO requires all of the guest's memory to be locked resident.
c401cc
-         * In this case, the guest's memory may already be locked, but it
c401cc
+        /* VFIO requires all of the guest's memory to be locked
c401cc
+         * resident (plus an additional 1GiB to cover IO space). During
c401cc
+         * hotplug, the guest's memory may already be locked, but it
c401cc
          * doesn't hurt to "change" the limit to the same value.
c401cc
+         * NB: the domain's memory tuning parameters are stored as
c401cc
+         * Kibibytes, but virProcessSetMaxMemLock expects the value in
c401cc
+         * bytes.
c401cc
          */
c401cc
-        if (vm->def->mem.hard_limit)
c401cc
-            virProcessSetMaxMemLock(vm->pid, vm->def->mem.hard_limit);
c401cc
-        else
c401cc
-            virProcessSetMaxMemLock(vm->pid,
c401cc
-                                    vm->def->mem.max_balloon + (1024 * 1024));
c401cc
-
c401cc
+        memKB = vm->def->mem.hard_limit
c401cc
+            ? vm->def->mem.hard_limit
c401cc
+            : vm->def->mem.max_balloon + (1024 * 1024);
c401cc
+        virProcessSetMaxMemLock(vm->pid, memKB * 1024);
c401cc
         break;
c401cc
 
c401cc
     case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
c401cc
-- 
c401cc
1.8.5.2
c401cc