Commit b2ac6aa8 authored by David Vrabel's avatar David Vrabel

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: default avatarDavid Vrabel <david.vrabel@citrix.com>
Reviewed-by: default avatarDaniel 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.
parent de5a77d8
...@@ -75,12 +75,14 @@ ...@@ -75,12 +75,14 @@
* balloon_process() state: * balloon_process() state:
* *
* BP_DONE: done or nothing to do, * BP_DONE: done or nothing to do,
* BP_WAIT: wait to be rescheduled,
* BP_EAGAIN: error, go to sleep, * BP_EAGAIN: error, go to sleep,
* BP_ECANCELED: error, balloon operation canceled. * BP_ECANCELED: error, balloon operation canceled.
*/ */
enum bp_state { enum bp_state {
BP_DONE, BP_DONE,
BP_WAIT,
BP_EAGAIN, BP_EAGAIN,
BP_ECANCELED BP_ECANCELED
}; };
...@@ -167,6 +169,9 @@ static struct page *balloon_next_page(struct page *page) ...@@ -167,6 +169,9 @@ static struct page *balloon_next_page(struct page *page)
static enum bp_state update_schedule(enum bp_state state) static enum bp_state update_schedule(enum bp_state state)
{ {
if (state == BP_WAIT)
return BP_WAIT;
if (state == BP_ECANCELED) if (state == BP_ECANCELED)
return BP_ECANCELED; return BP_ECANCELED;
...@@ -231,12 +236,22 @@ static void release_memory_resource(struct resource *resource) ...@@ -231,12 +236,22 @@ static void release_memory_resource(struct resource *resource)
kfree(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; struct resource *resource;
int nid, rc; int nid, rc;
unsigned long balloon_hotplug; 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); balloon_hotplug = round_up(credit, PAGES_PER_SECTION);
resource = additional_memory_resource(balloon_hotplug * PAGE_SIZE); resource = additional_memory_resource(balloon_hotplug * PAGE_SIZE);
...@@ -276,7 +291,7 @@ static enum bp_state reserve_additional_memory(long credit) ...@@ -276,7 +291,7 @@ static enum bp_state reserve_additional_memory(long credit)
balloon_stats.total_pages += balloon_hotplug; balloon_stats.total_pages += balloon_hotplug;
return BP_DONE; return BP_WAIT;
err: err:
release_memory_resource(resource); release_memory_resource(resource);
return BP_ECANCELED; return BP_ECANCELED;
...@@ -306,7 +321,7 @@ static struct notifier_block xen_memory_nb = { ...@@ -306,7 +321,7 @@ static struct notifier_block xen_memory_nb = {
.priority = 0 .priority = 0
}; };
#else #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; balloon_stats.target_pages = balloon_stats.current_pages;
return BP_DONE; return BP_DONE;
...@@ -474,7 +489,7 @@ static void balloon_process(struct work_struct *work) ...@@ -474,7 +489,7 @@ static void balloon_process(struct work_struct *work)
if (balloon_is_inflated()) if (balloon_is_inflated())
state = increase_reservation(credit); state = increase_reservation(credit);
else else
state = reserve_additional_memory(credit); state = reserve_additional_memory();
} }
if (credit < 0) if (credit < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment