]> xenbits.xensource.com Git - people/royger/linux-2.6.18-xen.git/commitdiff
xen/balloon: fix balloon driver accounting for HVM-with-PoD case
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 1 Feb 2010 14:12:36 +0000 (14:12 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 1 Feb 2010 14:12:36 +0000 (14:12 +0000)
With PoD, ballooning down a guest to the target set through xenstore
based on its totalram_pages value isn't sufficient, since that value
doesn't include all the pages assigned to the guest. Since the delta
is static, determine it once at load time.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
drivers/xen/balloon/balloon.c

index cf1878c7fc6eb9c9248d3d9f6985b189f335e8cb..c8bd48e19825fad77d0e0c5bba513d9bae606d90 100644 (file)
@@ -93,6 +93,18 @@ extern unsigned long totalhigh_pages;
 #define dec_totalhigh_pages() ((void)0)
 #endif
 
+#ifndef CONFIG_XEN
+/*
+ * In HVM guests accounting here uses the Xen visible values, but the kernel
+ * determined totalram_pages value shouldn't get altered. Since totalram_pages
+ * includes neither the kernel static image nor any memory allocated prior to
+ * or from the bootmem allocator, we have to synchronize the two values.
+ */
+static unsigned long __read_mostly totalram_bias;
+#else
+#define totalram_bias 0
+#endif
+
 /* List of ballooned pages, threaded through the mem_map array. */
 static LIST_HEAD(ballooned_pages);
 
@@ -289,7 +301,7 @@ static int increase_reservation(unsigned long nr_pages)
        }
 
        bs.current_pages += rc;
-       totalram_pages = bs.current_pages;
+       totalram_pages = bs.current_pages - totalram_bias;
 
  out:
        balloon_unlock(flags);
@@ -362,7 +374,7 @@ static int decrease_reservation(unsigned long nr_pages)
        BUG_ON(ret != nr_pages);
 
        bs.current_pages -= nr_pages;
-       totalram_pages = bs.current_pages;
+       totalram_pages = bs.current_pages - totalram_bias;
 
        balloon_unlock(flags);
 
@@ -498,7 +510,19 @@ static struct notifier_block xenstore_notifier;
 
 static int __init balloon_init(void)
 {
-#if defined(CONFIG_X86) && defined(CONFIG_XEN) 
+#if !defined(CONFIG_XEN)
+# ifndef XENMEM_get_pod_target
+#  define XENMEM_get_pod_target 17
+       typedef struct xen_pod_target {
+               uint64_t target_pages;
+               uint64_t tot_pages;
+               uint64_t pod_cache_pages;
+               uint64_t pod_entries;
+               domid_t domid;
+       } xen_pod_target_t;
+# endif
+       xen_pod_target_t pod_target = { .domid = DOMID_SELF };
+#elif defined(CONFIG_X86)
        unsigned long pfn;
        struct page *page;
 #endif
@@ -512,7 +536,20 @@ static int __init balloon_init(void)
        bs.current_pages = min(xen_start_info->nr_pages, max_pfn);
        totalram_pages   = bs.current_pages;
 #else 
-       bs.current_pages = totalram_pages; 
+       totalram_bias = HYPERVISOR_memory_op(
+               HYPERVISOR_memory_op(XENMEM_get_pod_target,
+                       &pod_target) != -ENOSYS
+               ? XENMEM_maximum_reservation
+               : XENMEM_current_reservation,
+               &pod_target.domid);
+       if ((long)totalram_bias != -ENOSYS) {
+               BUG_ON(totalram_bias < totalram_pages);
+               bs.current_pages = totalram_bias;
+               totalram_bias -= totalram_pages;
+       } else {
+               totalram_bias = 0;
+               bs.current_pages = totalram_pages;
+       }
 #endif
        bs.target_pages  = bs.current_pages;
        bs.balloon_low   = 0;
@@ -651,7 +688,7 @@ struct page **alloc_empty_pages_and_pagevec(int nr_pages)
                        goto err;
                }
 
-               totalram_pages = --bs.current_pages;
+               totalram_pages = --bs.current_pages - totalram_bias;
 
                balloon_unlock(flags);
        }