aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slab_common.c
diff options
context:
space:
mode:
authorVladimir Davydov <vdavydov@parallels.com>2015-02-12 17:59:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-12 21:54:10 -0500
commit2a4db7eb9391a544ff58f4fa11d35246e87c87af (patch)
tree3bbd57297a8303ffa227d6ea5600d2593a0302f4 /mm/slab_common.c
parentf1008365bbe4931d6a94dcfc11cf4cdada359664 (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.c39
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
548void 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
551void memcg_destroy_kmem_caches(struct mem_cgroup *memcg) 568void memcg_destroy_kmem_caches(struct mem_cgroup *memcg)
552{ 569{
553 LIST_HEAD(release); 570 LIST_HEAD(release);