提交 ca0dde97 编写于 作者: L Li Zefan 提交者: Linus Torvalds

memcg: take reference before releasing rcu_read_lock

The memcg is not referenced, so it can be destroyed at anytime right
after we exit rcu read section, so it's not safe to access it.

To fix this, we call css_tryget() to get a reference while we're still
in rcu read section.

This also removes a bogus comment above __memcg_create_cache_enqueue().
Signed-off-by: NLi Zefan <lizefan@huawei.com>
Acked-by: NGlauber Costa <glommer@parallels.com>
Acked-by: NMichal Hocko <mhocko@suse.cz>
Acked-by: NKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 ebff7d8f
......@@ -3483,7 +3483,6 @@ static void memcg_create_cache_work_func(struct work_struct *w)
/*
* Enqueue the creation of a per-memcg kmem_cache.
* Called with rcu_read_lock.
*/
static void __memcg_create_cache_enqueue(struct mem_cgroup *memcg,
struct kmem_cache *cachep)
......@@ -3491,12 +3490,8 @@ static void __memcg_create_cache_enqueue(struct mem_cgroup *memcg,
struct create_work *cw;
cw = kmalloc(sizeof(struct create_work), GFP_NOWAIT);
if (cw == NULL)
return;
/* The corresponding put will be done in the workqueue. */
if (!css_tryget(&memcg->css)) {
kfree(cw);
if (cw == NULL) {
css_put(&memcg->css);
return;
}
......@@ -3552,10 +3547,9 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep,
rcu_read_lock();
memcg = mem_cgroup_from_task(rcu_dereference(current->mm->owner));
rcu_read_unlock();
if (!memcg_can_account_kmem(memcg))
return cachep;
goto out;
idx = memcg_cache_id(memcg);
......@@ -3564,7 +3558,16 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep,
* code updating memcg_caches will issue a write barrier to match this.
*/
read_barrier_depends();
if (unlikely(cachep->memcg_params->memcg_caches[idx] == NULL)) {
if (likely(cachep->memcg_params->memcg_caches[idx])) {
cachep = cachep->memcg_params->memcg_caches[idx];
goto out;
}
/* The corresponding put will be done in the workqueue. */
if (!css_tryget(&memcg->css))
goto out;
rcu_read_unlock();
/*
* If we are in a safe context (can wait, and not in interrupt
* context), we could be be predictable and return right away.
......@@ -3584,9 +3587,9 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep,
*/
memcg_create_cache_enqueue(memcg, cachep);
return cachep;
}
return cachep->memcg_params->memcg_caches[idx];
out:
rcu_read_unlock();
return cachep;
}
EXPORT_SYMBOL(__memcg_kmem_get_cache);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册