Commit bbe373f2c60b2aa36c3231734a5afc5271a06718

Authored by David Rientjes
Committed by Linus Torvalds
1 parent 7213f5066f

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>

Showing 3 changed files with 16 additions and 35 deletions Side-by-side Diff

include/linux/cpuset.h
... ... @@ -45,7 +45,8 @@
45 45 __cpuset_zone_allowed_hardwall(z, gfp_mask);
46 46 }
47 47  
48   -extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
  48 +extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
  49 + const struct task_struct *tsk2);
49 50  
50 51 #define cpuset_memory_pressure_bump() \
51 52 do { \
... ... @@ -113,7 +114,8 @@
113 114 return 1;
114 115 }
115 116  
116   -static inline int cpuset_excl_nodes_overlap(const struct task_struct *p)
  117 +static inline int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
  118 + const struct task_struct *tsk2)
117 119 {
118 120 return 1;
119 121 }
... ... @@ -2506,41 +2506,20 @@
2506 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?
2510   - * @p: pointer to task_struct of some other task.
  2509 + * cpuset_mems_allowed_intersects - Does @tsk1's mems_allowed intersect @tsk2's?
  2510 + * @tsk1: pointer to task_struct of some task.
  2511 + * @tsk2: pointer to task_struct of some other task.
2511 2512 *
2512   - * Description: Return true if the nearest mem_exclusive ancestor
2513   - * cpusets of tasks @p and current overlap. Used by oom killer to
2514   - * determine if task @p's memory usage might impact the memory
2515   - * available to the current task.
2516   - *
2517   - * Call while holding callback_mutex.
  2513 + * Description: Return true if @tsk1's mems_allowed intersects the
  2514 + * mems_allowed of @tsk2. Used by the OOM killer to determine if
  2515 + * one of the task's memory usage might impact the memory available
  2516 + * to the other.
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 */
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;
  2522 + return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed);
2544 2523 }
2545 2524  
2546 2525 /*
... ... @@ -143,7 +143,7 @@
143 143 * because p may have allocated or otherwise mapped memory on
144 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 147 points /= 8;
148 148  
149 149 /*