Index: linux-2.6.21-rc7/mm/slub.c =================================================================== --- linux-2.6.21-rc7.orig/mm/slub.c 2007-04-23 11:51:45.000000000 -0700 +++ linux-2.6.21-rc7/mm/slub.c 2007-04-23 13:08:09.000000000 -0700 @@ -3297,16 +3297,66 @@ static struct kset_uevent_ops slab_ueven decl_subsys(slab, &slab_ktype, &slab_uevent_ops); +#define ID_STR_LENGTH 30 + +/* Create a unique string id for a slab cache: + * format + * :[flags-]size:[memory address of kmemcache] + */ +static char *create_unique_id(struct kmem_cache *s) +{ + char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL); + char *p = name; + + BUG_ON(!name); + + *p++ = ':'; + /* + * First flags affecting slabcache operations */ + if (s->flags & SLAB_CACHE_DMA) + *p++ = 'd'; + if (s->flags & SLAB_RECLAIM_ACCOUNT) + *p++ = 'a'; + if (s->flags & SLAB_DESTROY_BY_RCU) + *p++ = 'r';\ + /* Debug flags */ + if (s->flags & SLAB_RED_ZONE) + *p++ = 'Z'; + if (s->flags & SLAB_POISON) + *p++ = 'P'; + if (s->flags & SLAB_STORE_USER) + *p++ = 'U'; + if (p != name + 1) + *p++ = '-'; + p += sprintf(p,"%06d:0x%p" ,s->size, s); + BUG_ON(p > name + ID_STR_LENGTH - 1); + return name; +} + static int sysfs_slab_add(struct kmem_cache *s) { int err; + const char *name; if (slab_state < SYSFS) /* Defer until later */ return 0; - + if (s->flags & SLUB_NEVER_MERGE) { + /* + * Slabcache can never be merged so we can use the name proper. + * This is typically the case for debug situations. In that + * case we can catch duplicate names easily. + */ + sysfs_remove_link(&slab_subsys.kset.kobj, s->name); + name = s->name; + } else + /* + * Create a unique name for the slab as a target + * for the symlinks. + */ + name = create_unique_id(s); kobj_set_kset_s(s, slab_subsys); - kobject_set_name(&s->kobj, s->name); + kobject_set_name(&s->kobj, name); kobject_init(&s->kobj); err = kobject_add(&s->kobj); if (err) @@ -3316,6 +3366,8 @@ static int sysfs_slab_add(struct kmem_ca if (err) return err; kobject_uevent(&s->kobj, KOBJ_ADD); + if (!(s->flags & SLUB_NEVER_MERGE)) + sysfs_slab_alias(s, s->name); return 0; } @@ -3341,9 +3393,14 @@ static int sysfs_slab_alias(struct kmem_ { struct saved_alias *al; - if (slab_state == SYSFS) + if (slab_state == SYSFS) { + /* + * If we have a leftover link then remove it. + */ + sysfs_remove_link(&slab_subsys.kset.kobj, name); return sysfs_create_link(&slab_subsys.kset.kobj, &s->kobj, name); + } al = kmalloc(sizeof(struct saved_alias), GFP_KERNEL); if (!al)