From: David Rientjes Creates a helper function to return non-zero if a task is a member of a memory controller: int task_in_mem_cgroup(const struct task_struct *task, const struct mem_cgroup *mem); When the OOM killer is constrained by the memory controller, the exclusion of tasks that are not a member of that controller was previously misplaced and appeared in the badness scoring function. It should be excluded during the tasklist scan in select_bad_process() instead. Cc: Christoph Lameter Cc: Balbir Singh Signed-off-by: David Rientjes DESC memcontrol-move-oom-task-exclusion-to-tasklist-fix EDESC From: Andrew Morton In file included from include/linux/rmap.h:11, from mm/filemap_xip.c:15: include/linux/memcontrol.h: In function 'task_in_mem_cgroup': include/linux/memcontrol.h:63: error: implicit declaration of function 'task_lock' include/linux/memcontrol.h:64: error: dereferencing pointer to incomplete type include/linux/memcontrol.h:64: error: dereferencing pointer to incomplete type include/linux/memcontrol.h:65: error: implicit declaration of function 'task_unlock' In file included from mm/filemap_xip.c:16: include/linux/sched.h: At top level: include/linux/sched.h:1709: warning: conflicting types for 'task_lock' include/linux/sched.h:1709: error: static declaration of 'task_lock' follows non-static declaration include/linux/memcontrol.h:63: error: previous implicit declaration of 'task_lock' was here include/linux/sched.h:1714: warning: conflicting types for 'task_unlock' include/linux/sched.h:1714: error: static declaration of 'task_unlock' follows non-static declaration include/linux/memcontrol.h:65: error: previous implicit declaration of 'task_unlock' was here Cc: Balbir Singh Cc: Christoph Lameter Cc: David Rientjes Signed-off-by: Andrew Morton --- include/linux/memcontrol.h | 7 +++++++ mm/memcontrol.c | 10 ++++++++++ mm/oom_kill.c | 9 ++------- 3 files changed, 19 insertions(+), 7 deletions(-) diff -puN include/linux/memcontrol.h~memcontrol-move-oom-task-exclusion-to-tasklist include/linux/memcontrol.h --- a/include/linux/memcontrol.h~memcontrol-move-oom-task-exclusion-to-tasklist +++ a/include/linux/memcontrol.h @@ -45,6 +45,7 @@ extern unsigned long mem_cgroup_isolate_ extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); +int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); static inline struct mem_cgroup *mm_cgroup(const struct mm_struct *mm) { @@ -107,6 +108,12 @@ static inline struct mem_cgroup *mm_cgro return NULL; } +static inline int task_in_mem_cgroup(struct task_struct *task, + const struct mem_cgroup *mem) +{ + return 1; +} + #endif /* CONFIG_CGROUP_MEM_CONT */ #endif /* _LINUX_MEMCONTROL_H */ diff -puN mm/memcontrol.c~memcontrol-move-oom-task-exclusion-to-tasklist mm/memcontrol.c --- a/mm/memcontrol.c~memcontrol-move-oom-task-exclusion-to-tasklist +++ a/mm/memcontrol.c @@ -170,6 +170,16 @@ static void __mem_cgroup_move_lists(stru list_move(&pc->lru, &pc->mem_cgroup->inactive_list); } +int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) +{ + int ret; + + task_lock(task); + ret = task->mm && mm_cgroup(task->mm) == mem; + task_unlock(task); + return ret; +} + /* * This routine assumes that the appropriate zone's lru lock is already held */ diff -puN mm/oom_kill.c~memcontrol-move-oom-task-exclusion-to-tasklist mm/oom_kill.c --- a/mm/oom_kill.c~memcontrol-move-oom-task-exclusion-to-tasklist +++ a/mm/oom_kill.c @@ -65,13 +65,6 @@ unsigned long badness(struct task_struct return 0; } -#ifdef CONFIG_CGROUP_MEM_CONT - if (mem != NULL && mm->mem_cgroup != mem) { - task_unlock(p); - return 0; - } -#endif - /* * The memory size of the process is the basis for the badness. */ @@ -223,6 +216,8 @@ static struct task_struct *select_bad_pr /* skip the init task */ if (is_global_init(p)) continue; + if (mem && !task_in_mem_cgroup(p, mem)) + continue; /* * This task already has access to memory reserves and is _