Commit b78483a4ba60d5d90930262a533a784e1d9df660
Committed by
Linus Torvalds
1 parent
01017a2270
Exists in
master
and in
7 other branches
[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
mm/oom_kill.c
... | ... | @@ -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; |