diff options
author | Vladimir Davydov <vdavydov@parallels.com> | 2015-02-12 17:59:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-12 21:54:10 -0500 |
commit | 2a4db7eb9391a544ff58f4fa11d35246e87c87af (patch) | |
tree | 3bbd57297a8303ffa227d6ea5600d2593a0302f4 /mm/slab_common.c | |
parent | f1008365bbe4931d6a94dcfc11cf4cdada359664 (diff) |
memcg: free memcg_caches slot on css offline
We need to look up a kmem_cache in ->memcg_params.memcg_caches arrays only
on allocations, so there is no need to have the array entries set until
css free - we can clear them on css offline. This will allow us to reuse
array entries more efficiently and avoid costly array relocations.
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>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/slab_common.c')
-rw-r--r-- | mm/slab_common.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/mm/slab_common.c b/mm/slab_common.c index 6087b1f9a385..0873bcc61c7a 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
@@ -440,18 +440,8 @@ static int do_kmem_cache_shutdown(struct kmem_cache *s, | |||
440 | *need_rcu_barrier = true; | 440 | *need_rcu_barrier = true; |
441 | 441 | ||
442 | #ifdef CONFIG_MEMCG_KMEM | 442 | #ifdef CONFIG_MEMCG_KMEM |
443 | if (!is_root_cache(s)) { | 443 | if (!is_root_cache(s)) |
444 | int idx; | ||
445 | struct memcg_cache_array *arr; | ||
446 | |||
447 | idx = memcg_cache_id(s->memcg_params.memcg); | ||
448 | arr = rcu_dereference_protected(s->memcg_params.root_cache-> | ||
449 | memcg_params.memcg_caches, | ||
450 | lockdep_is_held(&slab_mutex)); | ||
451 | BUG_ON(arr->entries[idx] != s); | ||
452 | arr->entries[idx] = NULL; | ||
453 | list_del(&s->memcg_params.list); | 444 | list_del(&s->memcg_params.list); |
454 | } | ||
455 | #endif | 445 | #endif |
456 | list_move(&s->list, release); | 446 | list_move(&s->list, release); |
457 | return 0; | 447 | return 0; |
@@ -499,6 +489,13 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg, | |||
499 | 489 | ||
500 | mutex_lock(&slab_mutex); | 490 | mutex_lock(&slab_mutex); |
501 | 491 | ||
492 | /* | ||
493 | * The memory cgroup could have been deactivated while the cache | ||
494 | * creation work was pending. | ||
495 | */ | ||
496 | if (!memcg_kmem_is_active(memcg)) | ||
497 | goto out_unlock; | ||
498 | |||
502 | idx = memcg_cache_id(memcg); | 499 | idx = memcg_cache_id(memcg); |
503 | arr = rcu_dereference_protected(root_cache->memcg_params.memcg_caches, | 500 | arr = rcu_dereference_protected(root_cache->memcg_params.memcg_caches, |
504 | lockdep_is_held(&slab_mutex)); | 501 | lockdep_is_held(&slab_mutex)); |
@@ -548,6 +545,26 @@ out_unlock: | |||
548 | put_online_cpus(); | 545 | put_online_cpus(); |
549 | } | 546 | } |
550 | 547 | ||
548 | void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg) | ||
549 | { | ||
550 | int idx; | ||
551 | struct memcg_cache_array *arr; | ||
552 | struct kmem_cache *s; | ||
553 | |||
554 | idx = memcg_cache_id(memcg); | ||
555 | |||
556 | mutex_lock(&slab_mutex); | ||
557 | list_for_each_entry(s, &slab_caches, list) { | ||
558 | if (!is_root_cache(s)) | ||
559 | continue; | ||
560 | |||
561 | arr = rcu_dereference_protected(s->memcg_params.memcg_caches, | ||
562 | lockdep_is_held(&slab_mutex)); | ||
563 | arr->entries[idx] = NULL; | ||
564 | } | ||
565 | mutex_unlock(&slab_mutex); | ||
566 | } | ||
567 | |||
551 | void memcg_destroy_kmem_caches(struct mem_cgroup *memcg) | 568 | void memcg_destroy_kmem_caches(struct mem_cgroup *memcg) |
552 | { | 569 | { |
553 | LIST_HEAD(release); | 570 | LIST_HEAD(release); |