Commit 33a690c4 authored by Vladimir Davydov's avatar Vladimir Davydov Committed by Linus Torvalds

memcg: move memcg_{alloc,free}_cache_params to slab_common.c

The only reason why they live in memcontrol.c is that we get/put css
reference to the owner memory cgroup in them.  However, we can do that in
memcg_{un,}register_cache.  OTOH, there are several reasons to move them
to slab_common.c.

First, I think that the less public interface functions we have in
memcontrol.h the better.  Since the functions I move don't depend on
memcontrol, I think it's worth making them private to slab, especially
taking into account that the arrays are defined on the slab's side too.

Second, the way how per-memcg arrays are updated looks rather awkward: it
proceeds from memcontrol.c (__memcg_activate_kmem) to slab_common.c
(memcg_update_all_caches) and back to memcontrol.c again
(memcg_update_array_size).  In the following patches I move the function
relocating the arrays (memcg_update_array_size) to slab_common.c and
therefore get rid this circular call path.  I think we should have the
cache allocation stuff in the same place where we have relocation, because
it's easier to follow the code then.  So I move arrays alloc/free
functions to slab_common.c too.

The third point isn't obvious.  I'm going to make the list_lru structure
per-memcg to allow targeted kmem reclaim.  That means we will have
per-memcg arrays in list_lrus too.  It turns out that it's much easier to
update these arrays in list_lru.c rather than in memcontrol.c, because all
the stuff we need is defined there.  This patch makes memcg caches arrays
allocation path conform that of the upcoming list_lru.

So let's move these functions to slab_common.c and make them static.
Signed-off-by: default avatarVladimir Davydov <vdavydov@parallels.com>
Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
Acked-by: default avatarMichal Hocko <mhocko@suse.cz>
Cc: Christoph Lameter <cl@linux.com>
Cc: Glauber Costa <glommer@gmail.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7a82ca0d
...@@ -440,10 +440,6 @@ void __memcg_kmem_uncharge_pages(struct page *page, int order); ...@@ -440,10 +440,6 @@ void __memcg_kmem_uncharge_pages(struct page *page, int order);
int memcg_cache_id(struct mem_cgroup *memcg); int memcg_cache_id(struct mem_cgroup *memcg);
int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s,
struct kmem_cache *root_cache);
void memcg_free_cache_params(struct kmem_cache *s);
int memcg_update_cache_size(struct kmem_cache *s, int num_groups); int memcg_update_cache_size(struct kmem_cache *s, int num_groups);
void memcg_update_array_size(int num_groups); void memcg_update_array_size(int num_groups);
...@@ -574,16 +570,6 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg) ...@@ -574,16 +570,6 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg)
return -1; return -1;
} }
static inline int memcg_alloc_cache_params(struct mem_cgroup *memcg,
struct kmem_cache *s, struct kmem_cache *root_cache)
{
return 0;
}
static inline void memcg_free_cache_params(struct kmem_cache *s)
{
}
static inline struct kmem_cache * static inline struct kmem_cache *
memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
{ {
......
...@@ -2984,43 +2984,6 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups) ...@@ -2984,43 +2984,6 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
return 0; return 0;
} }
int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s,
struct kmem_cache *root_cache)
{
size_t size;
if (!memcg_kmem_enabled())
return 0;
if (!memcg) {
size = offsetof(struct memcg_cache_params, memcg_caches);
size += memcg_limited_groups_array_size * sizeof(void *);
} else
size = sizeof(struct memcg_cache_params);
s->memcg_params = kzalloc(size, GFP_KERNEL);
if (!s->memcg_params)
return -ENOMEM;
if (memcg) {
s->memcg_params->memcg = memcg;
s->memcg_params->root_cache = root_cache;
css_get(&memcg->css);
} else
s->memcg_params->is_root_cache = true;
return 0;
}
void memcg_free_cache_params(struct kmem_cache *s)
{
if (!s->memcg_params)
return;
if (!s->memcg_params->is_root_cache)
css_put(&s->memcg_params->memcg->css);
kfree(s->memcg_params);
}
static void memcg_register_cache(struct mem_cgroup *memcg, static void memcg_register_cache(struct mem_cgroup *memcg,
struct kmem_cache *root_cache) struct kmem_cache *root_cache)
{ {
...@@ -3051,6 +3014,7 @@ static void memcg_register_cache(struct mem_cgroup *memcg, ...@@ -3051,6 +3014,7 @@ static void memcg_register_cache(struct mem_cgroup *memcg,
if (!cachep) if (!cachep)
return; return;
css_get(&memcg->css);
list_add(&cachep->memcg_params->list, &memcg->memcg_slab_caches); list_add(&cachep->memcg_params->list, &memcg->memcg_slab_caches);
/* /*
...@@ -3084,6 +3048,9 @@ static void memcg_unregister_cache(struct kmem_cache *cachep) ...@@ -3084,6 +3048,9 @@ static void memcg_unregister_cache(struct kmem_cache *cachep)
list_del(&cachep->memcg_params->list); list_del(&cachep->memcg_params->list);
kmem_cache_destroy(cachep); kmem_cache_destroy(cachep);
/* drop the reference taken in memcg_register_cache */
css_put(&memcg->css);
} }
/* /*
......
...@@ -116,6 +116,38 @@ static inline int kmem_cache_sanity_check(const char *name, size_t size) ...@@ -116,6 +116,38 @@ static inline int kmem_cache_sanity_check(const char *name, size_t size)
#endif #endif
#ifdef CONFIG_MEMCG_KMEM #ifdef CONFIG_MEMCG_KMEM
static int memcg_alloc_cache_params(struct mem_cgroup *memcg,
struct kmem_cache *s, struct kmem_cache *root_cache)
{
size_t size;
if (!memcg_kmem_enabled())
return 0;
if (!memcg) {
size = offsetof(struct memcg_cache_params, memcg_caches);
size += memcg_limited_groups_array_size * sizeof(void *);
} else
size = sizeof(struct memcg_cache_params);
s->memcg_params = kzalloc(size, GFP_KERNEL);
if (!s->memcg_params)
return -ENOMEM;
if (memcg) {
s->memcg_params->memcg = memcg;
s->memcg_params->root_cache = root_cache;
} else
s->memcg_params->is_root_cache = true;
return 0;
}
static void memcg_free_cache_params(struct kmem_cache *s)
{
kfree(s->memcg_params);
}
int memcg_update_all_caches(int num_memcgs) int memcg_update_all_caches(int num_memcgs)
{ {
struct kmem_cache *s; struct kmem_cache *s;
...@@ -141,7 +173,17 @@ int memcg_update_all_caches(int num_memcgs) ...@@ -141,7 +173,17 @@ int memcg_update_all_caches(int num_memcgs)
mutex_unlock(&slab_mutex); mutex_unlock(&slab_mutex);
return ret; return ret;
} }
#endif #else
static inline int memcg_alloc_cache_params(struct mem_cgroup *memcg,
struct kmem_cache *s, struct kmem_cache *root_cache)
{
return 0;
}
static inline void memcg_free_cache_params(struct kmem_cache *s)
{
}
#endif /* CONFIG_MEMCG_KMEM */
/* /*
* Find a mergeable slab cache * Find a mergeable slab cache
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment