diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 101 |
1 files changed, 74 insertions, 27 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index a1b632713e43..08eb8584e2a8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -66,6 +66,7 @@ | |||
| 66 | #include <linux/user-return-notifier.h> | 66 | #include <linux/user-return-notifier.h> |
| 67 | #include <linux/oom.h> | 67 | #include <linux/oom.h> |
| 68 | #include <linux/khugepaged.h> | 68 | #include <linux/khugepaged.h> |
| 69 | #include <linux/signalfd.h> | ||
| 69 | 70 | ||
| 70 | #include <asm/pgtable.h> | 71 | #include <asm/pgtable.h> |
| 71 | #include <asm/pgalloc.h> | 72 | #include <asm/pgalloc.h> |
| @@ -192,6 +193,7 @@ void __put_task_struct(struct task_struct *tsk) | |||
| 192 | WARN_ON(atomic_read(&tsk->usage)); | 193 | WARN_ON(atomic_read(&tsk->usage)); |
| 193 | WARN_ON(tsk == current); | 194 | WARN_ON(tsk == current); |
| 194 | 195 | ||
| 196 | security_task_free(tsk); | ||
| 195 | exit_creds(tsk); | 197 | exit_creds(tsk); |
| 196 | delayacct_tsk_free(tsk); | 198 | delayacct_tsk_free(tsk); |
| 197 | put_signal_struct(tsk->signal); | 199 | put_signal_struct(tsk->signal); |
| @@ -354,7 +356,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
| 354 | charge = 0; | 356 | charge = 0; |
| 355 | if (mpnt->vm_flags & VM_ACCOUNT) { | 357 | if (mpnt->vm_flags & VM_ACCOUNT) { |
| 356 | unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; | 358 | unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; |
| 357 | if (security_vm_enough_memory(len)) | 359 | if (security_vm_enough_memory_mm(oldmm, len)) /* sic */ |
| 358 | goto fail_nomem; | 360 | goto fail_nomem; |
| 359 | charge = len; | 361 | charge = len; |
| 360 | } | 362 | } |
| @@ -510,6 +512,23 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p) | |||
| 510 | return NULL; | 512 | return NULL; |
| 511 | } | 513 | } |
| 512 | 514 | ||
| 515 | static void check_mm(struct mm_struct *mm) | ||
| 516 | { | ||
| 517 | int i; | ||
| 518 | |||
| 519 | for (i = 0; i < NR_MM_COUNTERS; i++) { | ||
| 520 | long x = atomic_long_read(&mm->rss_stat.count[i]); | ||
| 521 | |||
| 522 | if (unlikely(x)) | ||
| 523 | printk(KERN_ALERT "BUG: Bad rss-counter state " | ||
| 524 | "mm:%p idx:%d val:%ld\n", mm, i, x); | ||
| 525 | } | ||
| 526 | |||
| 527 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
| 528 | VM_BUG_ON(mm->pmd_huge_pte); | ||
| 529 | #endif | ||
| 530 | } | ||
| 531 | |||
| 513 | /* | 532 | /* |
| 514 | * Allocate and initialize an mm_struct. | 533 | * Allocate and initialize an mm_struct. |
| 515 | */ | 534 | */ |
| @@ -537,9 +556,7 @@ void __mmdrop(struct mm_struct *mm) | |||
| 537 | mm_free_pgd(mm); | 556 | mm_free_pgd(mm); |
| 538 | destroy_context(mm); | 557 | destroy_context(mm); |
| 539 | mmu_notifier_mm_destroy(mm); | 558 | mmu_notifier_mm_destroy(mm); |
| 540 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 559 | check_mm(mm); |
| 541 | VM_BUG_ON(mm->pmd_huge_pte); | ||
| 542 | #endif | ||
| 543 | free_mm(mm); | 560 | free_mm(mm); |
| 544 | } | 561 | } |
| 545 | EXPORT_SYMBOL_GPL(__mmdrop); | 562 | EXPORT_SYMBOL_GPL(__mmdrop); |
| @@ -667,6 +684,38 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) | |||
| 667 | return mm; | 684 | return mm; |
| 668 | } | 685 | } |
| 669 | 686 | ||
| 687 | static void complete_vfork_done(struct task_struct *tsk) | ||
| 688 | { | ||
| 689 | struct completion *vfork; | ||
| 690 | |||
| 691 | task_lock(tsk); | ||
| 692 | vfork = tsk->vfork_done; | ||
| 693 | if (likely(vfork)) { | ||
| 694 | tsk->vfork_done = NULL; | ||
| 695 | complete(vfork); | ||
| 696 | } | ||
| 697 | task_unlock(tsk); | ||
| 698 | } | ||
| 699 | |||
| 700 | static int wait_for_vfork_done(struct task_struct *child, | ||
| 701 | struct completion *vfork) | ||
| 702 | { | ||
| 703 | int killed; | ||
| 704 | |||
| 705 | freezer_do_not_count(); | ||
| 706 | killed = wait_for_completion_killable(vfork); | ||
| 707 | freezer_count(); | ||
| 708 | |||
| 709 | if (killed) { | ||
| 710 | task_lock(child); | ||
| 711 | child->vfork_done = NULL; | ||
| 712 | task_unlock(child); | ||
| 713 | } | ||
| 714 | |||
| 715 | put_task_struct(child); | ||
| 716 | return killed; | ||
| 717 | } | ||
| 718 | |||
| 670 | /* Please note the differences between mmput and mm_release. | 719 | /* Please note the differences between mmput and mm_release. |
| 671 | * mmput is called whenever we stop holding onto a mm_struct, | 720 | * mmput is called whenever we stop holding onto a mm_struct, |
| 672 | * error success whatever. | 721 | * error success whatever. |
| @@ -682,8 +731,6 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) | |||
| 682 | */ | 731 | */ |
| 683 | void mm_release(struct task_struct *tsk, struct mm_struct *mm) | 732 | void mm_release(struct task_struct *tsk, struct mm_struct *mm) |
| 684 | { | 733 | { |
| 685 | struct completion *vfork_done = tsk->vfork_done; | ||
| 686 | |||
| 687 | /* Get rid of any futexes when releasing the mm */ | 734 | /* Get rid of any futexes when releasing the mm */ |
| 688 | #ifdef CONFIG_FUTEX | 735 | #ifdef CONFIG_FUTEX |
| 689 | if (unlikely(tsk->robust_list)) { | 736 | if (unlikely(tsk->robust_list)) { |
| @@ -703,17 +750,15 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
| 703 | /* Get rid of any cached register state */ | 750 | /* Get rid of any cached register state */ |
| 704 | deactivate_mm(tsk, mm); | 751 | deactivate_mm(tsk, mm); |
| 705 | 752 | ||
| 706 | /* notify parent sleeping on vfork() */ | 753 | if (tsk->vfork_done) |
| 707 | if (vfork_done) { | 754 | complete_vfork_done(tsk); |
| 708 | tsk->vfork_done = NULL; | ||
| 709 | complete(vfork_done); | ||
| 710 | } | ||
| 711 | 755 | ||
| 712 | /* | 756 | /* |
| 713 | * If we're exiting normally, clear a user-space tid field if | 757 | * If we're exiting normally, clear a user-space tid field if |
| 714 | * requested. We leave this alone when dying by signal, to leave | 758 | * requested. We leave this alone when dying by signal, to leave |
| 715 | * the value intact in a core dump, and to save the unnecessary | 759 | * the value intact in a core dump, and to save the unnecessary |
| 716 | * trouble otherwise. Userland only wants this done for a sys_exit. | 760 | * trouble, say, a killed vfork parent shouldn't touch this mm. |
| 761 | * Userland only wants this done for a sys_exit. | ||
| 717 | */ | 762 | */ |
| 718 | if (tsk->clear_child_tid) { | 763 | if (tsk->clear_child_tid) { |
| 719 | if (!(tsk->flags & PF_SIGNALED) && | 764 | if (!(tsk->flags & PF_SIGNALED) && |
| @@ -934,8 +979,10 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) | |||
| 934 | 979 | ||
| 935 | void __cleanup_sighand(struct sighand_struct *sighand) | 980 | void __cleanup_sighand(struct sighand_struct *sighand) |
| 936 | { | 981 | { |
| 937 | if (atomic_dec_and_test(&sighand->count)) | 982 | if (atomic_dec_and_test(&sighand->count)) { |
| 983 | signalfd_cleanup(sighand); | ||
| 938 | kmem_cache_free(sighand_cachep, sighand); | 984 | kmem_cache_free(sighand_cachep, sighand); |
| 985 | } | ||
| 939 | } | 986 | } |
| 940 | 987 | ||
| 941 | 988 | ||
| @@ -1003,6 +1050,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 1003 | sig->oom_score_adj = current->signal->oom_score_adj; | 1050 | sig->oom_score_adj = current->signal->oom_score_adj; |
| 1004 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; | 1051 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; |
| 1005 | 1052 | ||
| 1053 | sig->has_child_subreaper = current->signal->has_child_subreaper || | ||
| 1054 | current->signal->is_child_subreaper; | ||
| 1055 | |||
| 1006 | mutex_init(&sig->cred_guard_mutex); | 1056 | mutex_init(&sig->cred_guard_mutex); |
| 1007 | 1057 | ||
| 1008 | return 0; | 1058 | return 0; |
| @@ -1014,7 +1064,6 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) | |||
| 1014 | 1064 | ||
| 1015 | new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER); | 1065 | new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER); |
| 1016 | new_flags |= PF_FORKNOEXEC; | 1066 | new_flags |= PF_FORKNOEXEC; |
| 1017 | new_flags |= PF_STARTING; | ||
| 1018 | p->flags = new_flags; | 1067 | p->flags = new_flags; |
| 1019 | } | 1068 | } |
| 1020 | 1069 | ||
| @@ -1191,6 +1240,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1191 | #ifdef CONFIG_CPUSETS | 1240 | #ifdef CONFIG_CPUSETS |
| 1192 | p->cpuset_mem_spread_rotor = NUMA_NO_NODE; | 1241 | p->cpuset_mem_spread_rotor = NUMA_NO_NODE; |
| 1193 | p->cpuset_slab_spread_rotor = NUMA_NO_NODE; | 1242 | p->cpuset_slab_spread_rotor = NUMA_NO_NODE; |
| 1243 | seqcount_init(&p->mems_allowed_seq); | ||
| 1194 | #endif | 1244 | #endif |
| 1195 | #ifdef CONFIG_TRACE_IRQFLAGS | 1245 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 1196 | p->irq_events = 0; | 1246 | p->irq_events = 0; |
| @@ -1309,7 +1359,13 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1309 | clear_all_latency_tracing(p); | 1359 | clear_all_latency_tracing(p); |
| 1310 | 1360 | ||
| 1311 | /* ok, now we should be set up.. */ | 1361 | /* ok, now we should be set up.. */ |
| 1312 | p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); | 1362 | if (clone_flags & CLONE_THREAD) |
| 1363 | p->exit_signal = -1; | ||
| 1364 | else if (clone_flags & CLONE_PARENT) | ||
| 1365 | p->exit_signal = current->group_leader->exit_signal; | ||
| 1366 | else | ||
| 1367 | p->exit_signal = (clone_flags & CSIGNAL); | ||
| 1368 | |||
| 1313 | p->pdeath_signal = 0; | 1369 | p->pdeath_signal = 0; |
| 1314 | p->exit_state = 0; | 1370 | p->exit_state = 0; |
| 1315 | 1371 | ||
| @@ -1544,16 +1600,9 @@ long do_fork(unsigned long clone_flags, | |||
| 1544 | if (clone_flags & CLONE_VFORK) { | 1600 | if (clone_flags & CLONE_VFORK) { |
| 1545 | p->vfork_done = &vfork; | 1601 | p->vfork_done = &vfork; |
| 1546 | init_completion(&vfork); | 1602 | init_completion(&vfork); |
| 1603 | get_task_struct(p); | ||
| 1547 | } | 1604 | } |
| 1548 | 1605 | ||
| 1549 | /* | ||
| 1550 | * We set PF_STARTING at creation in case tracing wants to | ||
| 1551 | * use this to distinguish a fully live task from one that | ||
| 1552 | * hasn't finished SIGSTOP raising yet. Now we clear it | ||
| 1553 | * and set the child going. | ||
| 1554 | */ | ||
| 1555 | p->flags &= ~PF_STARTING; | ||
| 1556 | |||
| 1557 | wake_up_new_task(p); | 1606 | wake_up_new_task(p); |
| 1558 | 1607 | ||
| 1559 | /* forking complete and child started to run, tell ptracer */ | 1608 | /* forking complete and child started to run, tell ptracer */ |
| @@ -1561,10 +1610,8 @@ long do_fork(unsigned long clone_flags, | |||
| 1561 | ptrace_event(trace, nr); | 1610 | ptrace_event(trace, nr); |
| 1562 | 1611 | ||
| 1563 | if (clone_flags & CLONE_VFORK) { | 1612 | if (clone_flags & CLONE_VFORK) { |
| 1564 | freezer_do_not_count(); | 1613 | if (!wait_for_vfork_done(p, &vfork)) |
| 1565 | wait_for_completion(&vfork); | 1614 | ptrace_event(PTRACE_EVENT_VFORK_DONE, nr); |
| 1566 | freezer_count(); | ||
| 1567 | ptrace_event(PTRACE_EVENT_VFORK_DONE, nr); | ||
| 1568 | } | 1615 | } |
| 1569 | } else { | 1616 | } else { |
| 1570 | nr = PTR_ERR(p); | 1617 | nr = PTR_ERR(p); |
