aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Rientjes <rientjes@google.com>2012-03-21 19:34:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 20:54:59 -0400
commite845e199362cc5712ba0e7eedc14eed70e144258 (patch)
tree3968125d82e512c3aee44ed96694fdd58b863506
parentc7cfa37b7324a190fc36ff116d79d0f899e8d273 (diff)
mm, memcg: pass charge order to oom killer
The oom killer typically displays the allocation order at the time of oom as a part of its diangostic messages (for global, cpuset, and mempolicy ooms). The memory controller may also pass the charge order to the oom killer so it can emit the same information. This is useful in determining how large the memory allocation is that triggered the oom killer. Signed-off-by: David Rientjes <rientjes@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@suse.cz> Cc: Balbir Singh <bsingharora@gmail.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/memcontrol.h3
-rw-r--r--mm/memcontrol.c6
-rw-r--r--mm/oom_kill.c7
3 files changed, 9 insertions, 7 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index b80de520670b..d90965086fae 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -77,7 +77,8 @@ extern void mem_cgroup_uncharge_end(void);
77extern void mem_cgroup_uncharge_page(struct page *page); 77extern void mem_cgroup_uncharge_page(struct page *page);
78extern void mem_cgroup_uncharge_cache_page(struct page *page); 78extern void mem_cgroup_uncharge_cache_page(struct page *page);
79 79
80extern void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask); 80extern void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
81 int order);
81int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg); 82int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *memcg);
82 83
83extern struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page); 84extern struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 37281816ff67..bb04067269bc 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1811,7 +1811,7 @@ static void memcg_oom_recover(struct mem_cgroup *memcg)
1811/* 1811/*
1812 * try to call OOM killer. returns false if we should exit memory-reclaim loop. 1812 * try to call OOM killer. returns false if we should exit memory-reclaim loop.
1813 */ 1813 */
1814bool mem_cgroup_handle_oom(struct mem_cgroup *memcg, gfp_t mask) 1814bool mem_cgroup_handle_oom(struct mem_cgroup *memcg, gfp_t mask, int order)
1815{ 1815{
1816 struct oom_wait_info owait; 1816 struct oom_wait_info owait;
1817 bool locked, need_to_kill; 1817 bool locked, need_to_kill;
@@ -1841,7 +1841,7 @@ bool mem_cgroup_handle_oom(struct mem_cgroup *memcg, gfp_t mask)
1841 1841
1842 if (need_to_kill) { 1842 if (need_to_kill) {
1843 finish_wait(&memcg_oom_waitq, &owait.wait); 1843 finish_wait(&memcg_oom_waitq, &owait.wait);
1844 mem_cgroup_out_of_memory(memcg, mask); 1844 mem_cgroup_out_of_memory(memcg, mask, order);
1845 } else { 1845 } else {
1846 schedule(); 1846 schedule();
1847 finish_wait(&memcg_oom_waitq, &owait.wait); 1847 finish_wait(&memcg_oom_waitq, &owait.wait);
@@ -2212,7 +2212,7 @@ static int mem_cgroup_do_charge(struct mem_cgroup *memcg, gfp_t gfp_mask,
2212 if (!oom_check) 2212 if (!oom_check)
2213 return CHARGE_NOMEM; 2213 return CHARGE_NOMEM;
2214 /* check OOM */ 2214 /* check OOM */
2215 if (!mem_cgroup_handle_oom(mem_over_limit, gfp_mask)) 2215 if (!mem_cgroup_handle_oom(mem_over_limit, gfp_mask, get_order(csize)))
2216 return CHARGE_OOM_DIE; 2216 return CHARGE_OOM_DIE;
2217 2217
2218 return CHARGE_RETRY; 2218 return CHARGE_RETRY;
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f23f33454645..4198e000f41a 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -554,7 +554,8 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask,
554} 554}
555 555
556#ifdef CONFIG_CGROUP_MEM_RES_CTLR 556#ifdef CONFIG_CGROUP_MEM_RES_CTLR
557void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask) 557void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
558 int order)
558{ 559{
559 unsigned long limit; 560 unsigned long limit;
560 unsigned int points = 0; 561 unsigned int points = 0;
@@ -570,12 +571,12 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask)
570 return; 571 return;
571 } 572 }
572 573
573 check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL); 574 check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, order, NULL);
574 limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT; 575 limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT;
575 read_lock(&tasklist_lock); 576 read_lock(&tasklist_lock);
576 p = select_bad_process(&points, limit, memcg, NULL, false); 577 p = select_bad_process(&points, limit, memcg, NULL, false);
577 if (p && PTR_ERR(p) != -1UL) 578 if (p && PTR_ERR(p) != -1UL)
578 oom_kill_process(p, gfp_mask, 0, points, limit, memcg, NULL, 579 oom_kill_process(p, gfp_mask, order, points, limit, memcg, NULL,
579 "Memory cgroup out of memory"); 580 "Memory cgroup out of memory");
580 read_unlock(&tasklist_lock); 581 read_unlock(&tasklist_lock);
581} 582}