diff options
author | Christoph Lameter <cl@linux.com> | 2012-07-07 00:25:13 +0400 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-07-09 13:13:42 +0400 |
commit | 20cea9683ecc6dd75a80c0dd02dc69c64e95be75 (patch) | |
tree | c52994730d2d280f9300197cc4f561b15e3dd4b2 /mm/slab_common.c | |
parent | 18004c5d4084d965aa1396392706b8688306427a (diff) | |
download | linux-20cea9683ecc6dd75a80c0dd02dc69c64e95be75.tar.xz |
mm, sl[aou]b: Move kmem_cache_create mutex handling to common code
Move the mutex handling into the common kmem_cache_create()
function.
Then we can also move more checks out of SLAB's kmem_cache_create()
into the common code.
Reviewed-by: Glauber Costa <glommer@parallels.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm/slab_common.c')
-rw-r--r-- | mm/slab_common.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/mm/slab_common.c b/mm/slab_common.c index 50e1ff10bff9..12637cee1f95 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -11,7 +11,8 @@ #include <linux/memory.h> #include <linux/compiler.h> #include <linux/module.h> - +#include <linux/cpu.h> +#include <linux/uaccess.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/page.h> @@ -61,8 +62,46 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align } #endif + get_online_cpus(); + mutex_lock(&slab_mutex); + +#ifdef CONFIG_DEBUG_VM + list_for_each_entry(s, &slab_caches, list) { + char tmp; + int res; + + /* + * This happens when the module gets unloaded and doesn't + * destroy its slab cache and no-one else reuses the vmalloc + * area of the module. Print a warning. + */ + res = probe_kernel_address(s->name, tmp); + if (res) { + printk(KERN_ERR + "Slab cache with size %d has lost its name\n", + s->object_size); + continue; + } + + if (!strcmp(s->name, name)) { + printk(KERN_ERR "kmem_cache_create(%s): Cache name" + " already exists.\n", + name); + dump_stack(); + s = NULL; + goto oops; + } + } + + WARN_ON(strchr(name, ' ')); /* It confuses parsers */ +#endif + s = __kmem_cache_create(name, size, align, flags, ctor); +oops: + mutex_unlock(&slab_mutex); + put_online_cpus(); + #ifdef CONFIG_DEBUG_VM out: #endif |