From 1058a75f07b9bb8323fb5197be5526220f8b75cf Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 22 Jan 2009 14:36:08 -0800 Subject: xen: actually release memory when shrinking domain Fix this: > It appears that in the upstream balloon driver, > the call to HYPERVISOR_update_va_mapping is missing > from decrease_reservation. I think as a result, > the balloon driver is eating memory but not > releasing it to Xen, thus rendering the balloon > driver essentially useless. (Can be observed via xentop.) Signed-off-by: Dan Magenheimer Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- drivers/xen/balloon.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/xen/balloon.c') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 8dc7109d61b7..8069d520c460 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -298,6 +298,11 @@ static int decrease_reservation(unsigned long nr_pages) frame_list[i] = pfn_to_mfn(pfn); scrub_page(page); + + ret = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + __pte_ma(0), 0); + BUG_ON(ret); } /* Ensure that ballooned highmem pages don't have kmaps. */ -- cgit v1.2.1 From ff4ce8c332859508dc97826ab8b7f42bb9c212c9 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 23 Jan 2009 16:26:21 +0000 Subject: xen: handle highmem pages correctly when shrinking a domain Commit 1058a75f07b9bb8323fb5197be5526220f8b75cf ("xen: actually release memory when shrinking domain") causes a crash if the page being released is a highmem page. If a page is highmem then there is no need to unmap it. Signed-off-by: Ian Campbell Acked-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- drivers/xen/balloon.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/xen/balloon.c') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 8069d520c460..2ba8f95516a0 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -299,10 +299,13 @@ static int decrease_reservation(unsigned long nr_pages) scrub_page(page); - ret = HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - __pte_ma(0), 0); - BUG_ON(ret); + if (!PageHighMem(page)) { + ret = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + __pte_ma(0), 0); + BUG_ON(ret); + } + } /* Ensure that ballooned highmem pages don't have kmaps. */ -- cgit v1.2.1 From 618b2c8db24522ae273d8299c6a936ea13793c4d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 28 Jan 2009 16:50:20 -0800 Subject: xen: make sysfs files behave as their names suggest 1: make "target_kb" only accept and produce a memory size in kilobytes. 2: add a second "target" file which produces output in bytes, and will accept memparse input (scaled bytes) This fixes the rather irritating problem that writing the same value read back into target_kb would end up shrinking the domain by a factor of 1024, with generally bad results. Signed-off-by: Jeremy Fitzhardinge Cc: Stable Kernel Cc: "dan.magenheimer@oracle.com" Signed-off-by: Ingo Molnar --- drivers/xen/balloon.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers/xen/balloon.c') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 2ba8f95516a0..efa4b363ce72 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -498,7 +498,7 @@ static ssize_t store_target_kb(struct sys_device *dev, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - target_bytes = memparse(buf, &endchar); + target_bytes = simple_strtoull(buf, &endchar, 0) * 1024; balloon_set_new_target(target_bytes >> PAGE_SHIFT); @@ -508,8 +508,39 @@ static ssize_t store_target_kb(struct sys_device *dev, static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR, show_target_kb, store_target_kb); + +static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr, + char *buf) +{ + return sprintf(buf, "%llu\n", + (u64)balloon_stats.target_pages << PAGE_SHIFT); +} + +static ssize_t store_target(struct sys_device *dev, + struct sysdev_attribute *attr, + const char *buf, + size_t count) +{ + char *endchar; + unsigned long long target_bytes; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + target_bytes = memparse(buf, &endchar); + + balloon_set_new_target(target_bytes >> PAGE_SHIFT); + + return count; +} + +static SYSDEV_ATTR(target, S_IRUGO | S_IWUSR, + show_target, store_target); + + static struct sysdev_attribute *balloon_attrs[] = { &attr_target_kb, + &attr_target, }; static struct attribute *balloon_info_attrs[] = { -- cgit v1.2.1