]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
xen/setup: Cap amount to populate based on current tot_pages count.
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Fri, 27 Apr 2012 02:11:08 +0000 (22:11 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Fri, 27 Apr 2012 20:02:32 +0000 (16:02 -0400)
Previous to this patch we would try to populate exactly up to
xen_released_pages number (so the ones that we released), but
that is incorrect as there are some pages that we thought were
released but in actuality were shared. Depending on the platform
it could be small amounts - 2 pages, but some had much higher - 17.

As such, lets use the XENMEM_current_reservation to get the exact
count of pages we are using, subtract it from nr_pages and use the
lesser of this and xen_released_pages to populate back.

This fixes errors such as:

(XEN) page_alloc.c:1148:d0 Over-allocation for domain 0: 2097153 > 2097152
(XEN) memory.c:133:d0 Could not allocate order=0 extent: id=0 memflags=0 (0 of 17)

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
arch/x86/xen/setup.c

index 506a3e64463667ae15f6d1b8d3f189e33d456136..8e7dcfd537ef93a286d29fb8f8ea45fb1bcc8f31 100644 (file)
@@ -287,7 +287,15 @@ static unsigned long __init xen_get_max_pages(void)
 
        return min(max_pages, MAX_DOMAIN_PAGES);
 }
-
+static unsigned long xen_get_current_pages(void)
+{
+       domid_t domid = DOMID_SELF;
+       int ret;
+       ret = HYPERVISOR_memory_op(XENMEM_current_reservation, &domid);
+       if (ret > 0)
+               return ret;
+       return 0;
+}
 static void xen_align_and_add_e820_region(u64 start, u64 size, int type)
 {
        u64 end = start + size;
@@ -358,7 +366,11 @@ char * __init xen_memory_setup(void)
 
        /*
         * Populate back the non-RAM pages and E820 gaps that had been
-        * released. */
+        * released. But cap it as certain regions cannot be repopulated.
+        */
+       if (xen_get_current_pages())
+               xen_released_pages = min(max_pfn - xen_get_current_pages(),
+                               xen_released_pages);
        populated = xen_populate_chunk(map, memmap.nr_entries,
                        max_pfn, &last_pfn, xen_released_pages);