Skip to contentSkip to conversation

: Xend: Balloon an additional 8MB for QEMU device model

PATCH In review Chris Lalancette 1 participant 2 messages Aug 24, 2007 – Aug 27, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 : Xend: Balloon an additional 8MB for QEMU device model

All,
Attached is a patch to make Xend balloon down an additional 8MB (for the
Cirrus logic video device) when doing a restore or migrate. Without this, you can run into the following situation:

1)  Start an HVM guest up on machine1
2)  Boot up machine2, making sure dom0 has *all* of available memory
3)  Migrate (off-line or live) from machine1 to machine2
4)  Have the video device setup fail, with the following in the qemu-dm log file:

Failed allocation for dom 3: 2048 extents of order 0

The problem ends up being that if dom0 has all of memory, the restore on the target side only balloons down exactly enough for the memory of the migrating domain; it doesn't take into account the additional memory needed for the device model. So the "populate_physmap" that happens as part of video device setup fails with out-of-memory, causing the failure above.

Note that it could be argued that this additional ballooning should be done from QEMU, since it knows better than anyone how much memory it is going to need. However, all of the logic for ballooning is currently contained in xend, so it seems like a more appropriate place to put it.

The patch is against 3.1.0, but should apply fairly easily to xen-unstable.

tools/python/xen/xend/XendCheckpoint.py renamed from tools/python/xen/xend/XendCheckpoint.py.orig +4 -0
@@ -178,6 +178,10 @@ def restore(xd, fd, paused=False):
 
         log.info("restore hvm domain %d, apic=%d, pae=%d",
                  dominfo.domid, apic, pae)
+
+        # for an HVM guest, we actually need an additional 2048 pages (8MB)
+        # for the qemu device model; add that here
+        nr_pfns += 2048
     else:
         apic = 0
         pae  = 0

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#1 lore raw
Quoted 4 lines · Chris Lalancette

All,
Attached is a patch to make Xend balloon down an additional 8MB (for the
Cirrus logic video device) when doing a restore or migrate. Without this, you can run into the following situation:

All,
Attached is an updated version of the patch. Dan Berrange correctly points
out that this logic already exists in xend, when an HVM domain is being created; the logic just wasn't being used in the restore path. This patch basically takes the logic from the creation path and pulls it into the restore path, so things work properly.

Again, this patch is against 3.1.0, but should apply fairly easily to unstable.

tools/python/xen/xend/XendCheckpoint.py renamed from tools/python/xen/xend/XendCheckpoint.py.orig +21 -8
@@ -18,6 +18,7 @@ import xen.util.auxbin
 import xen.lowlevel.xc
 
 import balloon
+import image
 from XendError import XendError, VmError
 from XendLogging import log
 from XendDomainInfo import DEV_MIGRATE_STEP1, DEV_MIGRATE_STEP2
@@ -168,8 +169,6 @@ def restore(xd, fd, paused=False):
     assert store_port
     assert console_port
 
-    nr_pfns = (dominfo.getMemoryTarget() + 3) / 4 
-
     # if hvm, pass mem size to calculate the store_mfn
     is_hvm = dominfo.is_hvm()
     if is_hvm:
@@ -183,18 +182,32 @@ def restore(xd, fd, paused=False):
         pae  = 0
 
     try:
-        shadow = dominfo.info['shadow_memory']
+        restore_image = image.create(dominfo, dominfo.info['image'],
+                                     dominfo.info['device'])
+        memory = restore_image.getRequiredAvailableMemory(
+            dominfo.info['memory'] * 1024)
+        maxmem = restore_image.getRequiredAvailableMemory(
+            dominfo.info['maxmem'] * 1024)
+        shadow = restore_image.getRequiredShadowMemory(
+            dominfo.info['shadow_memory'] * 1024,
+            dominfo.info['maxmem'] * 1024)
+
         log.debug("restore:shadow=0x%x, _static_max=0x%x, _static_min=0x%x, ",
                   dominfo.info['shadow_memory'],
                   dominfo.info['maxmem'],
                   dominfo.info['memory'])
 
-        balloon.free(xc.pages_to_kib(nr_pfns) + shadow * 1024)
+        # Round shadow up to a multiple of a MiB, as shadow_mem_control
+        # takes MiB and we must not round down and end up under-providing.
+        shadow = ((shadow + 1023) / 1024) * 1024
 
-        shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow)
-        dominfo.info['shadow_memory'] = shadow_cur
+        # set memory limit
+        xc.domain_setmaxmem(dominfo.getDomid(), maxmem)
 
-        xc.domain_setmaxmem(dominfo.getDomid(), dominfo.getMemoryMaximum())
+        balloon.free(memory + shadow)
+
+        shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow / 1024)
+        dominfo.info['shadow_memory'] = shadow_cur
 
         cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
                         fd, dominfo.getDomid(),
@@ -206,7 +219,7 @@ def restore(xd, fd, paused=False):
         forkHelper(cmd, fd, handler.handler, True)
 
         # We don't want to pass this fd to any other children -- we 
-        # might need to recover ths disk space that backs it.
+        # might need to recover the disk space that backs it.
         try:
             flags = fcntl.fcntl(fd, fcntl.F_GETFD)
             flags |= fcntl.FD_CLOEXEC

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel