Skip to content

Commit 9a41707

Browse files
Vladimir Davydovtorvalds
authored andcommitted
slub: rework sysfs layout for memcg caches
Currently, we try to arrange sysfs entries for memcg caches in the same manner as for global caches. Apart from turning /sys/kernel/slab into a mess when there are a lot of kmem-active memcgs created, it actually does not work properly - we won't create more than one link to a memcg cache in case its parent is merged with another cache. For instance, if A is a root cache merged with another root cache B, we will have the following sysfs setup: X A -> X B -> X where X is some unique id (see create_unique_id()). Now if memcgs M and N start to allocate from cache A (or B, which is the same), we will get: X X:M X:N A -> X B -> X A:M -> X:M A:N -> X:N Since B is an alias for A, we won't get entries B:M and B:N, which is confusing. It is more logical to have entries for memcg caches under the corresponding root cache's sysfs directory. This would allow us to keep sysfs layout clean, and avoid such inconsistencies like one described above. This patch does the trick. It creates a "cgroup" kset in each root cache kobject to keep its children caches there. Signed-off-by: Vladimir Davydov <vdavydov@parallels.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: David Rientjes <rientjes@google.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: Glauber Costa <glommer@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 84d0ddd commit 9a41707

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

include/linux/slub_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ struct kmem_cache {
8787
#ifdef CONFIG_MEMCG_KMEM
8888
struct memcg_cache_params *memcg_params;
8989
int max_attr_size; /* for propagation, maximum size of a stored attr */
90+
#ifdef CONFIG_SYSFS
91+
struct kset *memcg_kset;
92+
#endif
9093
#endif
9194

9295
#ifdef CONFIG_NUMA

mm/slub.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5138,6 +5138,15 @@ static const struct kset_uevent_ops slab_uevent_ops = {
51385138

51395139
static struct kset *slab_kset;
51405140

5141+
static inline struct kset *cache_kset(struct kmem_cache *s)
5142+
{
5143+
#ifdef CONFIG_MEMCG_KMEM
5144+
if (!is_root_cache(s))
5145+
return s->memcg_params->root_cache->memcg_kset;
5146+
#endif
5147+
return slab_kset;
5148+
}
5149+
51415150
#define ID_STR_LENGTH 64
51425151

51435152
/* Create a unique string id for a slab cache:
@@ -5203,7 +5212,7 @@ static int sysfs_slab_add(struct kmem_cache *s)
52035212
name = create_unique_id(s);
52045213
}
52055214

5206-
s->kobj.kset = slab_kset;
5215+
s->kobj.kset = cache_kset(s);
52075216
err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
52085217
if (err) {
52095218
kobject_put(&s->kobj);
@@ -5216,6 +5225,18 @@ static int sysfs_slab_add(struct kmem_cache *s)
52165225
kobject_put(&s->kobj);
52175226
return err;
52185227
}
5228+
5229+
#ifdef CONFIG_MEMCG_KMEM
5230+
if (is_root_cache(s)) {
5231+
s->memcg_kset = kset_create_and_add("cgroup", NULL, &s->kobj);
5232+
if (!s->memcg_kset) {
5233+
kobject_del(&s->kobj);
5234+
kobject_put(&s->kobj);
5235+
return -ENOMEM;
5236+
}
5237+
}
5238+
#endif
5239+
52195240
kobject_uevent(&s->kobj, KOBJ_ADD);
52205241
if (!unmergeable) {
52215242
/* Setup first alias */
@@ -5234,6 +5255,9 @@ static void sysfs_slab_remove(struct kmem_cache *s)
52345255
*/
52355256
return;
52365257

5258+
#ifdef CONFIG_MEMCG_KMEM
5259+
kset_unregister(s->memcg_kset);
5260+
#endif
52375261
kobject_uevent(&s->kobj, KOBJ_REMOVE);
52385262
kobject_del(&s->kobj);
52395263
kobject_put(&s->kobj);

0 commit comments

Comments
 (0)