On Mon, 21 May 2012, Glauber Costa wrote:
diff --git a/mm/slab.c b/mm/slab.c
index e901a36..cabd217 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2118,6 +2118,7 @@ static void __kmem_cache_destroy(struct kmem_cache *cachep)
kfree(l3);
}
}
+ kfree(cachep->name);
kmem_cache_free(&cache_cache, cachep);
}
@@ -2526,9 +2527,14 @@ kmem_cache_create (const char *name, size_t size, size_t align,
BUG_ON(ZERO_OR_NULL_PTR(cachep->slabp_cache));
}
cachep->ctor = ctor;
- cachep->name = name;
- if (setup_cpu_cache(cachep, gfp)) {
+ /* Can't do strdup while kmalloc is not up */
+ if (g_cpucache_up> EARLY)
+ cachep->name = kstrdup(name, GFP_KERNEL);
+ else
+ cachep->name = name;
+
+ if (!cachep->name || setup_cpu_cache(cachep, gfp)) {
__kmem_cache_destroy(cachep);
cachep = NULL;
goto oops;
This doesn't work if you kmem_cache_destroy() a cache that was created
when g_cpucache_cpu<= EARLY, the kfree() will explode. That never
happens for any existing cache created in kmem_cache_init(), but this
would introduce the first roadblock in doing so. So you'll need some
magic to determine whether the cache was allocated statically and suppress
the kfree() in such a case.