|
@@ -210,14 +210,11 @@ enum track_item { TRACK_ALLOC, TRACK_FREE };
|
|
#ifdef CONFIG_SYSFS
|
|
#ifdef CONFIG_SYSFS
|
|
static int sysfs_slab_add(struct kmem_cache *);
|
|
static int sysfs_slab_add(struct kmem_cache *);
|
|
static int sysfs_slab_alias(struct kmem_cache *, const char *);
|
|
static int sysfs_slab_alias(struct kmem_cache *, const char *);
|
|
-static void sysfs_slab_remove(struct kmem_cache *);
|
|
|
|
static void memcg_propagate_slab_attrs(struct kmem_cache *s);
|
|
static void memcg_propagate_slab_attrs(struct kmem_cache *s);
|
|
#else
|
|
#else
|
|
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 memcg_propagate_slab_attrs(struct kmem_cache *s) { }
|
|
static inline void memcg_propagate_slab_attrs(struct kmem_cache *s) { }
|
|
#endif
|
|
#endif
|
|
|
|
|
|
@@ -3238,24 +3235,7 @@ static inline int kmem_cache_close(struct kmem_cache *s)
|
|
|
|
|
|
int __kmem_cache_shutdown(struct kmem_cache *s)
|
|
int __kmem_cache_shutdown(struct kmem_cache *s)
|
|
{
|
|
{
|
|
- int rc = kmem_cache_close(s);
|
|
|
|
-
|
|
|
|
- if (!rc) {
|
|
|
|
- /*
|
|
|
|
- * Since slab_attr_store may take the slab_mutex, we should
|
|
|
|
- * release the lock while removing the sysfs entry in order to
|
|
|
|
- * avoid a deadlock. Because this is pretty much the last
|
|
|
|
- * operation we do and the lock will be released shortly after
|
|
|
|
- * that in slab_common.c, we could just move sysfs_slab_remove
|
|
|
|
- * to a later point in common code. We should do that when we
|
|
|
|
- * have a common sysfs framework for all allocators.
|
|
|
|
- */
|
|
|
|
- mutex_unlock(&slab_mutex);
|
|
|
|
- sysfs_slab_remove(s);
|
|
|
|
- mutex_lock(&slab_mutex);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return rc;
|
|
|
|
|
|
+ return kmem_cache_close(s);
|
|
}
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
/********************************************************************
|
|
@@ -5071,15 +5051,18 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
|
|
#ifdef CONFIG_MEMCG_KMEM
|
|
#ifdef CONFIG_MEMCG_KMEM
|
|
int i;
|
|
int i;
|
|
char *buffer = NULL;
|
|
char *buffer = NULL;
|
|
|
|
+ struct kmem_cache *root_cache;
|
|
|
|
|
|
- if (!is_root_cache(s))
|
|
|
|
|
|
+ if (is_root_cache(s))
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ root_cache = s->memcg_params->root_cache;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* This mean this cache had no attribute written. Therefore, no point
|
|
* This mean this cache had no attribute written. Therefore, no point
|
|
* in copying default values around
|
|
* in copying default values around
|
|
*/
|
|
*/
|
|
- if (!s->max_attr_size)
|
|
|
|
|
|
+ if (!root_cache->max_attr_size)
|
|
return;
|
|
return;
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(slab_attrs); i++) {
|
|
for (i = 0; i < ARRAY_SIZE(slab_attrs); i++) {
|
|
@@ -5101,7 +5084,7 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
|
|
*/
|
|
*/
|
|
if (buffer)
|
|
if (buffer)
|
|
buf = buffer;
|
|
buf = buffer;
|
|
- else if (s->max_attr_size < ARRAY_SIZE(mbuf))
|
|
|
|
|
|
+ else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf))
|
|
buf = mbuf;
|
|
buf = mbuf;
|
|
else {
|
|
else {
|
|
buffer = (char *) get_zeroed_page(GFP_KERNEL);
|
|
buffer = (char *) get_zeroed_page(GFP_KERNEL);
|
|
@@ -5110,7 +5093,7 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
|
|
buf = buffer;
|
|
buf = buffer;
|
|
}
|
|
}
|
|
|
|
|
|
- attr->show(s->memcg_params->root_cache, buf);
|
|
|
|
|
|
+ attr->show(root_cache, buf);
|
|
attr->store(s, buf, strlen(buf));
|
|
attr->store(s, buf, strlen(buf));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5119,6 +5102,11 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void kmem_cache_release(struct kobject *k)
|
|
|
|
+{
|
|
|
|
+ slab_kmem_cache_release(to_slab(k));
|
|
|
|
+}
|
|
|
|
+
|
|
static const struct sysfs_ops slab_sysfs_ops = {
|
|
static const struct sysfs_ops slab_sysfs_ops = {
|
|
.show = slab_attr_show,
|
|
.show = slab_attr_show,
|
|
.store = slab_attr_store,
|
|
.store = slab_attr_store,
|
|
@@ -5126,6 +5114,7 @@ static const 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)
|
|
@@ -5252,7 +5241,7 @@ out_put_kobj:
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
-static void sysfs_slab_remove(struct kmem_cache *s)
|
|
|
|
|
|
+void sysfs_slab_remove(struct kmem_cache *s)
|
|
{
|
|
{
|
|
if (slab_state < FULL)
|
|
if (slab_state < FULL)
|
|
/*
|
|
/*
|