Index: linux-2.6.19-mm1/include/linux/slub_def.h =================================================================== --- linux-2.6.19-mm1.orig/include/linux/slub_def.h 2006-12-11 19:00:40.125861321 -0800 +++ linux-2.6.19-mm1/include/linux/slub_def.h 2006-12-11 20:11:05.264922182 -0800 @@ -137,6 +137,8 @@ static inline void *kzalloc(size_t size, } #ifdef CONFIG_NUMA +extern void *__kmalloc_node(size_t size, gfp_t flags, int node); + static inline void *kmalloc_node(size_t size, gfp_t flags, int node) { if (__builtin_constant_p(size) && !(flags & __GFP_DMA)) { Index: linux-2.6.19-mm1/include/linux/slab.h =================================================================== --- linux-2.6.19-mm1.orig/include/linux/slab.h 2006-12-11 19:00:40.117072797 -0800 +++ linux-2.6.19-mm1/include/linux/slab.h 2006-12-11 20:11:05.265898684 -0800 @@ -76,7 +76,7 @@ static inline void *kmem_cache_alloc_nod void *__kmalloc(size_t, gfp_t); void *__kzalloc(size_t, gfp_t); void kfree(const void *); -unsigned int ksize(const void *); +size_t ksize(const void *); /** * kcalloc - allocate memory for an array. The memory is set to zero. Index: linux-2.6.19-mm1/mm/slub.c =================================================================== --- linux-2.6.19-mm1.orig/mm/slub.c 2006-12-11 19:27:52.262030000 -0800 +++ linux-2.6.19-mm1/mm/slub.c 2006-12-12 14:29:53.557001242 -0800 @@ -158,7 +158,7 @@ static void rcu_free_slab(struct rcu_hea static void free_slab(struct kmem_cache *s, struct page *page) { - if (s->flags & SLAB_DESTROY_BY_RCU) { + if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) { struct rcu_head *head = (void *)&page->lru; page->mapping = (void *)s; @@ -786,7 +786,7 @@ static int calculate_order(int size) int order = fls(size) -1 - PAGE_SHIFT; if (order >= 0) - return 0; + return order; } for (order = max(slab_min_order, fls(size - 1) - PAGE_SHIFT); @@ -814,7 +814,6 @@ int kmem_cache_open(struct kmem_cache *s void (*dtor)(void *, struct kmem_cache *, unsigned long)) { int cpu; - int one_object_slab; BUG_ON(flags & SLUB_UNIMPLEMENTED); memset(s, 0, sizeof(struct kmem_cache)); @@ -833,19 +832,29 @@ int kmem_cache_open(struct kmem_cache *s s->ctor = ctor; s->dtor = dtor; s->objsize = size; + /* * Here is the place to add other management type information * to the end of the object F.e. debug info */ - size += ALIGN(size, sizeof(void *)); + size = ALIGN(size, sizeof(void *)); s->inuse = size; - if ((flags & SLAB_DESTROY_BY_RCU) || ctor || dtor) { + + if (size * 2 >= (PAGE_SIZE << calculate_order(size)) && + ((flags & SLAB_DESTROY_BY_RCU) || ctor || dtor)) { /* - * Relocate free pointer after the object if we need - * to do RCU + * Relocate free pointer after the object if it is not + * permitted to overwrite the first word of the object on + * kmem_cache_free. + * + * This is the case if we do RCU, have a constructor or + * destructor. + * + * We never need a free pointer if each slab only has + * a single object. */ - s->offset = size; + s->offset = size / sizeof(void *); size += sizeof(void *); } @@ -856,8 +865,6 @@ int kmem_cache_open(struct kmem_cache *s size = ALIGN(size, align); s->size = size; - one_object_slab = size > ((PAGE_SIZE / 2) << calculate_order(size)); - s->order = calculate_order(size); if (s->order < 0) goto error; @@ -1146,7 +1153,6 @@ static struct kmem_cache *create_kmalloc 0, NULL, NULL)) panic("Creation of kmalloc slab %s size=%d failed.\n", name, size); - register_slab(s); return s; }