summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rientjes <rientjes@google.com>2008-02-07 08:14:06 (GMT)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 16:42:19 (GMT)
commit4c4a22148909e4c003562ea7ffe0a06e26919e3c (patch)
treefa8b7d00e89f0eb4cdb4394dbc74d898810519aa
parent4c6bc8dd5a0932f2c0b30a5f0a124464b7f614d0 (diff)
downloadlinux-fsl-qoriq-4c4a22148909e4c003562ea7ffe0a06e26919e3c.tar.xz
memcontrol: move oom task exclusion to tasklist scan
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. [akpm@linux-foundation.org: build fix] Cc: Christoph Lameter <clameter@sgi.com> Cc: Balbir Singh <balbir@linux.vnet.ibm.com> Signed-off-by: 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--include/linux/memcontrol.h7
-rw-r--r--mm/memcontrol.c10
-rw-r--r--mm/oom_kill.c9
3 files changed, 19 insertions, 7 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 4f58026..42536c7 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -48,6 +48,7 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
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)
{
@@ -110,6 +111,12 @@ static inline struct mem_cgroup *mm_cgroup(const struct mm_struct *mm)
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 --git a/mm/memcontrol.c b/mm/memcontrol.c
index f6cdbf7..2fadd48 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -170,6 +170,16 @@ static void __mem_cgroup_move_lists(struct page_cgroup *pc, bool active)
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 --git a/mm/oom_kill.c b/mm/oom_kill.c
index 64751dc..ef5084d 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -65,13 +65,6 @@ unsigned long badness(struct task_struct *p, unsigned long uptime,
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_process(unsigned long *ppoints,
/* 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