diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 41 |
1 files changed, 14 insertions, 27 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index d9b44f20b6b0..25e429152ddc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -66,6 +66,7 @@ | |||
| 66 | #include <linux/posix-timers.h> | 66 | #include <linux/posix-timers.h> |
| 67 | #include <linux/user-return-notifier.h> | 67 | #include <linux/user-return-notifier.h> |
| 68 | #include <linux/oom.h> | 68 | #include <linux/oom.h> |
| 69 | #include <linux/khugepaged.h> | ||
| 69 | 70 | ||
| 70 | #include <asm/pgtable.h> | 71 | #include <asm/pgtable.h> |
| 71 | #include <asm/pgalloc.h> | 72 | #include <asm/pgalloc.h> |
| @@ -330,6 +331,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
| 330 | retval = ksm_fork(mm, oldmm); | 331 | retval = ksm_fork(mm, oldmm); |
| 331 | if (retval) | 332 | if (retval) |
| 332 | goto out; | 333 | goto out; |
| 334 | retval = khugepaged_fork(mm, oldmm); | ||
| 335 | if (retval) | ||
| 336 | goto out; | ||
| 333 | 337 | ||
| 334 | prev = NULL; | 338 | prev = NULL; |
| 335 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { | 339 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { |
| @@ -529,6 +533,9 @@ void __mmdrop(struct mm_struct *mm) | |||
| 529 | mm_free_pgd(mm); | 533 | mm_free_pgd(mm); |
| 530 | destroy_context(mm); | 534 | destroy_context(mm); |
| 531 | mmu_notifier_mm_destroy(mm); | 535 | mmu_notifier_mm_destroy(mm); |
| 536 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
| 537 | VM_BUG_ON(mm->pmd_huge_pte); | ||
| 538 | #endif | ||
| 532 | free_mm(mm); | 539 | free_mm(mm); |
| 533 | } | 540 | } |
| 534 | EXPORT_SYMBOL_GPL(__mmdrop); | 541 | EXPORT_SYMBOL_GPL(__mmdrop); |
| @@ -543,6 +550,7 @@ void mmput(struct mm_struct *mm) | |||
| 543 | if (atomic_dec_and_test(&mm->mm_users)) { | 550 | if (atomic_dec_and_test(&mm->mm_users)) { |
| 544 | exit_aio(mm); | 551 | exit_aio(mm); |
| 545 | ksm_exit(mm); | 552 | ksm_exit(mm); |
| 553 | khugepaged_exit(mm); /* must run before exit_mmap */ | ||
| 546 | exit_mmap(mm); | 554 | exit_mmap(mm); |
| 547 | set_mm_exe_file(mm, NULL); | 555 | set_mm_exe_file(mm, NULL); |
| 548 | if (!list_empty(&mm->mmlist)) { | 556 | if (!list_empty(&mm->mmlist)) { |
| @@ -669,6 +677,10 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
| 669 | mm->token_priority = 0; | 677 | mm->token_priority = 0; |
| 670 | mm->last_interval = 0; | 678 | mm->last_interval = 0; |
| 671 | 679 | ||
| 680 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
| 681 | mm->pmd_huge_pte = NULL; | ||
| 682 | #endif | ||
| 683 | |||
| 672 | if (!mm_init(mm, tsk)) | 684 | if (!mm_init(mm, tsk)) |
| 673 | goto fail_nomem; | 685 | goto fail_nomem; |
| 674 | 686 | ||
| @@ -910,6 +922,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 910 | 922 | ||
| 911 | sig->oom_adj = current->signal->oom_adj; | 923 | sig->oom_adj = current->signal->oom_adj; |
| 912 | sig->oom_score_adj = current->signal->oom_score_adj; | 924 | sig->oom_score_adj = current->signal->oom_score_adj; |
| 925 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; | ||
| 913 | 926 | ||
| 914 | mutex_init(&sig->cred_guard_mutex); | 927 | mutex_init(&sig->cred_guard_mutex); |
| 915 | 928 | ||
| @@ -1410,23 +1423,6 @@ long do_fork(unsigned long clone_flags, | |||
| 1410 | } | 1423 | } |
| 1411 | 1424 | ||
| 1412 | /* | 1425 | /* |
| 1413 | * We hope to recycle these flags after 2.6.26 | ||
| 1414 | */ | ||
| 1415 | if (unlikely(clone_flags & CLONE_STOPPED)) { | ||
| 1416 | static int __read_mostly count = 100; | ||
| 1417 | |||
| 1418 | if (count > 0 && printk_ratelimit()) { | ||
| 1419 | char comm[TASK_COMM_LEN]; | ||
| 1420 | |||
| 1421 | count--; | ||
| 1422 | printk(KERN_INFO "fork(): process `%s' used deprecated " | ||
| 1423 | "clone flags 0x%lx\n", | ||
| 1424 | get_task_comm(comm, current), | ||
| 1425 | clone_flags & CLONE_STOPPED); | ||
| 1426 | } | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | /* | ||
| 1430 | * When called from kernel_thread, don't do user tracing stuff. | 1426 | * When called from kernel_thread, don't do user tracing stuff. |
| 1431 | */ | 1427 | */ |
| 1432 | if (likely(user_mode(regs))) | 1428 | if (likely(user_mode(regs))) |
| @@ -1464,16 +1460,7 @@ long do_fork(unsigned long clone_flags, | |||
| 1464 | */ | 1460 | */ |
| 1465 | p->flags &= ~PF_STARTING; | 1461 | p->flags &= ~PF_STARTING; |
| 1466 | 1462 | ||
| 1467 | if (unlikely(clone_flags & CLONE_STOPPED)) { | 1463 | wake_up_new_task(p, clone_flags); |
| 1468 | /* | ||
| 1469 | * We'll start up with an immediate SIGSTOP. | ||
| 1470 | */ | ||
| 1471 | sigaddset(&p->pending.signal, SIGSTOP); | ||
| 1472 | set_tsk_thread_flag(p, TIF_SIGPENDING); | ||
| 1473 | __set_task_state(p, TASK_STOPPED); | ||
| 1474 | } else { | ||
| 1475 | wake_up_new_task(p, clone_flags); | ||
| 1476 | } | ||
| 1477 | 1464 | ||
| 1478 | tracehook_report_clone_complete(trace, regs, | 1465 | tracehook_report_clone_complete(trace, regs, |
| 1479 | clone_flags, nr, p); | 1466 | clone_flags, nr, p); |
