]> xenbits.xensource.com Git - xen.git/commitdiff
xen: make the shadow allocation hypercalls include the p2m memory
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 8 Jul 2010 08:52:51 +0000 (09:52 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 8 Jul 2010 08:52:51 +0000 (09:52 +0100)
in the total shadow allocation. This makes the effect of allocation
changes consistent regardless of p2m activity on boot.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
xen/arch/x86/mm/hap/hap.c
xen/arch/x86/mm/shadow/common.c

index 00584616099d38192d3729f2aa38e72aa73f3fc3..60f6a3c97537c7bc3e30edb462e8684f10eb06cc 100644 (file)
@@ -334,7 +334,8 @@ static void hap_free_p2m_page(struct domain *d, struct page_info *pg)
 static unsigned int
 hap_get_allocation(struct domain *d)
 {
-    unsigned int pg = d->arch.paging.hap.total_pages;
+    unsigned int pg = d->arch.paging.hap.total_pages
+        + d->arch.paging.hap.p2m_pages;
 
     return ((pg >> (20 - PAGE_SHIFT))
             + ((pg & ((1 << (20 - PAGE_SHIFT)) - 1)) ? 1 : 0));
@@ -349,6 +350,11 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
 
     ASSERT(hap_locked_by_me(d));
 
+    if ( pages < d->arch.paging.hap.p2m_pages )
+        pages = 0;
+    else
+        pages -= d->arch.paging.hap.p2m_pages;
+
     while ( d->arch.paging.hap.total_pages != pages )
     {
         if ( d->arch.paging.hap.total_pages < pages )
@@ -367,6 +373,11 @@ hap_set_allocation(struct domain *d, unsigned int pages, int *preempted)
         else if ( d->arch.paging.hap.total_pages > pages )
         {
             /* Need to return memory to domheap */
+            if ( page_list_empty(&d->arch.paging.hap.freelist) )
+            {
+                HAP_PRINTK("failed to free enough hap pages.\n");
+                return -ENOMEM;
+            }
             pg = page_list_remove_head(&d->arch.paging.hap.freelist);
             ASSERT(pg);
             d->arch.paging.hap.free_pages--;
index a42de64725606b17028fcf9905100f366c6af4e5..ca756a4818ae335f7c924c81a74e64b916d41830 100644 (file)
@@ -1817,14 +1817,24 @@ static unsigned int sh_set_allocation(struct domain *d,
     unsigned int j, order = shadow_max_order(d);
 
     ASSERT(shadow_locked_by_me(d));
-    
-    /* Don't allocate less than the minimum acceptable, plus one page per
-     * megabyte of RAM (for the p2m table) */
-    lower_bound = shadow_min_acceptable_pages(d) + (d->tot_pages / 256);
-    if ( pages > 0 && pages < lower_bound )
-        pages = lower_bound;
-    /* Round up to largest block size */
-    pages = (pages + ((1<<SHADOW_MAX_ORDER)-1)) & ~((1<<SHADOW_MAX_ORDER)-1);
+
+    if ( pages > 0 )
+    {
+        /* Check for minimum value. */
+        if ( pages < d->arch.paging.shadow.p2m_pages )
+            pages = 0;
+        else
+            pages -= d->arch.paging.shadow.p2m_pages;
+        
+        /* Don't allocate less than the minimum acceptable, plus one page per
+         * megabyte of RAM (for the p2m table) */
+        lower_bound = shadow_min_acceptable_pages(d) + (d->tot_pages / 256);
+        if ( pages < lower_bound )
+            pages = lower_bound;
+        
+        /* Round up to largest block size */
+        pages = (pages + ((1<<SHADOW_MAX_ORDER)-1)) & ~((1<<SHADOW_MAX_ORDER)-1);
+    }
 
     SHADOW_PRINTK("current %i target %i\n", 
                    d->arch.paging.shadow.total_pages, pages);
@@ -1884,7 +1894,8 @@ static unsigned int sh_set_allocation(struct domain *d,
 /* Return the size of the shadow pool, rounded up to the nearest MB */
 static unsigned int shadow_get_allocation(struct domain *d)
 {
-    unsigned int pg = d->arch.paging.shadow.total_pages;
+    unsigned int pg = d->arch.paging.shadow.total_pages
+        + d->arch.paging.shadow.p2m_pages;
     return ((pg >> (20 - PAGE_SHIFT))
             + ((pg & ((1 << (20 - PAGE_SHIFT)) - 1)) ? 1 : 0));
 }