[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] xen balloon: allocate and free cold pages



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.