From: Keir Fraser Date: Mon, 1 Feb 2010 14:12:36 +0000 (+0000) Subject: xen/balloon: fix balloon driver accounting for HVM-with-PoD case X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=e6d0b08274c7145e919b365da4b1e9f8fe000f4b;p=legacy%2Flinux-2.6.18-xen.git xen/balloon: fix balloon driver accounting for HVM-with-PoD case 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 --- diff --git a/drivers/xen/balloon/balloon.c b/drivers/xen/balloon/balloon.c index cf1878c7..c8bd48e1 100644 --- a/drivers/xen/balloon/balloon.c +++ b/drivers/xen/balloon/balloon.c @@ -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); }