From: Vladimir Davydov <vdavydov@parallels.com>
To: akpm@linux-foundation.org
Cc: hannes@cmpxchg.org, mhocko@suse.cz, glommer@gmail.com,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
devel@openvz.org
Subject: [PATCH -mm 01/12] memcg: flush cache creation works before memcg cache destruction
Date: Wed, 26 Feb 2014 19:05:06 +0400 [thread overview]
Message-ID: <b4b2adcd61e506e60df267e7a4a99c282d97f0fb.1393423762.git.vdavydov@parallels.com> (raw)
In-Reply-To: <cover.1393423762.git.vdavydov@parallels.com>
When we get to memcg cache destruction, either from the root cache
destruction path or when turning memcg offline, there still might be
memcg cache creation works pending that was scheduled before we
initiated destruction. We need to flush them before starting to destroy
memcg caches, otherwise we can get a leaked kmem cache or, even worse,
an attempt to use after free.
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Glauber Costa <glommer@gmail.com>
---
mm/memcontrol.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 8a87614b6238..b61b6e9381e8 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2966,6 +2966,7 @@ static DEFINE_MUTEX(set_limit_mutex);
#ifdef CONFIG_MEMCG_KMEM
static DEFINE_MUTEX(activate_kmem_mutex);
+static struct workqueue_struct *memcg_cache_create_wq;
static inline bool memcg_can_account_kmem(struct mem_cgroup *memcg)
{
@@ -3392,6 +3393,15 @@ int __kmem_cache_destroy_memcg_children(struct kmem_cache *s)
int i, failed = 0;
/*
+ * Since the cache is being destroyed, it shouldn't be allocated from
+ * any more, and therefore no new memcg cache creation works could be
+ * scheduled. However, there still might be pending works scheduled
+ * before the cache destruction was initiated. Flush them before
+ * destroying child caches to avoid nasty races.
+ */
+ flush_workqueue(memcg_cache_create_wq);
+
+ /*
* If the cache is being destroyed, we trust that there is no one else
* requesting objects from it. Even if there are, the sanity checks in
* kmem_cache_destroy should caught this ill-case.
@@ -3439,6 +3449,15 @@ static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
if (!memcg_kmem_is_active(memcg))
return;
+ /*
+ * By the time we get here, the cgroup must be empty. That said no new
+ * allocations can happen from its caches, and therefore no new memcg
+ * cache creation works can be scheduled. However, there still might be
+ * pending works scheduled before the cgroup was turned offline. Flush
+ * them before destroying memcg caches to avoid nasty races.
+ */
+ flush_workqueue(memcg_cache_create_wq);
+
mutex_lock(&memcg->slab_caches_mutex);
list_for_each_entry(params, &memcg->memcg_slab_caches, list) {
cachep = memcg_params_to_cache(params);
@@ -3483,7 +3502,7 @@ static void __memcg_create_cache_enqueue(struct mem_cgroup *memcg,
cw->cachep = cachep;
INIT_WORK(&cw->work, memcg_create_cache_work_func);
- schedule_work(&cw->work);
+ queue_work(memcg_cache_create_wq, &cw->work);
}
static void memcg_create_cache_enqueue(struct mem_cgroup *memcg,
@@ -3694,10 +3713,20 @@ void __memcg_kmem_uncharge_pages(struct page *page, int order)
VM_BUG_ON_PAGE(mem_cgroup_is_root(memcg), page);
memcg_uncharge_kmem(memcg, PAGE_SIZE << order);
}
+
+static void __init memcg_kmem_init(void)
+{
+ memcg_cache_create_wq = alloc_workqueue("memcg_cache_create", 0, 1);
+ BUG_ON(!memcg_cache_create_wq);
+}
#else
static inline void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
{
}
+
+static void __init memcg_kmem_init(void)
+{
+}
#endif /* CONFIG_MEMCG_KMEM */
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -7261,6 +7290,7 @@ static int __init mem_cgroup_init(void)
enable_swap_cgroup();
mem_cgroup_soft_limit_tree_init();
memcg_stock_init();
+ memcg_kmem_init();
return 0;
}
subsys_initcall(mem_cgroup_init);
--
1.7.10.4
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2014-02-26 15:05 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-26 15:05 [PATCH -mm 00/12] kmemcg reparenting Vladimir Davydov
2014-02-26 15:05 ` Vladimir Davydov [this message]
2014-02-26 15:05 ` [PATCH -mm 02/12] memcg: fix race in memcg cache destruction path Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 03/12] memcg: fix root vs memcg cache destruction race Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 04/12] memcg: move slab caches list/mutex init to memcg creation Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 05/12] memcg: add pointer from memcg_cache_params to cache Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 06/12] memcg: keep all children of each root cache on a list Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 07/12] memcg: rework slab charging Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 08/12] memcg: do not charge kmalloc_large allocations Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 09/12] fork: do not charge thread_info to kmemcg Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 10/12] memcg: kill GFP_KMEMCG and stuff Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 11/12] memcg: reparent slab on css offline Vladimir Davydov
2014-02-26 15:05 ` [PATCH -mm 12/12] slub: make sure all memcg caches have unique names on sysfs Vladimir Davydov
2014-03-04 14:56 ` [PATCH -mm 00/12] kmemcg reparenting Vladimir Davydov
2014-03-04 15:21 ` Michal Hocko
2014-03-05 5:54 ` Vladimir Davydov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b4b2adcd61e506e60df267e7a4a99c282d97f0fb.1393423762.git.vdavydov@parallels.com \
--to=vdavydov@parallels.com \
--cc=akpm@linux-foundation.org \
--cc=devel@openvz.org \
--cc=glommer@gmail.com \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox