WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Loop retrying when ballooning out, even when the dom0-mi

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Loop retrying when ballooning out, even when the dom0-min-mem setting means
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 08 Dec 2005 15:28:10 +0000
Delivery-date: Thu, 08 Dec 2005 15:28:52 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 8e74f2cf985ed5ba10b11f9713ffe35be6ec2af5
# Parent  cdf76916951a49d77cb8b0d982a570eedbbb1538
Loop retrying when ballooning out, even when the dom0-min-mem setting means
that there is not sufficient memory available at the moment.  Memory may be
about to be freed up by the system after a domain destruction (i.e. the memory
is being scrubbed asynchronously, and will be released soon).

Closes bug #407, bug #429.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r cdf76916951a -r 8e74f2cf985e tools/python/xen/xend/balloon.py
--- a/tools/python/xen/xend/balloon.py  Thu Dec  8 12:10:22 2005
+++ b/tools/python/xen/xend/balloon.py  Thu Dec  8 12:13:06 2005
@@ -30,52 +30,95 @@
 PROC_XEN_BALLOON = "/proc/xen/balloon"
 BALLOON_OUT_SLACK = 1 # MiB.  We need this because the physinfo details are
                       # rounded.
+RETRY_LIMIT = 10
+##
+# The time to sleep between retries grows linearly, using this value (in
+# seconds).  When the system is lightly loaded, memory should be scrubbed and
+# returned to the system very quickly, whereas when it is loaded, the system
+# needs idle time to get the scrubbing done.  This linear growth accommodates
+# such requirements.
+SLEEP_TIME_GROWTH = 0.1
 
 
 def free(required):
     """Balloon out memory from the privileged domain so that there is the
     specified required amount (in KiB) free.
     """
-    
+
+    # We check whether there is enough free memory, and if not, instruct dom0
+    # to balloon out to free some up.  Memory freed by a destroyed domain may
+    # not appear in the free_memory field immediately, because it needs to be
+    # scrubbed before it can be released to the free list, which is done
+    # asynchronously by Xen; ballooning is asynchronous also.  No matter where
+    # we expect the free memory to come from, therefore, we need to wait for
+    # it to become available.
+    #
+    # We are not allowed to balloon below dom0_min_mem, or if dom0_min_mem
+    # is 0, we cannot balloon at all.  Memory can still become available
+    # through a rebooting domain, however.
+    #
+    # Eventually, we time out (presumably because there really isn't enough
+    # free memory).
+    #
+    # We don't want to set the memory target (triggering a watch) when that
+    # has already been done, but we do want to respond to changing memory
+    # usage, so we recheck the required alloc each time around the loop, but
+    # track the last used value so that we don't trigger too many watches.
+
+    need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK
+
+    xroot = XendRoot.instance()
     xc = xen.lowlevel.xc.xc()
-    xroot = XendRoot.instance()
 
     try:
-        free_mem = xc.physinfo()['free_memory']
-        need_mem = (required + 1023) / 1024 + BALLOON_OUT_SLACK
+        dom0_min_mem = xroot.get_dom0_min_mem()
 
-        log.debug("Balloon: free %d; need %d.", free_mem, need_mem)
-        
-        if free_mem >= need_mem:
-            return
+        retries = 0
+        sleep_time = SLEEP_TIME_GROWTH
+        last_new_alloc = None
+        while retries < RETRY_LIMIT:
+            free_mem = xc.physinfo()['free_memory']
 
-        dom0_min_mem = xroot.get_dom0_min_mem()
+            if free_mem >= need_mem:
+                log.debug("Balloon: free %d; need %d; done.", free_mem,
+                          need_mem)
+                return
+
+            if retries == 0:
+                log.debug("Balloon: free %d; need %d.", free_mem, need_mem)
+
+            if dom0_min_mem > 0:
+                dom0_alloc = _get_dom0_alloc()
+                new_alloc = dom0_alloc - (need_mem - free_mem)
+
+                if (new_alloc >= dom0_min_mem and
+                    new_alloc != last_new_alloc):
+                    log.debug("Balloon: setting dom0 target to %d.",
+                              new_alloc)
+                    dom0 = XendDomain.instance().privilegedDomain()
+                    dom0.setMemoryTarget(new_alloc)
+                    last_new_alloc = new_alloc
+                    # Continue to retry, waiting for ballooning.
+
+            time.sleep(sleep_time)
+            retries += 1
+            sleep_time += SLEEP_TIME_GROWTH
+
+        # Not enough memory; diagnose the problem.
         if dom0_min_mem == 0:
-            raise VmError('Not enough free memory and dom0_min_mem is 0.')
-
-        dom0_alloc = _get_dom0_alloc()
-        dom0_new_alloc = dom0_alloc - (need_mem - free_mem)
-        if dom0_new_alloc < dom0_min_mem:
+            raise VmError(('Not enough free memory and dom0_min_mem is 0, so '
+                           'I cannot release any more.  I need %d MiB but '
+                           'only have %d.') %
+                          (need_mem, free_mem))
+        elif new_alloc >= dom0_min_mem:
             raise VmError(
                 ('I need %d MiB, but dom0_min_mem is %d and shrinking to '
                  '%d MiB would leave only %d MiB free.') %
                 (need_mem, dom0_min_mem, dom0_min_mem,
-                 free_mem + (dom0_alloc - dom0_min_mem)))
+                 free_mem + dom0_alloc - dom0_min_mem))
+        else:
+            raise VmError('The privileged domain did not balloon!')
 
-        dom0 = XendDomain.instance().privilegedDomain()
-        dom0.setMemoryTarget(dom0_new_alloc)
-
-        timeout = 20 # 2 sec
-        while timeout > 0:
-            time.sleep(0.1)
-
-            free_mem = xc.physinfo()['free_memory']
-            if free_mem >= need_mem:
-                return
-
-            timeout -= 1
-
-        raise VmError('The privileged domain did not balloon!')
     finally:
         del xc
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>