mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
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>
This commit is contained in:
parent
e374d48356
commit
151c602f79
1 changed files with 13 additions and 2 deletions
15
mm/slub.c
15
mm/slub.c
|
@ -247,7 +247,10 @@ static void sysfs_slab_remove(struct kmem_cache *);
|
||||||
static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
|
static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
|
||||||
static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
|
static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
static inline void sysfs_slab_remove(struct kmem_cache *s) {}
|
static inline void sysfs_slab_remove(struct kmem_cache *s)
|
||||||
|
{
|
||||||
|
kfree(s);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
|
@ -2322,7 +2325,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
|
||||||
if (kmem_cache_close(s))
|
if (kmem_cache_close(s))
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
sysfs_slab_remove(s);
|
sysfs_slab_remove(s);
|
||||||
kfree(s);
|
|
||||||
} else
|
} else
|
||||||
up_write(&slub_lock);
|
up_write(&slub_lock);
|
||||||
}
|
}
|
||||||
|
@ -3937,6 +3939,13 @@ static ssize_t slab_attr_store(struct kobject *kobj,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void kmem_cache_release(struct kobject *kobj)
|
||||||
|
{
|
||||||
|
struct kmem_cache *s = to_slab(kobj);
|
||||||
|
|
||||||
|
kfree(s);
|
||||||
|
}
|
||||||
|
|
||||||
static struct sysfs_ops slab_sysfs_ops = {
|
static struct sysfs_ops slab_sysfs_ops = {
|
||||||
.show = slab_attr_show,
|
.show = slab_attr_show,
|
||||||
.store = slab_attr_store,
|
.store = slab_attr_store,
|
||||||
|
@ -3944,6 +3953,7 @@ static struct sysfs_ops slab_sysfs_ops = {
|
||||||
|
|
||||||
static struct kobj_type slab_ktype = {
|
static struct kobj_type slab_ktype = {
|
||||||
.sysfs_ops = &slab_sysfs_ops,
|
.sysfs_ops = &slab_sysfs_ops,
|
||||||
|
.release = kmem_cache_release
|
||||||
};
|
};
|
||||||
|
|
||||||
static int uevent_filter(struct kset *kset, struct kobject *kobj)
|
static int uevent_filter(struct kset *kset, struct kobject *kobj)
|
||||||
|
@ -4045,6 +4055,7 @@ static void sysfs_slab_remove(struct kmem_cache *s)
|
||||||
{
|
{
|
||||||
kobject_uevent(&s->kobj, KOBJ_REMOVE);
|
kobject_uevent(&s->kobj, KOBJ_REMOVE);
|
||||||
kobject_del(&s->kobj);
|
kobject_del(&s->kobj);
|
||||||
|
kobject_put(&s->kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue