diff options
author | Vladimir Davydov <vdavydov@parallels.com> | 2015-02-12 17:59:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 21:54:09 -0500 |
commit | f7ce3190c4a35bf887adb7a1aa1ba899b679872d (patch) | |
tree | 8a40d93f1e796e1007d59e67541ce3044430b927 /mm/memcontrol.c | |
parent | 49e7e7ff8d551b5b1e2f8da8497b9058cfa25672 (diff) |
slab: embed memcg_cache_params to kmem_cache
Currently, kmem_cache stores a pointer to struct memcg_cache_params
instead of embedding it. The rationale is to save memory when kmem
accounting is disabled. However, the memcg_cache_params has shrivelled
drastically since it was first introduced:
* Initially:
struct memcg_cache_params {
bool is_root_cache;
union {
struct kmem_cache *memcg_caches[0];
struct {
struct mem_cgroup *memcg;
struct list_head list;
struct kmem_cache *root_cache;
bool dead;
atomic_t nr_pages;
struct work_struct destroy;
};
};
};
* Now:
struct memcg_cache_params {
bool is_root_cache;
union {
struct {
struct rcu_head rcu_head;
struct kmem_cache *memcg_caches[0];
};
struct {
struct mem_cgroup *memcg;
struct kmem_cache *root_cache;
};
};
};
So the memory saving does not seem to be a clear win anymore.
OTOH, keeping a pointer to memcg_cache_params struct instead of embedding
it results in touching one more cache line on kmem alloc/free hot paths.
Besides, it makes linking kmem caches in a list chained by a field of
struct memcg_cache_params really painful due to a level of indirection,
while I want to make them linked in the following patch. That said, let
us embed it.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index afa55bb38cbd..6f3c0fcd7a2d 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -332,7 +332,7 @@ struct mem_cgroup { | |||
332 | struct cg_proto tcp_mem; | 332 | struct cg_proto tcp_mem; |
333 | #endif | 333 | #endif |
334 | #if defined(CONFIG_MEMCG_KMEM) | 334 | #if defined(CONFIG_MEMCG_KMEM) |
335 | /* Index in the kmem_cache->memcg_params->memcg_caches array */ | 335 | /* Index in the kmem_cache->memcg_params.memcg_caches array */ |
336 | int kmemcg_id; | 336 | int kmemcg_id; |
337 | #endif | 337 | #endif |
338 | 338 | ||
@@ -531,7 +531,7 @@ static void disarm_sock_keys(struct mem_cgroup *memcg) | |||
531 | 531 | ||
532 | #ifdef CONFIG_MEMCG_KMEM | 532 | #ifdef CONFIG_MEMCG_KMEM |
533 | /* | 533 | /* |
534 | * This will be the memcg's index in each cache's ->memcg_params->memcg_caches. | 534 | * This will be the memcg's index in each cache's ->memcg_params.memcg_caches. |
535 | * The main reason for not using cgroup id for this: | 535 | * The main reason for not using cgroup id for this: |
536 | * this works better in sparse environments, where we have a lot of memcgs, | 536 | * this works better in sparse environments, where we have a lot of memcgs, |
537 | * but only a few kmem-limited. Or also, if we have, for instance, 200 | 537 | * but only a few kmem-limited. Or also, if we have, for instance, 200 |
@@ -2667,8 +2667,7 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep) | |||
2667 | struct mem_cgroup *memcg; | 2667 | struct mem_cgroup *memcg; |
2668 | struct kmem_cache *memcg_cachep; | 2668 | struct kmem_cache *memcg_cachep; |
2669 | 2669 | ||
2670 | VM_BUG_ON(!cachep->memcg_params); | 2670 | VM_BUG_ON(!is_root_cache(cachep)); |
2671 | VM_BUG_ON(!cachep->memcg_params->is_root_cache); | ||
2672 | 2671 | ||
2673 | if (current->memcg_kmem_skip_account) | 2672 | if (current->memcg_kmem_skip_account) |
2674 | return cachep; | 2673 | return cachep; |
@@ -2702,7 +2701,7 @@ out: | |||
2702 | void __memcg_kmem_put_cache(struct kmem_cache *cachep) | 2701 | void __memcg_kmem_put_cache(struct kmem_cache *cachep) |
2703 | { | 2702 | { |
2704 | if (!is_root_cache(cachep)) | 2703 | if (!is_root_cache(cachep)) |
2705 | css_put(&cachep->memcg_params->memcg->css); | 2704 | css_put(&cachep->memcg_params.memcg->css); |
2706 | } | 2705 | } |
2707 | 2706 | ||
2708 | /* | 2707 | /* |
@@ -2778,7 +2777,7 @@ struct mem_cgroup *__mem_cgroup_from_kmem(void *ptr) | |||
2778 | if (PageSlab(page)) { | 2777 | if (PageSlab(page)) { |
2779 | cachep = page->slab_cache; | 2778 | cachep = page->slab_cache; |
2780 | if (!is_root_cache(cachep)) | 2779 | if (!is_root_cache(cachep)) |
2781 | memcg = cachep->memcg_params->memcg; | 2780 | memcg = cachep->memcg_params.memcg; |
2782 | } else | 2781 | } else |
2783 | /* page allocated by alloc_kmem_pages */ | 2782 | /* page allocated by alloc_kmem_pages */ |
2784 | memcg = page->mem_cgroup; | 2783 | memcg = page->mem_cgroup; |