aboutsummaryrefslogtreecommitdiffstats
path: root/mm/oom_kill.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r--mm/oom_kill.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 2e3ce3a928b9..223d9ccb7d64 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -264,7 +264,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
264 * flag though it's unlikely that we select a process with CAP_SYS_RAW_IO 264 * flag though it's unlikely that we select a process with CAP_SYS_RAW_IO
265 * set. 265 * set.
266 */ 266 */
267static void __oom_kill_task(struct task_struct *p, const char *message) 267static void __oom_kill_task(struct task_struct *p, int verbose)
268{ 268{
269 if (is_init(p)) { 269 if (is_init(p)) {
270 WARN_ON(1); 270 WARN_ON(1);
@@ -278,10 +278,8 @@ static void __oom_kill_task(struct task_struct *p, const char *message)
278 return; 278 return;
279 } 279 }
280 280
281 if (message) { 281 if (verbose)
282 printk(KERN_ERR "%s: Killed process %d (%s).\n", 282 printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
283 message, p->pid, p->comm);
284 }
285 283
286 /* 284 /*
287 * We give our sacrificial lamb high priority and access to 285 * We give our sacrificial lamb high priority and access to
@@ -294,7 +292,7 @@ static void __oom_kill_task(struct task_struct *p, const char *message)
294 force_sig(SIGKILL, p); 292 force_sig(SIGKILL, p);
295} 293}
296 294
297static int oom_kill_task(struct task_struct *p, const char *message) 295static int oom_kill_task(struct task_struct *p)
298{ 296{
299 struct mm_struct *mm; 297 struct mm_struct *mm;
300 struct task_struct *g, *q; 298 struct task_struct *g, *q;
@@ -313,15 +311,25 @@ static int oom_kill_task(struct task_struct *p, const char *message)
313 if (mm == NULL) 311 if (mm == NULL)
314 return 1; 312 return 1;
315 313
316 __oom_kill_task(p, message); 314 /*
315 * Don't kill the process if any threads are set to OOM_DISABLE
316 */
317 do_each_thread(g, q) {
318 if (q->mm == mm && p->oomkilladj == OOM_DISABLE)
319 return 1;
320 } while_each_thread(g, q);
321
322 __oom_kill_task(p, 1);
323
317 /* 324 /*
318 * kill all processes that share the ->mm (i.e. all threads), 325 * kill all processes that share the ->mm (i.e. all threads),
319 * but are in a different thread group 326 * but are in a different thread group. Don't let them have access
327 * to memory reserves though, otherwise we might deplete all memory.
320 */ 328 */
321 do_each_thread(g, q) 329 do_each_thread(g, q) {
322 if (q->mm == mm && q->tgid != p->tgid) 330 if (q->mm == mm && q->tgid != p->tgid)
323 __oom_kill_task(q, message); 331 force_sig(SIGKILL, p);
324 while_each_thread(g, q); 332 } while_each_thread(g, q);
325 333
326 return 0; 334 return 0;
327} 335}
@@ -337,21 +345,22 @@ static int oom_kill_process(struct task_struct *p, unsigned long points,
337 * its children or threads, just set TIF_MEMDIE so it can die quickly 345 * its children or threads, just set TIF_MEMDIE so it can die quickly
338 */ 346 */
339 if (p->flags & PF_EXITING) { 347 if (p->flags & PF_EXITING) {
340 __oom_kill_task(p, NULL); 348 __oom_kill_task(p, 0);
341 return 0; 349 return 0;
342 } 350 }
343 351
344 printk(KERN_ERR "Out of Memory: Kill process %d (%s) score %li" 352 printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n",
345 " and children.\n", p->pid, p->comm, points); 353 message, p->pid, p->comm, points);
354
346 /* Try to kill a child first */ 355 /* Try to kill a child first */
347 list_for_each(tsk, &p->children) { 356 list_for_each(tsk, &p->children) {
348 c = list_entry(tsk, struct task_struct, sibling); 357 c = list_entry(tsk, struct task_struct, sibling);
349 if (c->mm == p->mm) 358 if (c->mm == p->mm)
350 continue; 359 continue;
351 if (!oom_kill_task(c, message)) 360 if (!oom_kill_task(c))
352 return 0; 361 return 0;
353 } 362 }
354 return oom_kill_task(p, message); 363 return oom_kill_task(p);
355} 364}
356 365
357static BLOCKING_NOTIFIER_HEAD(oom_notify_list); 366static BLOCKING_NOTIFIER_HEAD(oom_notify_list);