diff options
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r-- | mm/oom_kill.c | 223 |
1 files changed, 112 insertions, 111 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index ac300c99baf6..198600861638 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -288,76 +288,93 @@ static enum oom_constraint constrained_alloc(struct zonelist *zonelist, | |||
288 | } | 288 | } |
289 | #endif | 289 | #endif |
290 | 290 | ||
291 | enum oom_scan_t oom_scan_process_thread(struct task_struct *task, | ||
292 | unsigned long totalpages, const nodemask_t *nodemask, | ||
293 | bool force_kill) | ||
294 | { | ||
295 | if (task->exit_state) | ||
296 | return OOM_SCAN_CONTINUE; | ||
297 | if (oom_unkillable_task(task, NULL, nodemask)) | ||
298 | return OOM_SCAN_CONTINUE; | ||
299 | |||
300 | /* | ||
301 | * This task already has access to memory reserves and is being killed. | ||
302 | * Don't allow any other task to have access to the reserves. | ||
303 | */ | ||
304 | if (test_tsk_thread_flag(task, TIF_MEMDIE)) { | ||
305 | if (unlikely(frozen(task))) | ||
306 | __thaw_task(task); | ||
307 | if (!force_kill) | ||
308 | return OOM_SCAN_ABORT; | ||
309 | } | ||
310 | if (!task->mm) | ||
311 | return OOM_SCAN_CONTINUE; | ||
312 | |||
313 | if (task->flags & PF_EXITING) { | ||
314 | /* | ||
315 | * If task is current and is in the process of releasing memory, | ||
316 | * allow the "kill" to set TIF_MEMDIE, which will allow it to | ||
317 | * access memory reserves. Otherwise, it may stall forever. | ||
318 | * | ||
319 | * The iteration isn't broken here, however, in case other | ||
320 | * threads are found to have already been oom killed. | ||
321 | */ | ||
322 | if (task == current) | ||
323 | return OOM_SCAN_SELECT; | ||
324 | else if (!force_kill) { | ||
325 | /* | ||
326 | * If this task is not being ptraced on exit, then wait | ||
327 | * for it to finish before killing some other task | ||
328 | * unnecessarily. | ||
329 | */ | ||
330 | if (!(task->group_leader->ptrace & PT_TRACE_EXIT)) | ||
331 | return OOM_SCAN_ABORT; | ||
332 | } | ||
333 | } | ||
334 | return OOM_SCAN_OK; | ||
335 | } | ||
336 | |||
291 | /* | 337 | /* |
292 | * Simple selection loop. We chose the process with the highest | 338 | * Simple selection loop. We chose the process with the highest |
293 | * number of 'points'. We expect the caller will lock the tasklist. | 339 | * number of 'points'. |
294 | * | 340 | * |
295 | * (not docbooked, we don't want this one cluttering up the manual) | 341 | * (not docbooked, we don't want this one cluttering up the manual) |
296 | */ | 342 | */ |
297 | static struct task_struct *select_bad_process(unsigned int *ppoints, | 343 | static struct task_struct *select_bad_process(unsigned int *ppoints, |
298 | unsigned long totalpages, struct mem_cgroup *memcg, | 344 | unsigned long totalpages, const nodemask_t *nodemask, |
299 | const nodemask_t *nodemask, bool force_kill) | 345 | bool force_kill) |
300 | { | 346 | { |
301 | struct task_struct *g, *p; | 347 | struct task_struct *g, *p; |
302 | struct task_struct *chosen = NULL; | 348 | struct task_struct *chosen = NULL; |
303 | unsigned long chosen_points = 0; | 349 | unsigned long chosen_points = 0; |
304 | 350 | ||
351 | rcu_read_lock(); | ||
305 | do_each_thread(g, p) { | 352 | do_each_thread(g, p) { |
306 | unsigned int points; | 353 | unsigned int points; |
307 | 354 | ||
308 | if (p->exit_state) | 355 | switch (oom_scan_process_thread(p, totalpages, nodemask, |
309 | continue; | 356 | force_kill)) { |
310 | if (oom_unkillable_task(p, memcg, nodemask)) | 357 | case OOM_SCAN_SELECT: |
311 | continue; | 358 | chosen = p; |
312 | 359 | chosen_points = ULONG_MAX; | |
313 | /* | 360 | /* fall through */ |
314 | * This task already has access to memory reserves and is | 361 | case OOM_SCAN_CONTINUE: |
315 | * being killed. Don't allow any other task access to the | ||
316 | * memory reserve. | ||
317 | * | ||
318 | * Note: this may have a chance of deadlock if it gets | ||
319 | * blocked waiting for another task which itself is waiting | ||
320 | * for memory. Is there a better alternative? | ||
321 | */ | ||
322 | if (test_tsk_thread_flag(p, TIF_MEMDIE)) { | ||
323 | if (unlikely(frozen(p))) | ||
324 | __thaw_task(p); | ||
325 | if (!force_kill) | ||
326 | return ERR_PTR(-1UL); | ||
327 | } | ||
328 | if (!p->mm) | ||
329 | continue; | 362 | continue; |
330 | 363 | case OOM_SCAN_ABORT: | |
331 | if (p->flags & PF_EXITING) { | 364 | rcu_read_unlock(); |
332 | /* | 365 | return ERR_PTR(-1UL); |
333 | * If p is the current task and is in the process of | 366 | case OOM_SCAN_OK: |
334 | * releasing memory, we allow the "kill" to set | 367 | break; |
335 | * TIF_MEMDIE, which will allow it to gain access to | 368 | }; |
336 | * memory reserves. Otherwise, it may stall forever. | 369 | points = oom_badness(p, NULL, nodemask, totalpages); |
337 | * | ||
338 | * The loop isn't broken here, however, in case other | ||
339 | * threads are found to have already been oom killed. | ||
340 | */ | ||
341 | if (p == current) { | ||
342 | chosen = p; | ||
343 | chosen_points = ULONG_MAX; | ||
344 | } else if (!force_kill) { | ||
345 | /* | ||
346 | * If this task is not being ptraced on exit, | ||
347 | * then wait for it to finish before killing | ||
348 | * some other task unnecessarily. | ||
349 | */ | ||
350 | if (!(p->group_leader->ptrace & PT_TRACE_EXIT)) | ||
351 | return ERR_PTR(-1UL); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | points = oom_badness(p, memcg, nodemask, totalpages); | ||
356 | if (points > chosen_points) { | 370 | if (points > chosen_points) { |
357 | chosen = p; | 371 | chosen = p; |
358 | chosen_points = points; | 372 | chosen_points = points; |
359 | } | 373 | } |
360 | } while_each_thread(g, p); | 374 | } while_each_thread(g, p); |
375 | if (chosen) | ||
376 | get_task_struct(chosen); | ||
377 | rcu_read_unlock(); | ||
361 | 378 | ||
362 | *ppoints = chosen_points * 1000 / totalpages; | 379 | *ppoints = chosen_points * 1000 / totalpages; |
363 | return chosen; | 380 | return chosen; |
@@ -371,17 +388,16 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, | |||
371 | * Dumps the current memory state of all eligible tasks. Tasks not in the same | 388 | * Dumps the current memory state of all eligible tasks. Tasks not in the same |
372 | * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes | 389 | * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes |
373 | * are not shown. | 390 | * are not shown. |
374 | * State information includes task's pid, uid, tgid, vm size, rss, cpu, oom_adj | 391 | * State information includes task's pid, uid, tgid, vm size, rss, nr_ptes, |
375 | * value, oom_score_adj value, and name. | 392 | * swapents, oom_score_adj value, and name. |
376 | * | ||
377 | * Call with tasklist_lock read-locked. | ||
378 | */ | 393 | */ |
379 | static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemask) | 394 | static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemask) |
380 | { | 395 | { |
381 | struct task_struct *p; | 396 | struct task_struct *p; |
382 | struct task_struct *task; | 397 | struct task_struct *task; |
383 | 398 | ||
384 | pr_info("[ pid ] uid tgid total_vm rss cpu oom_adj oom_score_adj name\n"); | 399 | pr_info("[ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name\n"); |
400 | rcu_read_lock(); | ||
385 | for_each_process(p) { | 401 | for_each_process(p) { |
386 | if (oom_unkillable_task(p, memcg, nodemask)) | 402 | if (oom_unkillable_task(p, memcg, nodemask)) |
387 | continue; | 403 | continue; |
@@ -396,13 +412,15 @@ static void dump_tasks(const struct mem_cgroup *memcg, const nodemask_t *nodemas | |||
396 | continue; | 412 | continue; |
397 | } | 413 | } |
398 | 414 | ||
399 | pr_info("[%5d] %5d %5d %8lu %8lu %3u %3d %5d %s\n", | 415 | pr_info("[%5d] %5d %5d %8lu %8lu %7lu %8lu %5d %s\n", |
400 | task->pid, from_kuid(&init_user_ns, task_uid(task)), | 416 | task->pid, from_kuid(&init_user_ns, task_uid(task)), |
401 | task->tgid, task->mm->total_vm, get_mm_rss(task->mm), | 417 | task->tgid, task->mm->total_vm, get_mm_rss(task->mm), |
402 | task_cpu(task), task->signal->oom_adj, | 418 | task->mm->nr_ptes, |
419 | get_mm_counter(task->mm, MM_SWAPENTS), | ||
403 | task->signal->oom_score_adj, task->comm); | 420 | task->signal->oom_score_adj, task->comm); |
404 | task_unlock(task); | 421 | task_unlock(task); |
405 | } | 422 | } |
423 | rcu_read_unlock(); | ||
406 | } | 424 | } |
407 | 425 | ||
408 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | 426 | static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, |
@@ -423,10 +441,14 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order, | |||
423 | } | 441 | } |
424 | 442 | ||
425 | #define K(x) ((x) << (PAGE_SHIFT-10)) | 443 | #define K(x) ((x) << (PAGE_SHIFT-10)) |
426 | static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | 444 | /* |
427 | unsigned int points, unsigned long totalpages, | 445 | * Must be called while holding a reference to p, which will be released upon |
428 | struct mem_cgroup *memcg, nodemask_t *nodemask, | 446 | * returning. |
429 | const char *message) | 447 | */ |
448 | void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | ||
449 | unsigned int points, unsigned long totalpages, | ||
450 | struct mem_cgroup *memcg, nodemask_t *nodemask, | ||
451 | const char *message) | ||
430 | { | 452 | { |
431 | struct task_struct *victim = p; | 453 | struct task_struct *victim = p; |
432 | struct task_struct *child; | 454 | struct task_struct *child; |
@@ -442,6 +464,7 @@ static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
442 | */ | 464 | */ |
443 | if (p->flags & PF_EXITING) { | 465 | if (p->flags & PF_EXITING) { |
444 | set_tsk_thread_flag(p, TIF_MEMDIE); | 466 | set_tsk_thread_flag(p, TIF_MEMDIE); |
467 | put_task_struct(p); | ||
445 | return; | 468 | return; |
446 | } | 469 | } |
447 | 470 | ||
@@ -459,6 +482,7 @@ static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
459 | * parent. This attempts to lose the minimal amount of work done while | 482 | * parent. This attempts to lose the minimal amount of work done while |
460 | * still freeing memory. | 483 | * still freeing memory. |
461 | */ | 484 | */ |
485 | read_lock(&tasklist_lock); | ||
462 | do { | 486 | do { |
463 | list_for_each_entry(child, &t->children, sibling) { | 487 | list_for_each_entry(child, &t->children, sibling) { |
464 | unsigned int child_points; | 488 | unsigned int child_points; |
@@ -471,15 +495,26 @@ static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
471 | child_points = oom_badness(child, memcg, nodemask, | 495 | child_points = oom_badness(child, memcg, nodemask, |
472 | totalpages); | 496 | totalpages); |
473 | if (child_points > victim_points) { | 497 | if (child_points > victim_points) { |
498 | put_task_struct(victim); | ||
474 | victim = child; | 499 | victim = child; |
475 | victim_points = child_points; | 500 | victim_points = child_points; |
501 | get_task_struct(victim); | ||
476 | } | 502 | } |
477 | } | 503 | } |
478 | } while_each_thread(p, t); | 504 | } while_each_thread(p, t); |
505 | read_unlock(&tasklist_lock); | ||
479 | 506 | ||
480 | victim = find_lock_task_mm(victim); | 507 | rcu_read_lock(); |
481 | if (!victim) | 508 | p = find_lock_task_mm(victim); |
509 | if (!p) { | ||
510 | rcu_read_unlock(); | ||
511 | put_task_struct(victim); | ||
482 | return; | 512 | return; |
513 | } else if (victim != p) { | ||
514 | get_task_struct(p); | ||
515 | put_task_struct(victim); | ||
516 | victim = p; | ||
517 | } | ||
483 | 518 | ||
484 | /* mm cannot safely be dereferenced after task_unlock(victim) */ | 519 | /* mm cannot safely be dereferenced after task_unlock(victim) */ |
485 | mm = victim->mm; | 520 | mm = victim->mm; |
@@ -510,17 +545,19 @@ static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, | |||
510 | task_unlock(p); | 545 | task_unlock(p); |
511 | do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true); | 546 | do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true); |
512 | } | 547 | } |
548 | rcu_read_unlock(); | ||
513 | 549 | ||
514 | set_tsk_thread_flag(victim, TIF_MEMDIE); | 550 | set_tsk_thread_flag(victim, TIF_MEMDIE); |
515 | do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true); | 551 | do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true); |
552 | put_task_struct(victim); | ||
516 | } | 553 | } |
517 | #undef K | 554 | #undef K |
518 | 555 | ||
519 | /* | 556 | /* |
520 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. | 557 | * Determines whether the kernel must panic because of the panic_on_oom sysctl. |
521 | */ | 558 | */ |
522 | static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | 559 | void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, |
523 | int order, const nodemask_t *nodemask) | 560 | int order, const nodemask_t *nodemask) |
524 | { | 561 | { |
525 | if (likely(!sysctl_panic_on_oom)) | 562 | if (likely(!sysctl_panic_on_oom)) |
526 | return; | 563 | return; |
@@ -533,42 +570,11 @@ static void check_panic_on_oom(enum oom_constraint constraint, gfp_t gfp_mask, | |||
533 | if (constraint != CONSTRAINT_NONE) | 570 | if (constraint != CONSTRAINT_NONE) |
534 | return; | 571 | return; |
535 | } | 572 | } |
536 | read_lock(&tasklist_lock); | ||
537 | dump_header(NULL, gfp_mask, order, NULL, nodemask); | 573 | dump_header(NULL, gfp_mask, order, NULL, nodemask); |
538 | read_unlock(&tasklist_lock); | ||
539 | panic("Out of memory: %s panic_on_oom is enabled\n", | 574 | panic("Out of memory: %s panic_on_oom is enabled\n", |
540 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); | 575 | sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); |
541 | } | 576 | } |
542 | 577 | ||
543 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
544 | void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, | ||
545 | int order) | ||
546 | { | ||
547 | unsigned long limit; | ||
548 | unsigned int points = 0; | ||
549 | struct task_struct *p; | ||
550 | |||
551 | /* | ||
552 | * If current has a pending SIGKILL, then automatically select it. The | ||
553 | * goal is to allow it to allocate so that it may quickly exit and free | ||
554 | * its memory. | ||
555 | */ | ||
556 | if (fatal_signal_pending(current)) { | ||
557 | set_thread_flag(TIF_MEMDIE); | ||
558 | return; | ||
559 | } | ||
560 | |||
561 | check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, order, NULL); | ||
562 | limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT ? : 1; | ||
563 | read_lock(&tasklist_lock); | ||
564 | p = select_bad_process(&points, limit, memcg, NULL, false); | ||
565 | if (p && PTR_ERR(p) != -1UL) | ||
566 | oom_kill_process(p, gfp_mask, order, points, limit, memcg, NULL, | ||
567 | "Memory cgroup out of memory"); | ||
568 | read_unlock(&tasklist_lock); | ||
569 | } | ||
570 | #endif | ||
571 | |||
572 | static BLOCKING_NOTIFIER_HEAD(oom_notify_list); | 578 | static BLOCKING_NOTIFIER_HEAD(oom_notify_list); |
573 | 579 | ||
574 | int register_oom_notifier(struct notifier_block *nb) | 580 | int register_oom_notifier(struct notifier_block *nb) |
@@ -690,7 +696,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
690 | struct task_struct *p; | 696 | struct task_struct *p; |
691 | unsigned long totalpages; | 697 | unsigned long totalpages; |
692 | unsigned long freed = 0; | 698 | unsigned long freed = 0; |
693 | unsigned int points; | 699 | unsigned int uninitialized_var(points); |
694 | enum oom_constraint constraint = CONSTRAINT_NONE; | 700 | enum oom_constraint constraint = CONSTRAINT_NONE; |
695 | int killed = 0; | 701 | int killed = 0; |
696 | 702 | ||
@@ -718,22 +724,20 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
718 | mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL; | 724 | mpol_mask = (constraint == CONSTRAINT_MEMORY_POLICY) ? nodemask : NULL; |
719 | check_panic_on_oom(constraint, gfp_mask, order, mpol_mask); | 725 | check_panic_on_oom(constraint, gfp_mask, order, mpol_mask); |
720 | 726 | ||
721 | read_lock(&tasklist_lock); | 727 | if (sysctl_oom_kill_allocating_task && current->mm && |
722 | if (sysctl_oom_kill_allocating_task && | ||
723 | !oom_unkillable_task(current, NULL, nodemask) && | 728 | !oom_unkillable_task(current, NULL, nodemask) && |
724 | current->mm) { | 729 | current->signal->oom_score_adj != OOM_SCORE_ADJ_MIN) { |
730 | get_task_struct(current); | ||
725 | oom_kill_process(current, gfp_mask, order, 0, totalpages, NULL, | 731 | oom_kill_process(current, gfp_mask, order, 0, totalpages, NULL, |
726 | nodemask, | 732 | nodemask, |
727 | "Out of memory (oom_kill_allocating_task)"); | 733 | "Out of memory (oom_kill_allocating_task)"); |
728 | goto out; | 734 | goto out; |
729 | } | 735 | } |
730 | 736 | ||
731 | p = select_bad_process(&points, totalpages, NULL, mpol_mask, | 737 | p = select_bad_process(&points, totalpages, mpol_mask, force_kill); |
732 | force_kill); | ||
733 | /* Found nothing?!?! Either we hang forever, or we panic. */ | 738 | /* Found nothing?!?! Either we hang forever, or we panic. */ |
734 | if (!p) { | 739 | if (!p) { |
735 | dump_header(NULL, gfp_mask, order, NULL, mpol_mask); | 740 | dump_header(NULL, gfp_mask, order, NULL, mpol_mask); |
736 | read_unlock(&tasklist_lock); | ||
737 | panic("Out of memory and no killable processes...\n"); | 741 | panic("Out of memory and no killable processes...\n"); |
738 | } | 742 | } |
739 | if (PTR_ERR(p) != -1UL) { | 743 | if (PTR_ERR(p) != -1UL) { |
@@ -742,14 +746,12 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, | |||
742 | killed = 1; | 746 | killed = 1; |
743 | } | 747 | } |
744 | out: | 748 | out: |
745 | read_unlock(&tasklist_lock); | ||
746 | |||
747 | /* | 749 | /* |
748 | * Give "p" a good chance of killing itself before we | 750 | * Give the killed threads a good chance of exiting before trying to |
749 | * retry to allocate memory unless "p" is current | 751 | * allocate memory again. |
750 | */ | 752 | */ |
751 | if (killed && !test_thread_flag(TIF_MEMDIE)) | 753 | if (killed) |
752 | schedule_timeout_uninterruptible(1); | 754 | schedule_timeout_killable(1); |
753 | } | 755 | } |
754 | 756 | ||
755 | /* | 757 | /* |
@@ -764,6 +766,5 @@ void pagefault_out_of_memory(void) | |||
764 | out_of_memory(NULL, 0, 0, NULL, false); | 766 | out_of_memory(NULL, 0, 0, NULL, false); |
765 | clear_system_oom(); | 767 | clear_system_oom(); |
766 | } | 768 | } |
767 | if (!test_thread_flag(TIF_MEMDIE)) | 769 | schedule_timeout_killable(1); |
768 | schedule_timeout_uninterruptible(1); | ||
769 | } | 770 | } |