# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1202723569 0
# Node ID 9dcb40286ad4fa5e3e376e280a176655d52f9fe5
# Parent 3b73a079c1fb225082ef1b70620afab5d6d919b9
xen balloon: allocate and free cold pages
To reduce the performance side effects of ballooning, use and return
cold pages. To limit the impact scrubbing of these (and other) pages
has on the cache, also implement a dedicated scrubbing function on x86
which uses non-temporal stores (when available).
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
arch/i386/lib/Makefile | 1
arch/i386/lib/scrub.c | 21 +++++++++++++++++++
arch/i386/mm/hypervisor.c | 4 +--
arch/x86_64/lib/Makefile | 1
arch/x86_64/lib/scrub.c | 1
drivers/xen/balloon/balloon.c | 32 +++++++++++++++++++----------
include/asm-i386/mach-xen/asm/hypervisor.h | 2 -
7 files changed, 49 insertions(+), 13 deletions(-)
diff -r 3b73a079c1fb -r 9dcb40286ad4 arch/i386/lib/Makefile
--- a/arch/i386/lib/Makefile Mon Feb 11 09:52:01 2008 +0000
+++ b/arch/i386/lib/Makefile Mon Feb 11 09:52:49 2008 +0000
@@ -7,3 +7,4 @@ lib-y = checksum.o delay.o usercopy.o ge
bitops.o
lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
+lib-$(CONFIG_XEN_SCRUB_PAGES) += scrub.o
diff -r 3b73a079c1fb -r 9dcb40286ad4 arch/i386/lib/scrub.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/i386/lib/scrub.c Mon Feb 11 09:52:49 2008 +0000
@@ -0,0 +1,21 @@
+#include <asm/cpufeature.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+void scrub_pages(void *v, unsigned int count)
+{
+ if (likely(cpu_has_xmm2)) {
+ unsigned long n = count * (PAGE_SIZE / sizeof(long) / 4);
+
+ for (; n--; v += sizeof(long) * 4)
+ asm("movnti %1,(%0)\n\t"
+ "movnti %1,%c2(%0)\n\t"
+ "movnti %1,2*%c2(%0)\n\t"
+ "movnti %1,3*%c2(%0)\n\t"
+ : : "r" (v), "r" (0L), "i" (sizeof(long))
+ : "memory");
+ asm volatile("sfence" : : : "memory");
+ } else
+ for (; count--; v += PAGE_SIZE)
+ clear_page(v);
+}
diff -r 3b73a079c1fb -r 9dcb40286ad4 arch/i386/mm/hypervisor.c
--- a/arch/i386/mm/hypervisor.c Mon Feb 11 09:52:01 2008 +0000
+++ b/arch/i386/mm/hypervisor.c Mon Feb 11 09:52:49 2008 +0000
@@ -280,7 +280,7 @@ int xen_create_contiguous_region(
set_xen_guest_handle(exchange.in.extent_start, in_frames);
set_xen_guest_handle(exchange.out.extent_start, &out_frame);
- scrub_pages(vstart, 1 << order);
+ scrub_pages((void *)vstart, 1 << order);
balloon_lock(flags);
@@ -373,7 +373,7 @@ void xen_destroy_contiguous_region(unsig
set_xen_guest_handle(exchange.in.extent_start, &in_frame);
set_xen_guest_handle(exchange.out.extent_start, out_frames);
- scrub_pages(vstart, 1 << order);
+ scrub_pages((void *)vstart, 1 << order);
balloon_lock(flags);
diff -r 3b73a079c1fb -r 9dcb40286ad4 arch/x86_64/lib/Makefile
--- a/arch/x86_64/lib/Makefile Mon Feb 11 09:52:01 2008 +0000
+++ b/arch/x86_64/lib/Makefile Mon Feb 11 09:52:49 2008 +0000
@@ -10,3 +10,4 @@ lib-y := csum-partial.o csum-copy.o csum
usercopy.o getuser.o putuser.o \
thunk.o clear_page.o copy_page.o bitstr.o bitops.o
lib-y += memcpy.o memmove.o memset.o copy_user.o
+lib-$(CONFIG_XEN_SCRUB_PAGES) += scrub.o
diff -r 3b73a079c1fb -r 9dcb40286ad4 arch/x86_64/lib/scrub.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/x86_64/lib/scrub.c Mon Feb 11 09:52:49 2008 +0000
@@ -0,0 +1,1 @@
+#include "../../i386/lib/scrub.c"
diff -r 3b73a079c1fb -r 9dcb40286ad4 drivers/xen/balloon/balloon.c
--- a/drivers/xen/balloon/balloon.c Mon Feb 11 09:52:01 2008 +0000
+++ b/drivers/xen/balloon/balloon.c Mon Feb 11 09:52:49 2008 +0000
@@ -104,7 +104,7 @@ static struct timer_list balloon_timer;
/* When ballooning out (allocating memory to return to Xen) we don't really
want the kernel to try too hard since that can trigger the oom killer. */
#define GFP_BALLOON \
- (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
+ (GFP_HIGHUSER|__GFP_NOWARN|__GFP_NORETRY|__GFP_NOMEMALLOC|__GFP_COLD)
#define PAGE_TO_LIST(p) (&(p)->lru)
#define LIST_TO_PAGE(l) list_entry((l), struct page, lru)
@@ -170,6 +170,17 @@ static struct page *balloon_next_page(st
return LIST_TO_PAGE(next);
}
+static inline void balloon_free_page(struct page *page)
+{
+#ifndef MODULE
+ if (put_page_testzero(page))
+ free_cold_page(page);
+#else
+ /* free_cold_page() is not being exported. */
+ __free_page(page);
+#endif
+}
+
static void balloon_alarm(unsigned long unused)
{
schedule_work(&balloon_worker);
@@ -251,7 +262,7 @@ static int increase_reservation(unsigned
/* Relinquish the page back to the allocator. */
ClearPageReserved(page);
init_page_count(page);
- __free_page(page);
+ balloon_free_page(page);
}
bs.current_pages += nr_pages;
@@ -566,7 +577,8 @@ static int dealloc_pte_fn(
struct page **alloc_empty_pages_and_pagevec(int nr_pages)
{
- unsigned long vaddr, flags;
+ unsigned long flags;
+ void *v;
struct page *page, **pagevec;
int i, ret;
@@ -575,13 +587,12 @@ struct page **alloc_empty_pages_and_page
return NULL;
for (i = 0; i < nr_pages; i++) {
- page = pagevec[i] = alloc_page(GFP_KERNEL);
+ page = pagevec[i] = alloc_page(GFP_KERNEL|__GFP_COLD);
if (page == NULL)
goto err;
- vaddr = (unsigned long)page_address(page);
-
- scrub_pages(vaddr, 1);
+ v = page_address(page);
+ scrub_pages(v, 1);
balloon_lock(flags);
@@ -599,8 +610,9 @@ struct page **alloc_empty_pages_and_page
ret = 0; /* success */
} else {
#ifdef CONFIG_XEN
- ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
- dealloc_pte_fn, NULL);
+ ret = apply_to_page_range(&init_mm, (unsigned long)v,
+ PAGE_SIZE, dealloc_pte_fn,
+ NULL);
#else
/* Cannot handle non-auto translate mode. */
ret = 1;
@@ -609,7 +621,7 @@ struct page **alloc_empty_pages_and_page
if (ret != 0) {
balloon_unlock(flags);
- __free_page(page);
+ balloon_free_page(page);
goto err;
}
diff -r 3b73a079c1fb -r 9dcb40286ad4 include/asm-i386/mach-xen/asm/hypervisor.h
--- a/include/asm-i386/mach-xen/asm/hypervisor.h Mon Feb 11 09:52:01
2008 +0000
+++ b/include/asm-i386/mach-xen/asm/hypervisor.h Mon Feb 11 09:52:49
2008 +0000
@@ -130,7 +130,7 @@ u64 jiffies_to_st(unsigned long jiffies)
u64 jiffies_to_st(unsigned long jiffies);
#ifdef CONFIG_XEN_SCRUB_PAGES
-#define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
+void scrub_pages(void *, unsigned int);
#else
#define scrub_pages(_p,_n) ((void)0)
#endif
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|