aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Davydov <vdavydov@virtuozzo.com>2016-07-26 18:22:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-26 19:19:19 -0400
commit2a966b77ae3ede207e787e7538b87d1011c4364e (patch)
treeb6fe80a56c921cb230443eff6bee65aa2372883c
parent798fd756952c4b6cb7dfe6f6437e9f02da79a5bc (diff)
mm: oom: add memcg to oom_control
It's a part of oom context just like allocation order and nodemask, so let's move it to oom_control instead of passing it in the argument list. Link: http://lkml.kernel.org/r/40e03fd7aaf1f55c75d787128d6d17c5a71226c2.1464358556.git.vdavydov@virtuozzo.com Signed-off-by: Vladimir Davydov <vdavydov@virtuozzo.com> Acked-by: Michal Hocko <mhocko@suse.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/tty/sysrq.c1
-rw-r--r--include/linux/oom.h8
-rw-r--r--mm/memcontrol.c5
-rw-r--r--mm/oom_kill.c32
-rw-r--r--mm/page_alloc.c1
5 files changed, 25 insertions, 22 deletions
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index e5139402e7f8..52bbd27e93ae 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -363,6 +363,7 @@ static void moom_callback(struct work_struct *ignored)
363 struct oom_control oc = { 363 struct oom_control oc = {
364 .zonelist = node_zonelist(first_memory_node, gfp_mask), 364 .zonelist = node_zonelist(first_memory_node, gfp_mask),
365 .nodemask = NULL, 365 .nodemask = NULL,
366 .memcg = NULL,
366 .gfp_mask = gfp_mask, 367 .gfp_mask = gfp_mask,
367 .order = -1, 368 .order = -1,
368 }; 369 };
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 83469522690a..cbc24a5fe28d 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -23,6 +23,9 @@ struct oom_control {
23 /* Used to determine mempolicy */ 23 /* Used to determine mempolicy */
24 nodemask_t *nodemask; 24 nodemask_t *nodemask;
25 25
26 /* Memory cgroup in which oom is invoked, or NULL for global oom */
27 struct mem_cgroup *memcg;
28
26 /* Used to determine cpuset and node locality requirement */ 29 /* Used to determine cpuset and node locality requirement */
27 const gfp_t gfp_mask; 30 const gfp_t gfp_mask;
28 31
@@ -83,11 +86,10 @@ extern unsigned long oom_badness(struct task_struct *p,
83 86
84extern void oom_kill_process(struct oom_control *oc, struct task_struct *p, 87extern void oom_kill_process(struct oom_control *oc, struct task_struct *p,
85 unsigned int points, unsigned long totalpages, 88 unsigned int points, unsigned long totalpages,
86 struct mem_cgroup *memcg, const char *message); 89 const char *message);
87 90
88extern void check_panic_on_oom(struct oom_control *oc, 91extern void check_panic_on_oom(struct oom_control *oc,
89 enum oom_constraint constraint, 92 enum oom_constraint constraint);
90 struct mem_cgroup *memcg);
91 93
92extern enum oom_scan_t oom_scan_process_thread(struct oom_control *oc, 94extern enum oom_scan_t oom_scan_process_thread(struct oom_control *oc,
93 struct task_struct *task, unsigned long totalpages); 95 struct task_struct *task, unsigned long totalpages);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3a755212448e..caea25a21c70 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1259,6 +1259,7 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
1259 struct oom_control oc = { 1259 struct oom_control oc = {
1260 .zonelist = NULL, 1260 .zonelist = NULL,
1261 .nodemask = NULL, 1261 .nodemask = NULL,
1262 .memcg = memcg,
1262 .gfp_mask = gfp_mask, 1263 .gfp_mask = gfp_mask,
1263 .order = order, 1264 .order = order,
1264 }; 1265 };
@@ -1281,7 +1282,7 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
1281 goto unlock; 1282 goto unlock;
1282 } 1283 }
1283 1284
1284 check_panic_on_oom(&oc, CONSTRAINT_MEMCG, memcg); 1285 check_panic_on_oom(&oc, CONSTRAINT_MEMCG);
1285 totalpages = mem_cgroup_get_limit(memcg) ? : 1; 1286 totalpages = mem_cgroup_get_limit(memcg) ? : 1;
1286 for_each_mem_cgroup_tree(iter, memcg) { 1287 for_each_mem_cgroup_tree(iter, memcg) {
1287 struct css_task_iter it; 1288 struct css_task_iter it;
@@ -1329,7 +1330,7 @@ static bool mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
1329 1330
1330 if (chosen) { 1331 if (chosen) {
1331 points = chosen_points * 1000 / totalpages; 1332 points = chosen_points * 1000 / totalpages;
1332 oom_kill_process(&oc, chosen, points, totalpages, memcg, 1333 oom_kill_process(&oc, chosen, points, totalpages,
1333 "Memory cgroup out of memory"); 1334 "Memory cgroup out of memory");
1334 } 1335 }
1335unlock: 1336unlock:
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 398c245a484a..a376f1ebdad5 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -383,8 +383,7 @@ static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
383 rcu_read_unlock(); 383 rcu_read_unlock();
384} 384}
385 385
386static void dump_header(struct oom_control *oc, struct task_struct *p, 386static void dump_header(struct oom_control *oc, struct task_struct *p)
387 struct mem_cgroup *memcg)
388{ 387{
389 pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n", 388 pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n",
390 current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order, 389 current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order,
@@ -392,12 +391,12 @@ static void dump_header(struct oom_control *oc, struct task_struct *p,
392 391
393 cpuset_print_current_mems_allowed(); 392 cpuset_print_current_mems_allowed();
394 dump_stack(); 393 dump_stack();
395 if (memcg) 394 if (oc->memcg)
396 mem_cgroup_print_oom_info(memcg, p); 395 mem_cgroup_print_oom_info(oc->memcg, p);
397 else 396 else
398 show_mem(SHOW_MEM_FILTER_NODES); 397 show_mem(SHOW_MEM_FILTER_NODES);
399 if (sysctl_oom_dump_tasks) 398 if (sysctl_oom_dump_tasks)
400 dump_tasks(memcg, oc->nodemask); 399 dump_tasks(oc->memcg, oc->nodemask);
401} 400}
402 401
403/* 402/*
@@ -739,7 +738,7 @@ void oom_killer_enable(void)
739 */ 738 */
740void oom_kill_process(struct oom_control *oc, struct task_struct *p, 739void oom_kill_process(struct oom_control *oc, struct task_struct *p,
741 unsigned int points, unsigned long totalpages, 740 unsigned int points, unsigned long totalpages,
742 struct mem_cgroup *memcg, const char *message) 741 const char *message)
743{ 742{
744 struct task_struct *victim = p; 743 struct task_struct *victim = p;
745 struct task_struct *child; 744 struct task_struct *child;
@@ -765,7 +764,7 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
765 task_unlock(p); 764 task_unlock(p);
766 765
767 if (__ratelimit(&oom_rs)) 766 if (__ratelimit(&oom_rs))
768 dump_header(oc, p, memcg); 767 dump_header(oc, p);
769 768
770 pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n", 769 pr_err("%s: Kill process %d (%s) score %u or sacrifice child\n",
771 message, task_pid_nr(p), p->comm, points); 770 message, task_pid_nr(p), p->comm, points);
@@ -786,8 +785,8 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
786 /* 785 /*
787 * oom_badness() returns 0 if the thread is unkillable 786 * oom_badness() returns 0 if the thread is unkillable
788 */ 787 */
789 child_points = oom_badness(child, memcg, oc->nodemask, 788 child_points = oom_badness(child,
790 totalpages); 789 oc->memcg, oc->nodemask, totalpages);
791 if (child_points > victim_points) { 790 if (child_points > victim_points) {
792 put_task_struct(victim); 791 put_task_struct(victim);
793 victim = child; 792 victim = child;
@@ -865,8 +864,7 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
865/* 864/*
866 * Determines whether the kernel must panic because of the panic_on_oom sysctl. 865 * Determines whether the kernel must panic because of the panic_on_oom sysctl.
867 */ 866 */
868void check_panic_on_oom(struct oom_control *oc, enum oom_constraint constraint, 867void check_panic_on_oom(struct oom_control *oc, enum oom_constraint constraint)
869 struct mem_cgroup *memcg)
870{ 868{
871 if (likely(!sysctl_panic_on_oom)) 869 if (likely(!sysctl_panic_on_oom))
872 return; 870 return;
@@ -882,7 +880,7 @@ void check_panic_on_oom(struct oom_control *oc, enum oom_constraint constraint,
882 /* Do not panic for oom kills triggered by sysrq */ 880 /* Do not panic for oom kills triggered by sysrq */
883 if (is_sysrq_oom(oc)) 881 if (is_sysrq_oom(oc))
884 return; 882 return;
885 dump_header(oc, NULL, memcg); 883 dump_header(oc, NULL);
886 panic("Out of memory: %s panic_on_oom is enabled\n", 884 panic("Out of memory: %s panic_on_oom is enabled\n",
887 sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); 885 sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide");
888} 886}
@@ -957,13 +955,13 @@ bool out_of_memory(struct oom_control *oc)
957 constraint = constrained_alloc(oc, &totalpages); 955 constraint = constrained_alloc(oc, &totalpages);
958 if (constraint != CONSTRAINT_MEMORY_POLICY) 956 if (constraint != CONSTRAINT_MEMORY_POLICY)
959 oc->nodemask = NULL; 957 oc->nodemask = NULL;
960 check_panic_on_oom(oc, constraint, NULL); 958 check_panic_on_oom(oc, constraint);
961 959
962 if (sysctl_oom_kill_allocating_task && current->mm && 960 if (sysctl_oom_kill_allocating_task && current->mm &&
963 !oom_unkillable_task(current, NULL, oc->nodemask) && 961 !oom_unkillable_task(current, NULL, oc->nodemask) &&
964 current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) { 962 current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) {
965 get_task_struct(current); 963 get_task_struct(current);
966 oom_kill_process(oc, current, 0, totalpages, NULL, 964 oom_kill_process(oc, current, 0, totalpages,
967 "Out of memory (oom_kill_allocating_task)"); 965 "Out of memory (oom_kill_allocating_task)");
968 return true; 966 return true;
969 } 967 }
@@ -971,12 +969,11 @@ bool out_of_memory(struct oom_control *oc)
971 p = select_bad_process(oc, &points, totalpages); 969 p = select_bad_process(oc, &points, totalpages);
972 /* Found nothing?!?! Either we hang forever, or we panic. */ 970 /* Found nothing?!?! Either we hang forever, or we panic. */
973 if (!p && !is_sysrq_oom(oc)) { 971 if (!p && !is_sysrq_oom(oc)) {
974 dump_header(oc, NULL, NULL); 972 dump_header(oc, NULL);
975 panic("Out of memory and no killable processes...\n"); 973 panic("Out of memory and no killable processes...\n");
976 } 974 }
977 if (p && p != (void *)-1UL) { 975 if (p && p != (void *)-1UL) {
978 oom_kill_process(oc, p, points, totalpages, NULL, 976 oom_kill_process(oc, p, points, totalpages, "Out of memory");
979 "Out of memory");
980 /* 977 /*
981 * Give the killed process a good chance to exit before trying 978 * Give the killed process a good chance to exit before trying
982 * to allocate memory again. 979 * to allocate memory again.
@@ -996,6 +993,7 @@ void pagefault_out_of_memory(void)
996 struct oom_control oc = { 993 struct oom_control oc = {
997 .zonelist = NULL, 994 .zonelist = NULL,
998 .nodemask = NULL, 995 .nodemask = NULL,
996 .memcg = NULL,
999 .gfp_mask = 0, 997 .gfp_mask = 0,
1000 .order = 0, 998 .order = 0,
1001 }; 999 };
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8129922a1504..f7bb1aef54f2 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3105,6 +3105,7 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
3105 struct oom_control oc = { 3105 struct oom_control oc = {
3106 .zonelist = ac->zonelist, 3106 .zonelist = ac->zonelist,
3107 .nodemask = ac->nodemask, 3107 .nodemask = ac->nodemask,
3108 .memcg = NULL,
3108 .gfp_mask = gfp_mask, 3109 .gfp_mask = gfp_mask,
3109 .order = order, 3110 .order = order,
3110 }; 3111 };