[Devel] [PATCH RHEL7 COMMIT] ms/memcg: get_mem_cgroup_from_mm()
Konstantin Khorenko
khorenko at virtuozzo.com
Mon Jan 16 08:27:05 PST 2017
The commit is pushed to "branch-rh7-3.10.0-514.vz7.27.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.vz7.27.10
------>
commit a7ec2fa951e33ca41ceee0fae9bf4926a431ff40
Author: Johannes Weiner <hannes at cmpxchg.org>
Date: Mon Jan 16 20:27:05 2017 +0400
ms/memcg: get_mem_cgroup_from_mm()
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 f1b599f..bcf7752 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 d09d55d9..40ac81b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1166,15 +1166,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;
@@ -1546,7 +1555,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 {
/*
@@ -1560,8 +1569,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
@@ -1693,7 +1700,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();
@@ -3458,9 +3465,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;
@@ -3543,15 +3548,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 6b0542c2..a82433f 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 f58fa90..c15e57a 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2521,7 +2521,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))
More information about the Devel
mailing list