xen/balloon: only hotplug additional memory if required
authorDavid Vrabel <david.vrabel@citrix.com>
Thu, 25 Jun 2015 11:10:28 +0000 (12:10 +0100)
committerDavid Vrabel <david.vrabel@citrix.com>
Fri, 23 Oct 2015 13:20:04 +0000 (14:20 +0100)
Now that we track the total number of pages (included hotplugged
regions), it is easy to determine if more memory needs to be
hotplugged.

Add a new BP_WAIT state to signal that the balloon process needs to
wait until kicked by the memory add notifier (when the new section is
onlined by userspace).

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
v3:
- Return BP_WAIT if enough sections are already hotplugged.

v2:
- New BP_WAIT status after adding new memory sections.

drivers/xen/balloon.c

index ac80547..ac6391b 100644 (file)
  * balloon_process() state:
  *
  * BP_DONE: done or nothing to do,
+ * BP_WAIT: wait to be rescheduled,
  * BP_EAGAIN: error, go to sleep,
  * BP_ECANCELED: error, balloon operation canceled.
  */
 
 enum bp_state {
        BP_DONE,
+       BP_WAIT,
        BP_EAGAIN,
        BP_ECANCELED
 };
@@ -167,6 +169,9 @@ static struct page *balloon_next_page(struct page *page)
 
 static enum bp_state update_schedule(enum bp_state state)
 {
+       if (state == BP_WAIT)
+               return BP_WAIT;
+
        if (state == BP_ECANCELED)
                return BP_ECANCELED;
 
@@ -231,12 +236,22 @@ static void release_memory_resource(struct resource *resource)
        kfree(resource);
 }
 
-static enum bp_state reserve_additional_memory(long credit)
+static enum bp_state reserve_additional_memory(void)
 {
+       long credit;
        struct resource *resource;
        int nid, rc;
        unsigned long balloon_hotplug;
 
+       credit = balloon_stats.target_pages - balloon_stats.total_pages;
+
+       /*
+        * Already hotplugged enough pages?  Wait for them to be
+        * onlined.
+        */
+       if (credit <= 0)
+               return BP_WAIT;
+
        balloon_hotplug = round_up(credit, PAGES_PER_SECTION);
 
        resource = additional_memory_resource(balloon_hotplug * PAGE_SIZE);
@@ -276,7 +291,7 @@ static enum bp_state reserve_additional_memory(long credit)
 
        balloon_stats.total_pages += balloon_hotplug;
 
-       return BP_DONE;
+       return BP_WAIT;
   err:
        release_memory_resource(resource);
        return BP_ECANCELED;
@@ -306,7 +321,7 @@ static struct notifier_block xen_memory_nb = {
        .priority = 0
 };
 #else
-static enum bp_state reserve_additional_memory(long credit)
+static enum bp_state reserve_additional_memory(void)
 {
        balloon_stats.target_pages = balloon_stats.current_pages;
        return BP_DONE;
@@ -474,7 +489,7 @@ static void balloon_process(struct work_struct *work)
                        if (balloon_is_inflated())
                                state = increase_reservation(credit);
                        else
-                               state = reserve_additional_memory(credit);
+                               state = reserve_additional_memory();
                }
 
                if (credit < 0)