[PATCH] slab: Avoid deadlock at kmem_cache_create/kmem_cache_destroy
authorRavikiran G Thirumalai <kiran@scalex86.org>
Fri, 10 Feb 2006 09:51:13 +0000 (01:51 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 10 Feb 2006 16:13:12 +0000 (08:13 -0800)
Prevents deadlock situation between
kmem_cache_create()/kmem_cache_destory(), and kmem_cache_create() /cpu
hotplug.  The locking order probably got moved over time.

Signed-off-by: Ravikiran Thirumalai <kiran@scalex86.org>
Signed-off-by: Shai Fultheim <shai@scalex86.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
mm/slab.c

index d66c2b0..add05d8 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1717,6 +1717,12 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                BUG();
        }
 
+       /*
+        * Prevent CPUs from coming and going.
+        * lock_cpu_hotplug() nests outside cache_chain_mutex
+        */
+       lock_cpu_hotplug();
+
        mutex_lock(&cache_chain_mutex);
 
        list_for_each(p, &cache_chain) {
@@ -1918,8 +1924,6 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        cachep->dtor = dtor;
        cachep->name = name;
 
-       /* Don't let CPUs to come and go */
-       lock_cpu_hotplug();
 
        if (g_cpucache_up == FULL) {
                enable_cpucache(cachep);
@@ -1978,12 +1982,12 @@ kmem_cache_create (const char *name, size_t size, size_t align,
 
        /* cache setup completed, link it into the list */
        list_add(&cachep->next, &cache_chain);
-       unlock_cpu_hotplug();
       oops:
        if (!cachep && (flags & SLAB_PANIC))
                panic("kmem_cache_create(): failed to create slab `%s'\n",
                      name);
        mutex_unlock(&cache_chain_mutex);
+       unlock_cpu_hotplug();
        return cachep;
 }
 EXPORT_SYMBOL(kmem_cache_create);