--- include/linux/quicklist.h | 11 ++++++++--- include/linux/slub_def.h | 2 +- mm/Kconfig | 2 +- mm/Makefile | 2 +- mm/slub.c | 14 +++++++++++--- 5 files changed, 22 insertions(+), 9 deletions(-) Index: linux-2.6/include/linux/quicklist.h =================================================================== --- linux-2.6.orig/include/linux/quicklist.h 2008-02-09 18:49:13.819403118 -0800 +++ linux-2.6/include/linux/quicklist.h 2008-02-09 19:12:31.838027627 -0800 @@ -11,14 +11,16 @@ #include #include -#ifdef CONFIG_QUICKLIST +#if defined(CONFIG_QUICKLIST) || defined(CONFIG_SLUB) struct quicklist { void *page; int nr_pages; }; -DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK]; +#define QUICK_SLUB CONFIG_NR_QUICK + +DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK + 1]; /* * The two key functions quicklist_alloc and quicklist_free are inline so @@ -43,8 +45,11 @@ static inline void *quicklist_alloc(int q->nr_pages--; } put_cpu_var(quicklist); - if (likely(p)) + if (likely(p)) { + if (nr == QUICK_SLUB) + memset(p, 0, PAGE_SIZE); return p; + } p = (void *)__get_free_page(flags | __GFP_ZERO); if (ctor && p) Index: linux-2.6/include/linux/slub_def.h =================================================================== --- linux-2.6.orig/include/linux/slub_def.h 2008-02-09 18:49:13.811402799 -0800 +++ linux-2.6/include/linux/slub_def.h 2008-02-09 19:11:13.141643394 -0800 @@ -190,7 +190,7 @@ void *__kmalloc(size_t size, gfp_t flags static __always_inline void *kmalloc(size_t size, gfp_t flags) { - if (__builtin_constant_p(size)) { + if (__builtin_constant_p(size) && size != PAGE_SIZE) { if (size > PAGE_SIZE / 2) return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size)); Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2008-02-09 18:49:13.791403053 -0800 +++ linux-2.6/mm/slub.c 2008-02-09 19:12:09.969920155 -0800 @@ -21,6 +21,7 @@ #include #include #include +#include /* * Lock order: @@ -2670,9 +2671,13 @@ void *__kmalloc(size_t size, gfp_t flags { struct kmem_cache *s; - if (unlikely(size > PAGE_SIZE / 2)) - return (void *)__get_free_pages(flags | __GFP_COMP, + if (unlikely(size > PAGE_SIZE / 2)) { + if (size == PAGE_SIZE) + return quicklist_alloc(QUICK_SLUB, flags, NULL); + else + return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size)); + } s = get_slab(size, flags); @@ -2752,7 +2757,10 @@ void kfree(const void *x) page = virt_to_head_page(x); if (unlikely(!PageSlab(page))) { - put_page(page); + if (!PageHead(page)) + quicklist_free(QUICK_SLUB, NULL, x); + else + put_page(page); return; } slab_free(page->slab, page, object, __builtin_return_address(0)); Index: linux-2.6/mm/Kconfig =================================================================== --- linux-2.6.orig/mm/Kconfig 2008-02-09 18:49:13.803403160 -0800 +++ linux-2.6/mm/Kconfig 2008-02-09 18:59:08.162171366 -0800 @@ -186,7 +186,7 @@ config BOUNCE config NR_QUICK int - depends on QUICKLIST + depends on QUICKLIST || SLUB default "2" if SUPERH default "1" Index: linux-2.6/mm/Makefile =================================================================== --- linux-2.6.orig/mm/Makefile 2008-02-09 19:16:22.535191553 -0800 +++ linux-2.6/mm/Makefile 2008-02-09 19:16:58.463362104 -0800 @@ -11,7 +11,7 @@ obj-y := bootmem.o filemap.o mempool.o page_alloc.o page-writeback.o pdflush.o \ readahead.o swap.o truncate.o vmscan.o \ prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ - page_isolation.o $(mmu-y) + page_isolation.o $(mmu-y) quicklist.o obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o obj-$(CONFIG_BOUNCE) += bounce.o