diff options
| -rw-r--r-- | drivers/xen/balloon.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index e7f1d4ca6d75..e7f74ea7cd5e 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -679,7 +679,7 @@ void xen_free_ballooned_pages(unsigned int nr_pages, struct page **pages) } EXPORT_SYMBOL(xen_free_ballooned_pages); -static int __init balloon_add_regions(void) +static int __init balloon_add_regions(bool append) { unsigned long start_pfn, pages; unsigned long pfn, extra_pfn_end; @@ -703,19 +703,26 @@ static int __init balloon_add_regions(void) balloon_append(pfn_to_page(pfn)); /* - * Extra regions are accounted for in the physmap, but need - * decreasing from current_pages and target_pages to balloon - * down the initial allocation, because they are already - * accounted for in total_pages. + * There are two different use-cases depending on how the + * initial memory target is fetched. For PVH dom0 and PV the + * target is usually set to reflect the domain assigned memory, + * and hence extra regions need adding. + * + * OTOH for HVM and PVH domU the target is set to the amount of + * RAM reported in the memory map, and hence extra regions need + * subtracting to reflect the real memory usage. */ pages = extra_pfn_end - start_pfn; - if (pages >= balloon_stats.current_pages || - pages >= balloon_stats.target_pages) { + if (append) { + balloon_stats.total_pages += pages; + } else if (pages >= balloon_stats.current_pages || + pages >= balloon_stats.target_pages) { WARN(1, "Extra pages underflow current target"); return -ERANGE; + } else { + balloon_stats.current_pages -= pages; + balloon_stats.target_pages -= pages; } - balloon_stats.current_pages -= pages; - balloon_stats.target_pages -= pages; } return 0; @@ -726,6 +733,7 @@ static int __init balloon_init(void) struct task_struct *task; long current_pages = 0; domid_t domid = DOMID_SELF; + bool append = true; int rc; if (!xen_domain()) @@ -745,6 +753,7 @@ static int __init balloon_init(void) } else { if (xen_unpopulated_pages >= get_num_physpages()) goto underflow; + append = false; current_pages = get_num_physpages() - xen_unpopulated_pages; } @@ -767,7 +776,7 @@ static int __init balloon_init(void) register_sysctl_init("xen/balloon", balloon_table); #endif - rc = balloon_add_regions(); + rc = balloon_add_regions(append); if (rc) return rc; |
