aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/oom_kill.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 4f815b06ac1b..0131bae2a16d 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -210,11 +210,26 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
210 /* 210 /*
211 * This is in the process of releasing memory so wait for it 211 * This is in the process of releasing memory so wait for it
212 * to finish before killing some other task by mistake. 212 * to finish before killing some other task by mistake.
213 *
214 * However, if p is the current task, we allow the 'kill' to
215 * go ahead if it is exiting: this will simply set TIF_MEMDIE,
216 * which will allow it to gain access to memory reserves in
217 * the process of exiting and releasing its resources.
218 * Otherwise we could get an OOM deadlock.
213 */ 219 */
214 releasing = test_tsk_thread_flag(p, TIF_MEMDIE) || 220 releasing = test_tsk_thread_flag(p, TIF_MEMDIE) ||
215 p->flags & PF_EXITING; 221 p->flags & PF_EXITING;
216 if (releasing && !(p->flags & PF_DEAD)) 222 if (releasing) {
223 /* PF_DEAD tasks have already released their mm */
224 if (p->flags & PF_DEAD)
225 continue;
226 if (p->flags & PF_EXITING && p == current) {
227 chosen = p;
228 *ppoints = ULONG_MAX;
229 break;
230 }
217 return ERR_PTR(-1UL); 231 return ERR_PTR(-1UL);
232 }
218 if (p->flags & PF_SWAPOFF) 233 if (p->flags & PF_SWAPOFF)
219 return p; 234 return p;
220 235
@@ -248,8 +263,11 @@ static void __oom_kill_task(struct task_struct *p, const char *message)
248 return; 263 return;
249 } 264 }
250 task_unlock(p); 265 task_unlock(p);
251 printk(KERN_ERR "%s: Killed process %d (%s).\n", 266
267 if (message) {
268 printk(KERN_ERR "%s: Killed process %d (%s).\n",
252 message, p->pid, p->comm); 269 message, p->pid, p->comm);
270 }
253 271
254 /* 272 /*
255 * We give our sacrificial lamb high priority and access to 273 * We give our sacrificial lamb high priority and access to
@@ -300,8 +318,17 @@ static int oom_kill_process(struct task_struct *p, unsigned long points,
300 struct task_struct *c; 318 struct task_struct *c;
301 struct list_head *tsk; 319 struct list_head *tsk;
302 320
303 printk(KERN_ERR "Out of Memory: Kill process %d (%s) score %li and " 321 /*
304 "children.\n", p->pid, p->comm, points); 322 * If the task is already exiting, don't alarm the sysadmin or kill
323 * its children or threads, just set TIF_MEMDIE so it can die quickly
324 */
325 if (p->flags & PF_EXITING) {
326 __oom_kill_task(p, NULL);
327 return 0;
328 }
329
330 printk(KERN_ERR "Out of Memory: Kill process %d (%s) score %li"
331 " and children.\n", p->pid, p->comm, points);
305 /* Try to kill a child first */ 332 /* Try to kill a child first */
306 list_for_each(tsk, &p->children) { 333 list_for_each(tsk, &p->children) {
307 c = list_entry(tsk, struct task_struct, sibling); 334 c = list_entry(tsk, struct task_struct, sibling);