[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] linux: 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). As usual, written and tested on 2.6.24 and made apply to the 2.6.18 tree without further testing. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> Index: head-2008-01-28/arch/i386/lib/Makefile =================================================================== --- head-2008-01-28.orig/arch/i386/lib/Makefile 2008-01-24 23:58:37.000000000 +0100 +++ head-2008-01-28/arch/i386/lib/Makefile 2008-02-08 10:46:49.000000000 +0100 @@ -7,3 +7,4 @@ include ${srctree}/arch/x86/lib/Makefile bitops.o lib-$(CONFIG_X86_USE_3DNOW) += mmx.o +lib-$(CONFIG_XEN_SCRUB_PAGES) += scrub.o Index: head-2008-01-28/arch/i386/lib/scrub.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ head-2008-01-28/arch/i386/lib/scrub.c 2008-02-08 12:30:51.000000000 +0100 @@ -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); +} Index: head-2008-01-28/arch/i386/mm/hypervisor.c =================================================================== --- head-2008-01-28.orig/arch/i386/mm/hypervisor.c 2008-02-08 14:29:22.000000000 +0100 +++ head-2008-01-28/arch/i386/mm/hypervisor.c 2008-02-08 11:30:34.000000000 +0100 @@ -281,7 +281,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); @@ -374,7 +374,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); Index: head-2008-01-28/arch/x86_64/lib/Makefile =================================================================== --- head-2008-01-28.orig/arch/x86_64/lib/Makefile 2008-01-24 23:58:37.000000000 +0100 +++ head-2008-01-28/arch/x86_64/lib/Makefile 2008-02-08 10:46:49.000000000 +0100 @@ -10,3 +10,4 @@ include ${srctree}/arch/x86/lib/Makefile 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 Index: head-2008-01-28/arch/x86_64/lib/scrub.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ head-2008-01-28/arch/x86_64/lib/scrub.c 2008-02-08 12:30:51.000000000 +0100 @@ -0,0 +1,1 @@ +#include "../../i386/lib/scrub.c" Index: head-2008-01-28/drivers/xen/balloon/balloon.c =================================================================== --- head-2008-01-28.orig/drivers/xen/balloon/balloon.c 2008-02-08 14:29:22.000000000 +0100 +++ head-2008-01-28/drivers/xen/balloon/balloon.c 2008-02-08 14:29:36.000000000 +0100 @@ -105,7 +105,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) @@ -175,6 +175,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); @@ -292,7 +303,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; @@ -623,7 +634,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; @@ -632,13 +644,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); @@ -656,8 +667,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; @@ -668,7 +679,7 @@ struct page **alloc_empty_pages_and_page if (ret != 0) { balloon_unlock(flags); - __free_page(page); + balloon_free_page(page); goto err; } Index: head-2008-01-28/include/asm-i386/mach-xen/asm/hypervisor.h =================================================================== --- head-2008-01-28.orig/include/asm-i386/mach-xen/asm/hypervisor.h 2008-02-08 14:29:22.000000000 +0100 +++ head-2008-01-28/include/asm-i386/mach-xen/asm/hypervisor.h 2008-02-08 10:42:13.000000000 +0100 @@ -121,7 +121,7 @@ int xen_limit_pages_to_max_mfn( 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-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |