diff options
author | Christoph Lameter <clameter@sgi.com> | 2007-07-17 04:03:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-17 10:23:02 -0700 |
commit | a0e1d1be204612ee83b3afe8aa24c5d27e63d464 (patch) | |
tree | a32092a7eda82c84c5e195de5efd2cb6c0bff553 /mm | |
parent | 434e245ddd3f14aa8eef97cae16c71b863ab092a (diff) | |
download | linux-stable-a0e1d1be204612ee83b3afe8aa24c5d27e63d464.tar.gz linux-stable-a0e1d1be204612ee83b3afe8aa24c5d27e63d464.tar.bz2 linux-stable-a0e1d1be204612ee83b3afe8aa24c5d27e63d464.zip |
SLUB: Move sysfs operations outside of slub_lock
Sysfs can do a gazillion things when called. Make sure that we do not call
any sysfs functions while holding the slub_lock.
Just protect the essentials:
1. The list of all slab caches
2. The kmalloc_dma array
3. The ref counters of the slabs.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/slub.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/mm/slub.c b/mm/slub.c index f976d2866e73..1c5d6a068556 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2192,12 +2192,13 @@ void kmem_cache_destroy(struct kmem_cache *s) s->refcount--; if (!s->refcount) { list_del(&s->list); + up_write(&slub_lock); if (kmem_cache_close(s)) WARN_ON(1); sysfs_slab_remove(s); kfree(s); - } - up_write(&slub_lock); + } else + up_write(&slub_lock); } EXPORT_SYMBOL(kmem_cache_destroy); @@ -2679,25 +2680,26 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, */ s->objsize = max(s->objsize, (int)size); s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *))); + up_write(&slub_lock); if (sysfs_slab_alias(s, name)) goto err; - } else { - s = kmalloc(kmem_size, GFP_KERNEL); - if (s && kmem_cache_open(s, GFP_KERNEL, name, + return s; + } + s = kmalloc(kmem_size, GFP_KERNEL); + if (s) { + if (kmem_cache_open(s, GFP_KERNEL, name, size, align, flags, ctor)) { - if (sysfs_slab_add(s)) { - kfree(s); - goto err; - } list_add(&s->list, &slab_caches); - } else - kfree(s); + up_write(&slub_lock); + if (sysfs_slab_add(s)) + goto err; + return s; + } + kfree(s); } up_write(&slub_lock); - return s; err: - up_write(&slub_lock); if (flags & SLAB_PANIC) panic("Cannot create slabcache %s\n", name); else |