xen/balloon: account for pages released during memory setup
authorDavid Vrabel <david.vrabel@citrix.com>
Wed, 28 Sep 2011 16:46:32 +0000 (17:46 +0100)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Thu, 29 Sep 2011 15:12:09 +0000 (11:12 -0400)
In xen_memory_setup() pages that occur in gaps in the memory map are
released back to Xen.  This reduces the domain's current page count in
the hypervisor.  The Xen balloon driver does not correctly decrease
its initial current_pages count to reflect this.  If 'delta' pages are
released and the target is adjusted the resulting reservation is
always 'delta' less than the requested target.

This affects dom0 if the initial allocation of pages overlaps the PCI
memory region but won't affect most domU guests that have been setup
with pseudo-physical memory maps that don't have gaps.

Fix this by accouting for the released pages when starting the balloon
driver.

If the domain's targets are managed by xapi, the domain may eventually
run out of memory and die because xapi currently gets its target
calculations wrong and whenever it is restarted it always reduces the
target by 'delta'.

Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
arch/x86/xen/setup.c
drivers/xen/balloon.c
include/xen/page.h

index 46d6d21dbdbec60800e38f996c7a89ebad2f1ae2..c983717c018ca757555ece7c6a8777ef369cbf1b 100644 (file)
@@ -39,6 +39,9 @@ extern void xen_syscall32_target(void);
 /* Amount of extra memory space we add to the e820 ranges */
 phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
 
+/* Number of pages released from the initial allocation. */
+unsigned long xen_released_pages;
+
 /* 
  * The maximum amount of extra memory compared to the base size.  The
  * main scaling factor is the size of struct page.  At extreme ratios
@@ -313,7 +316,9 @@ char * __init xen_memory_setup(void)
                        extra_pages = 0;
        }
 
-       extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
+       xen_released_pages = xen_return_unused_memory(xen_start_info->nr_pages,
+                                                     &e820);
+       extra_pages += xen_released_pages;
 
        /*
         * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
index 5dfd8f8ff07f402e9063b608c7e11b1b6571c126..4f59fb3733815c2e331a1f353046ee64fb2bc24b 100644 (file)
@@ -565,7 +565,9 @@ static int __init balloon_init(void)
 
        pr_info("xen/balloon: Initialising balloon driver.\n");
 
-       balloon_stats.current_pages = xen_pv_domain() ? min(xen_start_info->nr_pages, max_pfn) : max_pfn;
+       balloon_stats.current_pages = xen_pv_domain()
+               ? min(xen_start_info->nr_pages - xen_released_pages, max_pfn)
+               : max_pfn;
        balloon_stats.target_pages  = balloon_stats.current_pages;
        balloon_stats.balloon_low   = 0;
        balloon_stats.balloon_high  = 0;
index 0be36b976f4b02905034532919e7fc576eba19d7..92b61f8c772cd2ea27fcdfa460a0315d5da158aa 100644 (file)
@@ -5,4 +5,6 @@
 
 extern phys_addr_t xen_extra_mem_start, xen_extra_mem_size;
 
+extern unsigned long xen_released_pages;
+
 #endif /* _XEN_PAGE_H */