Commit 158e0a2d1b3cffed8b46cbc56393a1394672ef79
Committed by
Linus Torvalds
1 parent
73045c47b6
Exists in
master
and in
7 other branches
memcg: use find_lock_task_mm() in memory cgroups oom
When the OOM killer scans task, it check a task is under memcg or not when it's called via memcg's context. But, as Oleg pointed out, a thread group leader may have NULL ->mm and task_in_mem_cgroup() may do wrong decision. We have to use find_lock_task_mm() in memcg as generic OOM-Killer does. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Cc: Balbir Singh <balbir@linux.vnet.ibm.com> Reviewed-by: Minchan Kim <minchan.kim@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 10 additions and 4 deletions Side-by-side Diff
include/linux/oom.h
... | ... | @@ -66,6 +66,8 @@ |
66 | 66 | extern unsigned long badness(struct task_struct *p, struct mem_cgroup *mem, |
67 | 67 | const nodemask_t *nodemask, unsigned long uptime); |
68 | 68 | |
69 | +extern struct task_struct *find_lock_task_mm(struct task_struct *p); | |
70 | + | |
69 | 71 | /* sysctls */ |
70 | 72 | extern int sysctl_oom_dump_tasks; |
71 | 73 | extern int sysctl_oom_kill_allocating_task; |
mm/memcontrol.c
... | ... | @@ -47,6 +47,7 @@ |
47 | 47 | #include <linux/mm_inline.h> |
48 | 48 | #include <linux/page_cgroup.h> |
49 | 49 | #include <linux/cpu.h> |
50 | +#include <linux/oom.h> | |
50 | 51 | #include "internal.h" |
51 | 52 | |
52 | 53 | #include <asm/uaccess.h> |
53 | 54 | |
... | ... | @@ -838,10 +839,13 @@ |
838 | 839 | { |
839 | 840 | int ret; |
840 | 841 | struct mem_cgroup *curr = NULL; |
842 | + struct task_struct *p; | |
841 | 843 | |
842 | - task_lock(task); | |
843 | - curr = try_get_mem_cgroup_from_mm(task->mm); | |
844 | - task_unlock(task); | |
844 | + p = find_lock_task_mm(task); | |
845 | + if (!p) | |
846 | + return 0; | |
847 | + curr = try_get_mem_cgroup_from_mm(p->mm); | |
848 | + task_unlock(p); | |
845 | 849 | if (!curr) |
846 | 850 | return 0; |
847 | 851 | /* |
mm/oom_kill.c
... | ... | @@ -106,7 +106,7 @@ |
106 | 106 | * pointer. Return p, or any of its subthreads with a valid ->mm, with |
107 | 107 | * task_lock() held. |
108 | 108 | */ |
109 | -static struct task_struct *find_lock_task_mm(struct task_struct *p) | |
109 | +struct task_struct *find_lock_task_mm(struct task_struct *p) | |
110 | 110 | { |
111 | 111 | struct task_struct *t = p; |
112 | 112 |