Commit b78483a4ba60d5d90930262a533a784e1d9df660

Authored by Nick Piggin
Committed by Linus Torvalds
1 parent 01017a2270

[PATCH] oom: don't kill current when another OOM in progress

A previous patch to allow an exiting task to OOM kill itself (and thereby
avoid a little deadlock) introduced a problem.  We don't want the
PF_EXITING task, even if it is 'current', to access mem reserves if there
is already a TIF_MEMDIE process in the system sucking up reserves.

Also make the commenting a little bit clearer, and note that our current
scheme of effectively single threading the OOM killer is not itself
perfect.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 17 additions and 6 deletions Side-by-side Diff

... ... @@ -216,6 +216,18 @@
216 216 continue;
217 217  
218 218 /*
  219 + * This task already has access to memory reserves and is
  220 + * being killed. Don't allow any other task access to the
  221 + * memory reserve.
  222 + *
  223 + * Note: this may have a chance of deadlock if it gets
  224 + * blocked waiting for another task which itself is waiting
  225 + * for memory. Is there a better alternative?
  226 + */
  227 + if (test_tsk_thread_flag(p, TIF_MEMDIE))
  228 + return ERR_PTR(-1UL);
  229 +
  230 + /*
219 231 * This is in the process of releasing memory so wait for it
220 232 * to finish before killing some other task by mistake.
221 233 *
222 234  
223 235  
224 236  
... ... @@ -223,16 +235,15 @@
223 235 * go ahead if it is exiting: this will simply set TIF_MEMDIE,
224 236 * which will allow it to gain access to memory reserves in
225 237 * the process of exiting and releasing its resources.
226   - * Otherwise we could get an OOM deadlock.
  238 + * Otherwise we could get an easy OOM deadlock.
227 239 */
228   - if ((p->flags & PF_EXITING) && p == current) {
  240 + if (p->flags & PF_EXITING) {
  241 + if (p != current)
  242 + return ERR_PTR(-1UL);
  243 +
229 244 chosen = p;
230 245 *ppoints = ULONG_MAX;
231   - break;
232 246 }
233   - if ((p->flags & PF_EXITING) ||
234   - test_tsk_thread_flag(p, TIF_MEMDIE))
235   - return ERR_PTR(-1UL);
236 247  
237 248 if (p->oomkilladj == OOM_DISABLE)
238 249 continue;