Skip to content

Commit a44cb94

Browse files
Vladimir Davydovtorvalds
authored andcommitted
memcg, slab: never try to merge memcg caches
When a kmem cache is created (kmem_cache_create_memcg()), we first try to find a compatible cache that already exists and can handle requests from the new cache, i.e. has the same object size, alignment, ctor, etc. If there is such a cache, we do not create any new caches, instead we simply increment the refcount of the cache found and return it. Currently we do this procedure not only when creating root caches, but also for memcg caches. However, there is no point in that, because, as every memcg cache has exactly the same parameters as its parent and cache merging cannot be turned off in runtime (only on boot by passing "slub_nomerge"), the root caches of any two potentially mergeable memcg caches should be merged already, i.e. it must be the same root cache, and therefore we couldn't even get to the memcg cache creation, because it already exists. The only exception is boot caches - they are explicitly forbidden to be merged by setting their refcount to -1. There are currently only two of them - kmem_cache and kmem_cache_node, which are used in slab internals (I do not count kmalloc caches as their refcount is set to 1 immediately after creation). Since they are prevented from merging preliminary I guess we should avoid to merge their children too. So let's remove the useless code responsible for merging memcg caches. 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 cf7bc58 commit a44cb94

File tree

3 files changed

+18
-30
lines changed

3 files changed

+18
-30
lines changed

mm/slab.h

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ extern void create_boot_cache(struct kmem_cache *, const char *name,
5555
struct mem_cgroup;
5656
#ifdef CONFIG_SLUB
5757
struct kmem_cache *
58-
__kmem_cache_alias(struct mem_cgroup *memcg, const char *name, size_t size,
59-
size_t align, unsigned long flags, void (*ctor)(void *));
58+
__kmem_cache_alias(const char *name, size_t size, size_t align,
59+
unsigned long flags, void (*ctor)(void *));
6060
#else
6161
static inline struct kmem_cache *
62-
__kmem_cache_alias(struct mem_cgroup *memcg, const char *name, size_t size,
63-
size_t align, unsigned long flags, void (*ctor)(void *))
62+
__kmem_cache_alias(const char *name, size_t size, size_t align,
63+
unsigned long flags, void (*ctor)(void *))
6464
{ return NULL; }
6565
#endif
6666

@@ -119,13 +119,6 @@ static inline bool is_root_cache(struct kmem_cache *s)
119119
return !s->memcg_params || s->memcg_params->is_root_cache;
120120
}
121121

122-
static inline bool cache_match_memcg(struct kmem_cache *cachep,
123-
struct mem_cgroup *memcg)
124-
{
125-
return (is_root_cache(cachep) && !memcg) ||
126-
(cachep->memcg_params->memcg == memcg);
127-
}
128-
129122
static inline void memcg_bind_pages(struct kmem_cache *s, int order)
130123
{
131124
if (!is_root_cache(s))
@@ -204,12 +197,6 @@ static inline bool is_root_cache(struct kmem_cache *s)
204197
return true;
205198
}
206199

207-
static inline bool cache_match_memcg(struct kmem_cache *cachep,
208-
struct mem_cgroup *memcg)
209-
{
210-
return true;
211-
}
212-
213200
static inline void memcg_bind_pages(struct kmem_cache *s, int order)
214201
{
215202
}

mm/slab_common.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,11 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size,
200200
*/
201201
flags &= CACHE_CREATE_MASK;
202202

203-
s = __kmem_cache_alias(memcg, name, size, align, flags, ctor);
204-
if (s)
205-
goto out_unlock;
203+
if (!memcg) {
204+
s = __kmem_cache_alias(name, size, align, flags, ctor);
205+
if (s)
206+
goto out_unlock;
207+
}
206208

207209
err = -ENOMEM;
208210
s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL);

mm/slub.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3685,6 +3685,9 @@ static int slab_unmergeable(struct kmem_cache *s)
36853685
if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE))
36863686
return 1;
36873687

3688+
if (!is_root_cache(s))
3689+
return 1;
3690+
36883691
if (s->ctor)
36893692
return 1;
36903693

@@ -3697,9 +3700,8 @@ static int slab_unmergeable(struct kmem_cache *s)
36973700
return 0;
36983701
}
36993702

3700-
static struct kmem_cache *find_mergeable(struct mem_cgroup *memcg, size_t size,
3701-
size_t align, unsigned long flags, const char *name,
3702-
void (*ctor)(void *))
3703+
static struct kmem_cache *find_mergeable(size_t size, size_t align,
3704+
unsigned long flags, const char *name, void (*ctor)(void *))
37033705
{
37043706
struct kmem_cache *s;
37053707

@@ -3722,7 +3724,7 @@ static struct kmem_cache *find_mergeable(struct mem_cgroup *memcg, size_t size,
37223724
continue;
37233725

37243726
if ((flags & SLUB_MERGE_SAME) != (s->flags & SLUB_MERGE_SAME))
3725-
continue;
3727+
continue;
37263728
/*
37273729
* Check if alignment is compatible.
37283730
* Courtesy of Adrian Drzewiecki
@@ -3733,21 +3735,18 @@ static struct kmem_cache *find_mergeable(struct mem_cgroup *memcg, size_t size,
37333735
if (s->size - size >= sizeof(void *))
37343736
continue;
37353737

3736-
if (!cache_match_memcg(s, memcg))
3737-
continue;
3738-
37393738
return s;
37403739
}
37413740
return NULL;
37423741
}
37433742

37443743
struct kmem_cache *
3745-
__kmem_cache_alias(struct mem_cgroup *memcg, const char *name, size_t size,
3746-
size_t align, unsigned long flags, void (*ctor)(void *))
3744+
__kmem_cache_alias(const char *name, size_t size, size_t align,
3745+
unsigned long flags, void (*ctor)(void *))
37473746
{
37483747
struct kmem_cache *s;
37493748

3750-
s = find_mergeable(memcg, size, align, flags, name, ctor);
3749+
s = find_mergeable(size, align, flags, name, ctor);
37513750
if (s) {
37523751
s->refcount++;
37533752
/*

0 commit comments

Comments
 (0)