Index: linux-2.6.21-rc1/include/linux/slab.h =================================================================== --- linux-2.6.21-rc1.orig/include/linux/slab.h 2007-02-26 13:50:38.000000000 -0800 +++ linux-2.6.21-rc1/include/linux/slab.h 2007-02-26 13:51:01.000000000 -0800 @@ -32,6 +32,7 @@ #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */ #define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */ #define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */ +#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */ /* Flags passed to a constructor functions */ #define SLAB_CTOR_CONSTRUCTOR 0x001UL /* If not set, then deconstructor */ Index: linux-2.6.21-rc1/mm/slub.c =================================================================== --- linux-2.6.21-rc1.orig/mm/slub.c 2007-02-26 13:51:05.000000000 -0800 +++ linux-2.6.21-rc1/mm/slub.c 2007-02-26 14:53:16.000000000 -0800 @@ -50,8 +50,7 @@ /* * Flags from the regular SLAB that SLUB does not support: */ -#define SLUB_UNIMPLEMENTED (SLAB_DEBUG_INITIAL | \ - SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER) +#define SLUB_UNIMPLEMENTED (SLAB_DEBUG_INITIAL | SLAB_STORE_USER) #define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \ SLAB_STORE_USER | SLAB_POISON) @@ -59,7 +58,8 @@ * Set of flags that will prevent slab merging */ #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \ - SLAB_DESTROY_BY_RCU | SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA) + SLAB_DESTROY_BY_RCU | SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \ + SLAB_TRACE) #ifndef ARCH_KMALLOC_MINALIGN #define ARCH_KMALLOC_MINALIGN sizeof(void *) @@ -249,7 +249,6 @@ static void init_object(struct kmem_cache *s, void *object, int active) { -#if 0 u8 *p = object; if (s->flags & SLAB_POISON) { @@ -261,7 +260,6 @@ memset(p + s->objsize, active ? RED_ACTIVE : RED_INACTIVE, s->inuse - s->objsize); -#endif } static int check_bytes(u8 *start, unsigned int value, unsigned int bytes) @@ -278,7 +276,6 @@ static int check_object(struct kmem_cache *s, struct page *page, void *object, int active) { -#if 0 u8 *p = object; if (s->flags & SLAB_RED_ZONE) @@ -294,7 +291,6 @@ object_err(s, page, p, "Poison"); return 0; } -#endif return 1; } @@ -556,7 +552,7 @@ page->slab = s; page->flags |= 1 << PG_slab; if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON | - SLAB_STORE_USER) || s->objects == 1) + SLAB_STORE_USER | SLAB_TRACE) || s->objects == 1) page->flags |= 1 << PG_error; if (s->objects > 1) { @@ -739,6 +735,13 @@ if (!check_object(s, page, object, 0)) dump_stack(); init_object(s, object, 1); + if (s->flags & SLAB_TRACE) { + printk("SLUB-Trace %s alloc node=%d gfp=%4lx " + "object=%p slab=%p inuse=%d freelist=%p\n", + s->name, node, (unsigned long)gfpflags, + object, page, page->inuse, page->freelist); + dump_stack(); + } } return object; @@ -830,6 +833,14 @@ goto dumpret; if (!check_object(s, page, object, 1)) goto dumpret; + if (s->flags & SLAB_TRACE) { + printk("SLUB-Trace %s free object=%p slab=%p" + "inuse=%d freelist=%p\n", + s->name, object, page, page->inuse, + page->freelist); + print_section("SLUB-Trace", x, min(s->objsize, 128)); + dump_stack(); + } init_object(s, object, 0); } @@ -1091,12 +1102,9 @@ /* Enable debugging if selected on the kernel commandline */ if (slub_debug && (!slub_debug_slabs || strncmp(slub_debug_slabs, name, - strlen(slub_debug_slabs) == 0))) + strlen(slub_debug_slabs)) == 0)) flags |= slub_debug; - printk("kmem_cache_open %s slub_debug=%lx slub_debug_slabs=%s flags=%lx\n", name, - slub_debug,slub_debug_slabs, flags); - s->name = name; s->ctor = ctor; s->dtor = dtor; @@ -1349,12 +1357,11 @@ static int __init setup_slub_debug(char *str) { - if (!str) + if (!str || *str != '=') slub_debug = DEBUG_DEFAULT_FLAGS; - else - if (*str == '=') { + else { str++; - if (!*str || *str == ',') + if (*str == 0 || *str == ',') slub_debug = DEBUG_DEFAULT_FLAGS; else for( ;str && *str != ','; str++) @@ -1363,13 +1370,14 @@ case 'z' : case 'Z' : slub_debug |= SLAB_RED_ZONE;break; case 'p' : case 'P' : slub_debug |= SLAB_POISON;break; case 'u' : case 'U' : slub_debug |= SLAB_STORE_USER;break; + case 't' : case 'T' : slub_debug |= SLAB_TRACE;break; default: printk(KERN_CRIT "slub_debug option '%c' unknown. skipped\n",*str); } } + if (*str == ',') slub_debug_slabs = str + 1; - printk("setup_slub_debug slub_debug=%lx slub_debug_slabs=%s\n", slub_debug,slub_debug_slabs); return 1; } @@ -1760,6 +1768,8 @@ *d++ = 'Z'; if (s->flags & SLAB_POISON) *d++ = 'P'; + if (s->flags & SLAB_TRACE) + *d++ = 'T'; *d = 0;