diff options
author | Roman Gushchin <guro@fb.com> | 2019-07-11 23:56:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-12 14:05:44 -0400 |
commit | 63b02ef7dc4ec239df45c018ac0adbd02ba30a0c (patch) | |
tree | 8dba00a499a11f78abf6a12f963a26b9c57397d1 /mm/slab_common.c | |
parent | 570332978ea7fdbec86a07086a584d796a87da2c (diff) |
mm: memcg/slab: synchronize access to kmem_cache dying flag using a spinlock
Currently the memcg_params.dying flag and the corresponding workqueue used
for the asynchronous deactivation of kmem_caches is synchronized using the
slab_mutex.
It makes impossible to check this flag from the irq context, which will be
required in order to implement asynchronous release of kmem_caches.
So let's switch over to the irq-save flavor of the spinlock-based
synchronization.
Link: http://lkml.kernel.org/r/20190611231813.3148843-8-guro@fb.com
Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Vladimir Davydov <vdavydov.dev@gmail.com>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Waiman Long <longman@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Andrei Vagin <avagin@gmail.com>
Cc: Qian Cai <cai@lca.pw>
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 | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/mm/slab_common.c b/mm/slab_common.c index afdd73553b88..a15557776d7d 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
@@ -130,6 +130,7 @@ int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr, | |||
130 | #ifdef CONFIG_MEMCG_KMEM | 130 | #ifdef CONFIG_MEMCG_KMEM |
131 | 131 | ||
132 | LIST_HEAD(slab_root_caches); | 132 | LIST_HEAD(slab_root_caches); |
133 | static DEFINE_SPINLOCK(memcg_kmem_wq_lock); | ||
133 | 134 | ||
134 | void slab_init_memcg_params(struct kmem_cache *s) | 135 | void slab_init_memcg_params(struct kmem_cache *s) |
135 | { | 136 | { |
@@ -734,14 +735,22 @@ static void kmemcg_cache_deactivate(struct kmem_cache *s) | |||
734 | 735 | ||
735 | __kmemcg_cache_deactivate(s); | 736 | __kmemcg_cache_deactivate(s); |
736 | 737 | ||
738 | /* | ||
739 | * memcg_kmem_wq_lock is used to synchronize memcg_params.dying | ||
740 | * flag and make sure that no new kmem_cache deactivation tasks | ||
741 | * are queued (see flush_memcg_workqueue() ). | ||
742 | */ | ||
743 | spin_lock_irq(&memcg_kmem_wq_lock); | ||
737 | if (s->memcg_params.root_cache->memcg_params.dying) | 744 | if (s->memcg_params.root_cache->memcg_params.dying) |
738 | return; | 745 | goto unlock; |
739 | 746 | ||
740 | /* pin memcg so that @s doesn't get destroyed in the middle */ | 747 | /* pin memcg so that @s doesn't get destroyed in the middle */ |
741 | css_get(&s->memcg_params.memcg->css); | 748 | css_get(&s->memcg_params.memcg->css); |
742 | 749 | ||
743 | s->memcg_params.work_fn = __kmemcg_cache_deactivate_after_rcu; | 750 | s->memcg_params.work_fn = __kmemcg_cache_deactivate_after_rcu; |
744 | call_rcu(&s->memcg_params.rcu_head, kmemcg_rcufn); | 751 | call_rcu(&s->memcg_params.rcu_head, kmemcg_rcufn); |
752 | unlock: | ||
753 | spin_unlock_irq(&memcg_kmem_wq_lock); | ||
745 | } | 754 | } |
746 | 755 | ||
747 | void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg) | 756 | void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg) |
@@ -851,9 +860,9 @@ static int shutdown_memcg_caches(struct kmem_cache *s) | |||
851 | 860 | ||
852 | static void flush_memcg_workqueue(struct kmem_cache *s) | 861 | static void flush_memcg_workqueue(struct kmem_cache *s) |
853 | { | 862 | { |
854 | mutex_lock(&slab_mutex); | 863 | spin_lock_irq(&memcg_kmem_wq_lock); |
855 | s->memcg_params.dying = true; | 864 | s->memcg_params.dying = true; |
856 | mutex_unlock(&slab_mutex); | 865 | spin_unlock_irq(&memcg_kmem_wq_lock); |
857 | 866 | ||
858 | /* | 867 | /* |
859 | * SLAB and SLUB deactivate the kmem_caches through call_rcu. Make | 868 | * SLAB and SLUB deactivate the kmem_caches through call_rcu. Make |