aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2008-01-08 01:29:05 -0500
committerChristoph Lameter <clameter@sgi.com>2008-02-04 13:56:01 -0500
commit151c602f79cb9154c3f3d83223cae355af463d6f (patch)
tree140f75b7a100c50b9d337b3a128dd34b5731780f
parente374d4835668a8c6aec7cefc0a44df69f9679017 (diff)
SLUB: Fix sysfs refcounting
If CONFIG_SYSFS is set then free the kmem_cache structure when sysfs tells us its okay. Otherwise there is the danger (as pointed out by Al Viro) that sysfs thinks the kobject still exists after kmem_cache_destroy() removed it. Signed-off-by: Christoph Lameter <clameter@sgi.com> Reviewed-by: Pekka J Enberg <penberg@cs.helsinki.fi>
-rw-r--r--mm/slub.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 93f5c288f024..65bf21dc996a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -247,7 +247,10 @@ static void sysfs_slab_remove(struct kmem_cache *);
247static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; } 247static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
248static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p) 248static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
249 { return 0; } 249 { return 0; }
250static inline void sysfs_slab_remove(struct kmem_cache *s) {} 250static inline void sysfs_slab_remove(struct kmem_cache *s)
251{
252 kfree(s);
253}
251#endif 254#endif
252 255
253/******************************************************************** 256/********************************************************************
@@ -2322,7 +2325,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
2322 if (kmem_cache_close(s)) 2325 if (kmem_cache_close(s))
2323 WARN_ON(1); 2326 WARN_ON(1);
2324 sysfs_slab_remove(s); 2327 sysfs_slab_remove(s);
2325 kfree(s);
2326 } else 2328 } else
2327 up_write(&slub_lock); 2329 up_write(&slub_lock);
2328} 2330}
@@ -3937,6 +3939,13 @@ static ssize_t slab_attr_store(struct kobject *kobj,
3937 return err; 3939 return err;
3938} 3940}
3939 3941
3942static void kmem_cache_release(struct kobject *kobj)
3943{
3944 struct kmem_cache *s = to_slab(kobj);
3945
3946 kfree(s);
3947}
3948
3940static struct sysfs_ops slab_sysfs_ops = { 3949static struct sysfs_ops slab_sysfs_ops = {
3941 .show = slab_attr_show, 3950 .show = slab_attr_show,
3942 .store = slab_attr_store, 3951 .store = slab_attr_store,
@@ -3944,6 +3953,7 @@ static struct sysfs_ops slab_sysfs_ops = {
3944 3953
3945static struct kobj_type slab_ktype = { 3954static struct kobj_type slab_ktype = {
3946 .sysfs_ops = &slab_sysfs_ops, 3955 .sysfs_ops = &slab_sysfs_ops,
3956 .release = kmem_cache_release
3947}; 3957};
3948 3958
3949static int uevent_filter(struct kset *kset, struct kobject *kobj) 3959static int uevent_filter(struct kset *kset, struct kobject *kobj)
@@ -4045,6 +4055,7 @@ static void sysfs_slab_remove(struct kmem_cache *s)
4045{ 4055{
4046 kobject_uevent(&s->kobj, KOBJ_REMOVE); 4056 kobject_uevent(&s->kobj, KOBJ_REMOVE);
4047 kobject_del(&s->kobj); 4057 kobject_del(&s->kobj);
4058 kobject_put(&s->kobj);
4048} 4059}
4049 4060
4050/* 4061/*