diff options
author | David Rientjes <rientjes@google.com> | 2007-10-17 02:25:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 11:42:46 -0400 |
commit | bbe373f2c60b2aa36c3231734a5afc5271a06718 (patch) | |
tree | 00146d69594672ca41e35be8ff9b349e8751ab5c /kernel | |
parent | 7213f5066fc8a17c78389fe245de522b5cf0648a (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>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cpuset.c | 43 |
1 files changed, 11 insertions, 32 deletions
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) | |||
2506 | EXPORT_SYMBOL_GPL(cpuset_mem_spread_node); | 2506 | EXPORT_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 | ||
2520 | int cpuset_excl_nodes_overlap(const struct task_struct *p) | 2519 | int 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); | ||
2542 | done: | ||
2543 | return overlap; | ||
2544 | } | 2523 | } |
2545 | 2524 | ||
2546 | /* | 2525 | /* |