[Devel] [PATCH rh7 04/21] ms/memcg: get_mem_cgroup_from_mm()
Andrey Ryabinin
aryabinin at virtuozzo.com
Tue Nov 1 02:21:23 PDT 2016
From: Johannes Weiner <hannes at cmpxchg.org>
Instead of returning NULL from try_get_mem_cgroup_from_mm() when the mm
owner is exiting, just return root_mem_cgroup. This makes sense for all
callsites and gets rid of some of them having to fallback manually.
[fengguang.wu at intel.com: fix warnings]
Signed-off-by: Johannes Weiner <hannes at cmpxchg.org>
Signed-off-by: Fengguang Wu <fengguang.wu at intel.com>
Acked-by: Michal Hocko <mhocko at suse.cz>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
https://jira.sw.ru/browse/PSBM-51558
(cherry picked from commit df381975463996178d685f6ef7d3555c5f887201)
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
include/linux/memcontrol.h | 12 ++++++------
mm/memcontrol.c | 37 +++++++++++++++++--------------------
mm/oom_kill.c | 4 ++--
net/packet/af_packet.c | 2 +-
4 files changed, 26 insertions(+), 29 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 48bf2ca..c48547d 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -85,7 +85,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg)
extern struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page);
extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p);
-extern struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm);
+extern struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm);
extern struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg);
extern struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont);
@@ -304,17 +304,17 @@ static inline struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
return NULL;
}
-static inline struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm)
-{
- return NULL;
-}
-
static inline bool mm_match_cgroup(struct mm_struct *mm,
struct mem_cgroup *memcg)
{
return true;
}
+static inline struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm)
+{
+ return NULL;
+}
+
static inline int task_in_mem_cgroup(struct task_struct *task,
const struct mem_cgroup *memcg)
{
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index ca3f8a8..f3a266f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1149,15 +1149,24 @@ struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
return mem_cgroup_from_css(task_subsys_state(p, mem_cgroup_subsys_id));
}
-struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm)
+struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm)
{
struct mem_cgroup *memcg = NULL;
rcu_read_lock();
do {
- memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
- if (unlikely(!memcg))
- break;
+ /*
+ * Page cache insertions can happen withou an
+ * actual mm context, e.g. during disk probing
+ * on boot, loopback IO, acct() writes etc.
+ */
+ if (unlikely(!mm))
+ memcg = root_mem_cgroup;
+ else {
+ memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
+ if (unlikely(!memcg))
+ memcg = root_mem_cgroup;
+ }
} while (!css_tryget(&memcg->css));
rcu_read_unlock();
return memcg;
@@ -1529,7 +1538,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg)
p = find_lock_task_mm(task);
if (p) {
- curr = try_get_mem_cgroup_from_mm(p->mm);
+ curr = get_mem_cgroup_from_mm(p->mm);
task_unlock(p);
} else {
/*
@@ -1543,8 +1552,6 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg)
css_get(&curr->css);
task_unlock(task);
}
- if (!curr)
- return 0;
/*
* We should check use_hierarchy of "memcg" not "curr". Because checking
* use_hierarchy of "curr" here make this function true if hierarchy is
@@ -1676,7 +1683,7 @@ void mem_cgroup_note_oom_kill(struct mem_cgroup *root_memcg,
p = find_lock_task_mm(task);
if (p) {
- memcg = try_get_mem_cgroup_from_mm(p->mm);
+ memcg = get_mem_cgroup_from_mm(p->mm);
task_unlock(p);
} else {
rcu_read_lock();
@@ -3474,9 +3481,7 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep,
if (!current->mm || current->memcg_kmem_skip_account)
return cachep;
- memcg = try_get_mem_cgroup_from_mm(current->mm);
- if (unlikely(!memcg))
- return cachep;
+ memcg = get_mem_cgroup_from_mm(current->mm);
if (!memcg_kmem_is_active(memcg))
goto out;
@@ -3559,15 +3564,7 @@ __memcg_kmem_newpage_charge(struct page *page, gfp_t gfp, int order)
if (!current->mm || current->memcg_kmem_skip_account)
return true;
- memcg = try_get_mem_cgroup_from_mm(current->mm);
-
- /*
- * very rare case described in mem_cgroup_from_task. Unfortunately there
- * isn't much we can do without complicating this too much, and it would
- * be gfp-dependent anyway. Just let it go
- */
- if (unlikely(!memcg))
- return true;
+ memcg = get_mem_cgroup_from_mm(current->mm);
if (!memcg_kmem_is_active(memcg)) {
css_put(&memcg->css);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f9a8e62..622a248 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -182,7 +182,7 @@ static unsigned long mm_overdraft(struct mm_struct *mm)
struct oom_context *ctx;
unsigned long overdraft;
- memcg = try_get_mem_cgroup_from_mm(mm);
+ memcg = get_mem_cgroup_from_mm(mm);
ctx = mem_cgroup_oom_context(memcg);
overdraft = ctx->overdraft;
if (memcg)
@@ -476,7 +476,7 @@ void mark_oom_victim(struct task_struct *tsk)
* owner memcg so that others can wait for it to exit. It will
* be cleared in exit_oom_victim.
*/
- memcg = try_get_mem_cgroup_from_mm(tsk->mm);
+ memcg = get_mem_cgroup_from_mm(tsk->mm);
ctx = mem_cgroup_oom_context(memcg);
spin_lock(&oom_context_lock);
if (!ctx->victim) {
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2a1b15a..da259df 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2510,7 +2510,7 @@ static struct cg_proto *packet_sk_charge(void)
goto out;
err = 0;
- psc->memcg = try_get_mem_cgroup_from_mm(current->mm);
+ psc->memcg = get_mem_cgroup_from_mm(current->mm);
if (!psc->memcg)
goto out_free_psc;
if (!memcg_kmem_is_active(psc->memcg))
--
2.7.3
More information about the Devel
mailing list