Index: linux-2.6.20-rc1/include/linux/slub_def.h =================================================================== --- linux-2.6.20-rc1.orig/include/linux/slub_def.h 2006-12-15 19:24:35.000000000 -0800 +++ linux-2.6.20-rc1/include/linux/slub_def.h 2006-12-15 19:28:17.000000000 -0800 @@ -35,6 +35,7 @@ struct list_head partial; unsigned long nr_partial; atomic_long_t nr_slabs; /* Total slabs used */ + struct page *page; } ____cacheline_aligned_in_smp; /* Index: linux-2.6.20-rc1/mm/slub.c =================================================================== --- linux-2.6.20-rc1.orig/mm/slub.c 2006-12-15 19:19:20.000000000 -0800 +++ linux-2.6.20-rc1/mm/slub.c 2006-12-15 19:36:37.000000000 -0800 @@ -704,10 +704,15 @@ void **object; struct page *page; unsigned long flags; + struct node_slab *n; local_irq_save(flags); - page = get_partial(s, gfpflags, node); - if (unlikely(!page)) { + n = NODE_INFO(s, node); + if (likely(n->page)) + goto got_page; + + n->page = get_partial(s, gfpflags, node); + if (unlikely(!n->page)) { struct page *page; page = new_slab(s, gfpflags, node); @@ -725,12 +730,19 @@ object = page_address(page); goto out; } - slab_lock(page); - } - object = page->freelist; - page->freelist = object[page->offset]; - page->inuse++; - putback_slab(s, page); + + if (a->page) + discard_slab(page); + else + a->page = page; + + slab_lock(n->page); + } +got_page: + object = n->page->freelist; + n->page->freelist = object[n->page->offset]; + n->page->inuse++; + putback_slab(s, n->page); out: local_irq_restore(flags); return object; @@ -1039,6 +1051,7 @@ #endif spin_lock_init(&n->list_lock); INIT_LIST_HEAD(&n->partial); + n->page = NULL; if (page) { putback_slab(s, page); atomic_long_set(&n->nr_slabs, 1);