summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2015-06-25 14:10:28 +0300
committerDavid Vrabel <david.vrabel@citrix.com>2015-10-23 16:20:04 +0300
commitb2ac6aa8f71bf57b948ee68cd913c350b932da88 (patch)
tree265cb770cf581da01049c6bc6acc696a03467411
parentde5a77d8422fc7ed0b2f4349bceb65a1a639e5b2 (diff)
downloadlinux-b2ac6aa8f71bf57b948ee68cd913c350b932da88.tar.xz
xen/balloon: only hotplug additional memory if required
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.
-rw-r--r--drivers/xen/balloon.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index ac8054765127..ac6391bd8029 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -75,12 +75,14 @@
* 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)