aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Rientjes <rientjes@google.com>2007-10-17 02:25:58 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:42:46 -0400
commitbbe373f2c60b2aa36c3231734a5afc5271a06718 (patch)
tree00146d69594672ca41e35be8ff9b349e8751ab5c
parent7213f5066fc8a17c78389fe245de522b5cf0648a (diff)
oom: compare cpuset mems_allowed instead of exclusive ancestors
Instead of testing for overlap in the memory nodes of the the nearest exclusive ancestor of both current and the candidate task, it is better to simply test for intersection between the task's mems_allowed in their task descriptors. This does not require taking callback_mutex since it is only used as a hint in the badness scoring. Tasks that do not have an intersection in their mems_allowed with the current task are not explicitly restricted from being OOM killed because it is quite possible that the candidate task has allocated memory there before and has since changed its mems_allowed. Cc: Andrea Arcangeli <andrea@suse.de> Acked-by: Christoph Lameter <clameter@sgi.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/cpuset.h6
-rw-r--r--kernel/cpuset.c43
-rw-r--r--mm/oom_kill.c2
3 files changed, 16 insertions, 35 deletions
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 9e633ea103ce..ea44d2e768a0 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -45,7 +45,8 @@ static int inline cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
45 __cpuset_zone_allowed_hardwall(z, gfp_mask); 45 __cpuset_zone_allowed_hardwall(z, gfp_mask);
46} 46}
47 47
48extern int cpuset_excl_nodes_overlap(const struct task_struct *p); 48extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
49 const struct task_struct *tsk2);
49 50
50#define cpuset_memory_pressure_bump() \ 51#define cpuset_memory_pressure_bump() \
51 do { \ 52 do { \
@@ -113,7 +114,8 @@ static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
113 return 1; 114 return 1;
114} 115}
115 116
116static inline int cpuset_excl_nodes_overlap(const struct task_struct *p) 117static inline int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
118 const struct task_struct *tsk2)
117{ 119{
118 return 1; 120 return 1;
119} 121}
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 0864f4097930..2eb2e50db0d6 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -2506,41 +2506,20 @@ int cpuset_mem_spread_node(void)
2506EXPORT_SYMBOL_GPL(cpuset_mem_spread_node); 2506EXPORT_SYMBOL_GPL(cpuset_mem_spread_node);
2507 2507
2508/** 2508/**
2509 * cpuset_excl_nodes_overlap - Do we overlap @p's mem_exclusive ancestors? 2509 * cpuset_mems_allowed_intersects - Does @tsk1's mems_allowed intersect @tsk2's?
2510 * @p: pointer to task_struct of some other task. 2510 * @tsk1: pointer to task_struct of some task.
2511 * 2511 * @tsk2: pointer to task_struct of some other task.
2512 * Description: Return true if the nearest mem_exclusive ancestor 2512 *
2513 * cpusets of tasks @p and current overlap. Used by oom killer to 2513 * Description: Return true if @tsk1's mems_allowed intersects the
2514 * determine if task @p's memory usage might impact the memory 2514 * mems_allowed of @tsk2. Used by the OOM killer to determine if
2515 * available to the current task. 2515 * one of the task's memory usage might impact the memory available
2516 * 2516 * to the other.
2517 * Call while holding callback_mutex.
2518 **/ 2517 **/
2519 2518
2520int cpuset_excl_nodes_overlap(const struct task_struct *p) 2519int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
2520 const struct task_struct *tsk2)
2521{ 2521{
2522 const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */ 2522 return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed);
2523 int overlap = 1; /* do cpusets overlap? */
2524
2525 task_lock(current);
2526 if (current->flags & PF_EXITING) {
2527 task_unlock(current);
2528 goto done;
2529 }
2530 cs1 = nearest_exclusive_ancestor(current->cpuset);
2531 task_unlock(current);
2532
2533 task_lock((struct task_struct *)p);
2534 if (p->flags & PF_EXITING) {
2535 task_unlock((struct task_struct *)p);
2536 goto done;
2537 }
2538 cs2 = nearest_exclusive_ancestor(p->cpuset);
2539 task_unlock((struct task_struct *)p);
2540
2541 overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
2542done:
2543 return overlap;
2544} 2523}
2545 2524
2546/* 2525/*
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 5c5aa7380bd1..d9bba82923d5 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -143,7 +143,7 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
143 * because p may have allocated or otherwise mapped memory on 143 * because p may have allocated or otherwise mapped memory on
144 * this node before. However it will be less likely. 144 * this node before. However it will be less likely.
145 */ 145 */
146 if (!cpuset_excl_nodes_overlap(p)) 146 if (!cpuset_mems_allowed_intersects(current, p))
147 points /= 8; 147 points /= 8;
148 148
149 /* 149 /*