aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/slub_def.h9
-rw-r--r--mm/slab.h1
-rw-r--r--mm/slab_common.c13
-rw-r--r--mm/slub.c30
4 files changed, 29 insertions, 24 deletions
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index f2f7398848cf..d82abd40a3c0 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -101,4 +101,13 @@ struct kmem_cache {
101 struct kmem_cache_node *node[MAX_NUMNODES]; 101 struct kmem_cache_node *node[MAX_NUMNODES];
102}; 102};
103 103
104#ifdef CONFIG_SYSFS
105#define SLAB_SUPPORTS_SYSFS
106void sysfs_slab_remove(struct kmem_cache *);
107#else
108static inline void sysfs_slab_remove(struct kmem_cache *s)
109{
110}
111#endif
112
104#endif /* _LINUX_SLUB_DEF_H */ 113#endif /* _LINUX_SLUB_DEF_H */
diff --git a/mm/slab.h b/mm/slab.h
index 3045316b7c9d..6bd4c353704f 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -91,6 +91,7 @@ __kmem_cache_alias(const char *name, size_t size, size_t align,
91#define CACHE_CREATE_MASK (SLAB_CORE_FLAGS | SLAB_DEBUG_FLAGS | SLAB_CACHE_FLAGS) 91#define CACHE_CREATE_MASK (SLAB_CORE_FLAGS | SLAB_DEBUG_FLAGS | SLAB_CACHE_FLAGS)
92 92
93int __kmem_cache_shutdown(struct kmem_cache *); 93int __kmem_cache_shutdown(struct kmem_cache *);
94void slab_kmem_cache_release(struct kmem_cache *);
94 95
95struct seq_file; 96struct seq_file;
96struct file; 97struct file;
diff --git a/mm/slab_common.c b/mm/slab_common.c
index f3cfccf76dda..102cc6fca3d3 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -323,6 +323,12 @@ static int kmem_cache_destroy_memcg_children(struct kmem_cache *s)
323} 323}
324#endif /* CONFIG_MEMCG_KMEM */ 324#endif /* CONFIG_MEMCG_KMEM */
325 325
326void slab_kmem_cache_release(struct kmem_cache *s)
327{
328 kfree(s->name);
329 kmem_cache_free(kmem_cache, s);
330}
331
326void kmem_cache_destroy(struct kmem_cache *s) 332void kmem_cache_destroy(struct kmem_cache *s)
327{ 333{
328 get_online_cpus(); 334 get_online_cpus();
@@ -352,8 +358,11 @@ void kmem_cache_destroy(struct kmem_cache *s)
352 rcu_barrier(); 358 rcu_barrier();
353 359
354 memcg_free_cache_params(s); 360 memcg_free_cache_params(s);
355 kfree(s->name); 361#ifdef SLAB_SUPPORTS_SYSFS
356 kmem_cache_free(kmem_cache, s); 362 sysfs_slab_remove(s);
363#else
364 slab_kmem_cache_release(s);
365#endif
357 goto out_put_cpus; 366 goto out_put_cpus;
358 367
359out_unlock: 368out_unlock:
diff --git a/mm/slub.c b/mm/slub.c
index 042a47b4d0f5..2b1ce697fc4b 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -210,14 +210,11 @@ enum track_item { TRACK_ALLOC, TRACK_FREE };
210#ifdef CONFIG_SYSFS 210#ifdef CONFIG_SYSFS
211static int sysfs_slab_add(struct kmem_cache *); 211static int sysfs_slab_add(struct kmem_cache *);
212static int sysfs_slab_alias(struct kmem_cache *, const char *); 212static int sysfs_slab_alias(struct kmem_cache *, const char *);
213static void sysfs_slab_remove(struct kmem_cache *);
214static void memcg_propagate_slab_attrs(struct kmem_cache *s); 213static void memcg_propagate_slab_attrs(struct kmem_cache *s);
215#else 214#else
216static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; } 215static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
217static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p) 216static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
218 { return 0; } 217 { return 0; }
219static inline void sysfs_slab_remove(struct kmem_cache *s) { }
220
221static inline void memcg_propagate_slab_attrs(struct kmem_cache *s) { } 218static inline void memcg_propagate_slab_attrs(struct kmem_cache *s) { }
222#endif 219#endif
223 220
@@ -3238,24 +3235,7 @@ static inline int kmem_cache_close(struct kmem_cache *s)
3238 3235
3239int __kmem_cache_shutdown(struct kmem_cache *s) 3236int __kmem_cache_shutdown(struct kmem_cache *s)
3240{ 3237{
3241 int rc = kmem_cache_close(s); 3238 return kmem_cache_close(s);
3242
3243 if (!rc) {
3244 /*
3245 * Since slab_attr_store may take the slab_mutex, we should
3246 * release the lock while removing the sysfs entry in order to
3247 * avoid a deadlock. Because this is pretty much the last
3248 * operation we do and the lock will be released shortly after
3249 * that in slab_common.c, we could just move sysfs_slab_remove
3250 * to a later point in common code. We should do that when we
3251 * have a common sysfs framework for all allocators.
3252 */
3253 mutex_unlock(&slab_mutex);
3254 sysfs_slab_remove(s);
3255 mutex_lock(&slab_mutex);
3256 }
3257
3258 return rc;
3259} 3239}
3260 3240
3261/******************************************************************** 3241/********************************************************************
@@ -5122,6 +5102,11 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s)
5122#endif 5102#endif
5123} 5103}
5124 5104
5105static void kmem_cache_release(struct kobject *k)
5106{
5107 slab_kmem_cache_release(to_slab(k));
5108}
5109
5125static const struct sysfs_ops slab_sysfs_ops = { 5110static const struct sysfs_ops slab_sysfs_ops = {
5126 .show = slab_attr_show, 5111 .show = slab_attr_show,
5127 .store = slab_attr_store, 5112 .store = slab_attr_store,
@@ -5129,6 +5114,7 @@ static const struct sysfs_ops slab_sysfs_ops = {
5129 5114
5130static struct kobj_type slab_ktype = { 5115static struct kobj_type slab_ktype = {
5131 .sysfs_ops = &slab_sysfs_ops, 5116 .sysfs_ops = &slab_sysfs_ops,
5117 .release = kmem_cache_release,
5132}; 5118};
5133 5119
5134static int uevent_filter(struct kset *kset, struct kobject *kobj) 5120static int uevent_filter(struct kset *kset, struct kobject *kobj)
@@ -5255,7 +5241,7 @@ out_put_kobj:
5255 goto out; 5241 goto out;
5256} 5242}
5257 5243
5258static void sysfs_slab_remove(struct kmem_cache *s) 5244void sysfs_slab_remove(struct kmem_cache *s)
5259{ 5245{
5260 if (slab_state < FULL) 5246 if (slab_state < FULL)
5261 /* 5247 /*