aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slub.c
diff options
context:
space:
mode:
authorChristoph Lameter <cl@linux-foundation.org>2010-07-19 12:39:11 -0400
committerPekka Enberg <penberg@cs.helsinki.fi>2010-08-03 00:28:32 -0400
commit2bce64858442149784f6c8803c9095a8556320a2 (patch)
treef9a097d8da73f33703622d8ef4237997248b6f39 /mm/slub.c
parente438444de82f354563d46ee5d991b5916dd19b01 (diff)
slub: Allow removal of slab caches during boot
Serialize kmem_cache_create and kmem_cache_destroy using the slub_lock. Only possible after the use of the slub_lock during dynamic dma creation has been removed. Then make sure that the setup of the slab sysfs entries does not race with kmem_cache_create and kmem_cache destroy. If a slab cache is removed before we have setup sysfs then simply skip over the sysfs handling. Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Roland Dreier <rdreier@cisco.com> Signed-off-by: Christoph Lameter <cl@linux-foundation.org> Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/mm/slub.c b/mm/slub.c
index f0f403693bd9..fb6518efe1ed 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2491,7 +2491,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
2491 s->refcount--; 2491 s->refcount--;
2492 if (!s->refcount) { 2492 if (!s->refcount) {
2493 list_del(&s->list); 2493 list_del(&s->list);
2494 up_write(&slub_lock);
2495 if (kmem_cache_close(s)) { 2494 if (kmem_cache_close(s)) {
2496 printk(KERN_ERR "SLUB %s: %s called for cache that " 2495 printk(KERN_ERR "SLUB %s: %s called for cache that "
2497 "still has objects.\n", s->name, __func__); 2496 "still has objects.\n", s->name, __func__);
@@ -2500,8 +2499,8 @@ void kmem_cache_destroy(struct kmem_cache *s)
2500 if (s->flags & SLAB_DESTROY_BY_RCU) 2499 if (s->flags & SLAB_DESTROY_BY_RCU)
2501 rcu_barrier(); 2500 rcu_barrier();
2502 sysfs_slab_remove(s); 2501 sysfs_slab_remove(s);
2503 } else 2502 }
2504 up_write(&slub_lock); 2503 up_write(&slub_lock);
2505} 2504}
2506EXPORT_SYMBOL(kmem_cache_destroy); 2505EXPORT_SYMBOL(kmem_cache_destroy);
2507 2506
@@ -3227,14 +3226,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
3227 */ 3226 */
3228 s->objsize = max(s->objsize, (int)size); 3227 s->objsize = max(s->objsize, (int)size);
3229 s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *))); 3228 s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
3230 up_write(&slub_lock);
3231 3229
3232 if (sysfs_slab_alias(s, name)) { 3230 if (sysfs_slab_alias(s, name)) {
3233 down_write(&slub_lock);
3234 s->refcount--; 3231 s->refcount--;
3235 up_write(&slub_lock);
3236 goto err; 3232 goto err;
3237 } 3233 }
3234 up_write(&slub_lock);
3238 return s; 3235 return s;
3239 } 3236 }
3240 3237
@@ -3243,14 +3240,12 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
3243 if (kmem_cache_open(s, GFP_KERNEL, name, 3240 if (kmem_cache_open(s, GFP_KERNEL, name,
3244 size, align, flags, ctor)) { 3241 size, align, flags, ctor)) {
3245 list_add(&s->list, &slab_caches); 3242 list_add(&s->list, &slab_caches);
3246 up_write(&slub_lock);
3247 if (sysfs_slab_add(s)) { 3243 if (sysfs_slab_add(s)) {
3248 down_write(&slub_lock);
3249 list_del(&s->list); 3244 list_del(&s->list);
3250 up_write(&slub_lock);
3251 kfree(s); 3245 kfree(s);
3252 goto err; 3246 goto err;
3253 } 3247 }
3248 up_write(&slub_lock);
3254 return s; 3249 return s;
3255 } 3250 }
3256 kfree(s); 3251 kfree(s);
@@ -4498,6 +4493,13 @@ static int sysfs_slab_add(struct kmem_cache *s)
4498 4493
4499static void sysfs_slab_remove(struct kmem_cache *s) 4494static void sysfs_slab_remove(struct kmem_cache *s)
4500{ 4495{
4496 if (slab_state < SYSFS)
4497 /*
4498 * Sysfs has not been setup yet so no need to remove the
4499 * cache from sysfs.
4500 */
4501 return;
4502
4501 kobject_uevent(&s->kobj, KOBJ_REMOVE); 4503 kobject_uevent(&s->kobj, KOBJ_REMOVE);
4502 kobject_del(&s->kobj); 4504 kobject_del(&s->kobj);
4503 kobject_put(&s->kobj); 4505 kobject_put(&s->kobj);
@@ -4543,8 +4545,11 @@ static int __init slab_sysfs_init(void)
4543 struct kmem_cache *s; 4545 struct kmem_cache *s;
4544 int err; 4546 int err;
4545 4547
4548 down_write(&slub_lock);
4549
4546 slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj); 4550 slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);
4547 if (!slab_kset) { 4551 if (!slab_kset) {
4552 up_write(&slub_lock);
4548 printk(KERN_ERR "Cannot register slab subsystem.\n"); 4553 printk(KERN_ERR "Cannot register slab subsystem.\n");
4549 return -ENOSYS; 4554 return -ENOSYS;
4550 } 4555 }
@@ -4569,6 +4574,7 @@ static int __init slab_sysfs_init(void)
4569 kfree(al); 4574 kfree(al);
4570 } 4575 }
4571 4576
4577 up_write(&slub_lock);
4572 resiliency_test(); 4578 resiliency_test();
4573 return 0; 4579 return 0;
4574} 4580}