diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 110 |
1 files changed, 71 insertions, 39 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 8e7e135d0817..0276c30401a0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <linux/taskstats_kern.h> | 59 | #include <linux/taskstats_kern.h> |
60 | #include <linux/random.h> | 60 | #include <linux/random.h> |
61 | #include <linux/tty.h> | 61 | #include <linux/tty.h> |
62 | #include <linux/proc_fs.h> | ||
63 | #include <linux/blkdev.h> | 62 | #include <linux/blkdev.h> |
64 | #include <linux/fs_struct.h> | 63 | #include <linux/fs_struct.h> |
65 | #include <linux/magic.h> | 64 | #include <linux/magic.h> |
@@ -485,20 +484,6 @@ static void mm_init_aio(struct mm_struct *mm) | |||
485 | #endif | 484 | #endif |
486 | } | 485 | } |
487 | 486 | ||
488 | int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm) | ||
489 | { | ||
490 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
491 | if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL)) | ||
492 | return -ENOMEM; | ||
493 | |||
494 | if (oldmm) | ||
495 | cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm)); | ||
496 | else | ||
497 | memset(mm_cpumask(mm), 0, cpumask_size()); | ||
498 | #endif | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 487 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) |
503 | { | 488 | { |
504 | atomic_set(&mm->mm_users, 1); | 489 | atomic_set(&mm->mm_users, 1); |
@@ -539,17 +524,8 @@ struct mm_struct * mm_alloc(void) | |||
539 | return NULL; | 524 | return NULL; |
540 | 525 | ||
541 | memset(mm, 0, sizeof(*mm)); | 526 | memset(mm, 0, sizeof(*mm)); |
542 | mm = mm_init(mm, current); | 527 | mm_init_cpumask(mm); |
543 | if (!mm) | 528 | return mm_init(mm, current); |
544 | return NULL; | ||
545 | |||
546 | if (mm_init_cpumask(mm, NULL)) { | ||
547 | mm_free_pgd(mm); | ||
548 | free_mm(mm); | ||
549 | return NULL; | ||
550 | } | ||
551 | |||
552 | return mm; | ||
553 | } | 529 | } |
554 | 530 | ||
555 | /* | 531 | /* |
@@ -560,7 +536,6 @@ struct mm_struct * mm_alloc(void) | |||
560 | void __mmdrop(struct mm_struct *mm) | 536 | void __mmdrop(struct mm_struct *mm) |
561 | { | 537 | { |
562 | BUG_ON(mm == &init_mm); | 538 | BUG_ON(mm == &init_mm); |
563 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
564 | mm_free_pgd(mm); | 539 | mm_free_pgd(mm); |
565 | destroy_context(mm); | 540 | destroy_context(mm); |
566 | mmu_notifier_mm_destroy(mm); | 541 | mmu_notifier_mm_destroy(mm); |
@@ -597,6 +572,57 @@ void mmput(struct mm_struct *mm) | |||
597 | } | 572 | } |
598 | EXPORT_SYMBOL_GPL(mmput); | 573 | EXPORT_SYMBOL_GPL(mmput); |
599 | 574 | ||
575 | /* | ||
576 | * We added or removed a vma mapping the executable. The vmas are only mapped | ||
577 | * during exec and are not mapped with the mmap system call. | ||
578 | * Callers must hold down_write() on the mm's mmap_sem for these | ||
579 | */ | ||
580 | void added_exe_file_vma(struct mm_struct *mm) | ||
581 | { | ||
582 | mm->num_exe_file_vmas++; | ||
583 | } | ||
584 | |||
585 | void removed_exe_file_vma(struct mm_struct *mm) | ||
586 | { | ||
587 | mm->num_exe_file_vmas--; | ||
588 | if ((mm->num_exe_file_vmas == 0) && mm->exe_file){ | ||
589 | fput(mm->exe_file); | ||
590 | mm->exe_file = NULL; | ||
591 | } | ||
592 | |||
593 | } | ||
594 | |||
595 | void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) | ||
596 | { | ||
597 | if (new_exe_file) | ||
598 | get_file(new_exe_file); | ||
599 | if (mm->exe_file) | ||
600 | fput(mm->exe_file); | ||
601 | mm->exe_file = new_exe_file; | ||
602 | mm->num_exe_file_vmas = 0; | ||
603 | } | ||
604 | |||
605 | struct file *get_mm_exe_file(struct mm_struct *mm) | ||
606 | { | ||
607 | struct file *exe_file; | ||
608 | |||
609 | /* We need mmap_sem to protect against races with removal of | ||
610 | * VM_EXECUTABLE vmas */ | ||
611 | down_read(&mm->mmap_sem); | ||
612 | exe_file = mm->exe_file; | ||
613 | if (exe_file) | ||
614 | get_file(exe_file); | ||
615 | up_read(&mm->mmap_sem); | ||
616 | return exe_file; | ||
617 | } | ||
618 | |||
619 | static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm) | ||
620 | { | ||
621 | /* It's safe to write the exe_file pointer without exe_file_lock because | ||
622 | * this is called during fork when the task is not yet in /proc */ | ||
623 | newmm->exe_file = get_mm_exe_file(oldmm); | ||
624 | } | ||
625 | |||
600 | /** | 626 | /** |
601 | * get_task_mm - acquire a reference to the task's mm | 627 | * get_task_mm - acquire a reference to the task's mm |
602 | * | 628 | * |
@@ -703,6 +729,7 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
703 | goto fail_nomem; | 729 | goto fail_nomem; |
704 | 730 | ||
705 | memcpy(mm, oldmm, sizeof(*mm)); | 731 | memcpy(mm, oldmm, sizeof(*mm)); |
732 | mm_init_cpumask(mm); | ||
706 | 733 | ||
707 | /* Initializing for Swap token stuff */ | 734 | /* Initializing for Swap token stuff */ |
708 | mm->token_priority = 0; | 735 | mm->token_priority = 0; |
@@ -715,9 +742,6 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
715 | if (!mm_init(mm, tsk)) | 742 | if (!mm_init(mm, tsk)) |
716 | goto fail_nomem; | 743 | goto fail_nomem; |
717 | 744 | ||
718 | if (mm_init_cpumask(mm, oldmm)) | ||
719 | goto fail_nocpumask; | ||
720 | |||
721 | if (init_new_context(tsk, mm)) | 745 | if (init_new_context(tsk, mm)) |
722 | goto fail_nocontext; | 746 | goto fail_nocontext; |
723 | 747 | ||
@@ -744,9 +768,6 @@ fail_nomem: | |||
744 | return NULL; | 768 | return NULL; |
745 | 769 | ||
746 | fail_nocontext: | 770 | fail_nocontext: |
747 | free_cpumask_var(mm->cpu_vm_mask_var); | ||
748 | |||
749 | fail_nocpumask: | ||
750 | /* | 771 | /* |
751 | * If init_new_context() failed, we cannot use mmput() to free the mm | 772 | * If init_new_context() failed, we cannot use mmput() to free the mm |
752 | * because it calls destroy_context() | 773 | * because it calls destroy_context() |
@@ -957,6 +978,10 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
957 | tty_audit_fork(sig); | 978 | tty_audit_fork(sig); |
958 | sched_autogroup_fork(sig); | 979 | sched_autogroup_fork(sig); |
959 | 980 | ||
981 | #ifdef CONFIG_CGROUPS | ||
982 | init_rwsem(&sig->threadgroup_fork_lock); | ||
983 | #endif | ||
984 | |||
960 | sig->oom_adj = current->signal->oom_adj; | 985 | sig->oom_adj = current->signal->oom_adj; |
961 | sig->oom_score_adj = current->signal->oom_score_adj; | 986 | sig->oom_score_adj = current->signal->oom_score_adj; |
962 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; | 987 | sig->oom_score_adj_min = current->signal->oom_score_adj_min; |
@@ -1138,6 +1163,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1138 | monotonic_to_bootbased(&p->real_start_time); | 1163 | monotonic_to_bootbased(&p->real_start_time); |
1139 | p->io_context = NULL; | 1164 | p->io_context = NULL; |
1140 | p->audit_context = NULL; | 1165 | p->audit_context = NULL; |
1166 | if (clone_flags & CLONE_THREAD) | ||
1167 | threadgroup_fork_read_lock(current); | ||
1141 | cgroup_fork(p); | 1168 | cgroup_fork(p); |
1142 | #ifdef CONFIG_NUMA | 1169 | #ifdef CONFIG_NUMA |
1143 | p->mempolicy = mpol_dup(p->mempolicy); | 1170 | p->mempolicy = mpol_dup(p->mempolicy); |
@@ -1223,12 +1250,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1223 | if (clone_flags & CLONE_THREAD) | 1250 | if (clone_flags & CLONE_THREAD) |
1224 | p->tgid = current->tgid; | 1251 | p->tgid = current->tgid; |
1225 | 1252 | ||
1226 | if (current->nsproxy != p->nsproxy) { | ||
1227 | retval = ns_cgroup_clone(p, pid); | ||
1228 | if (retval) | ||
1229 | goto bad_fork_free_pid; | ||
1230 | } | ||
1231 | |||
1232 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; | 1253 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; |
1233 | /* | 1254 | /* |
1234 | * Clear TID on mm_release()? | 1255 | * Clear TID on mm_release()? |
@@ -1342,6 +1363,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1342 | write_unlock_irq(&tasklist_lock); | 1363 | write_unlock_irq(&tasklist_lock); |
1343 | proc_fork_connector(p); | 1364 | proc_fork_connector(p); |
1344 | cgroup_post_fork(p); | 1365 | cgroup_post_fork(p); |
1366 | if (clone_flags & CLONE_THREAD) | ||
1367 | threadgroup_fork_read_unlock(current); | ||
1345 | perf_event_fork(p); | 1368 | perf_event_fork(p); |
1346 | return p; | 1369 | return p; |
1347 | 1370 | ||
@@ -1380,6 +1403,8 @@ bad_fork_cleanup_policy: | |||
1380 | mpol_put(p->mempolicy); | 1403 | mpol_put(p->mempolicy); |
1381 | bad_fork_cleanup_cgroup: | 1404 | bad_fork_cleanup_cgroup: |
1382 | #endif | 1405 | #endif |
1406 | if (clone_flags & CLONE_THREAD) | ||
1407 | threadgroup_fork_read_unlock(current); | ||
1383 | cgroup_exit(p, cgroup_callbacks_done); | 1408 | cgroup_exit(p, cgroup_callbacks_done); |
1384 | delayacct_tsk_free(p); | 1409 | delayacct_tsk_free(p); |
1385 | module_put(task_thread_info(p)->exec_domain->module); | 1410 | module_put(task_thread_info(p)->exec_domain->module); |
@@ -1537,6 +1562,13 @@ void __init proc_caches_init(void) | |||
1537 | fs_cachep = kmem_cache_create("fs_cache", | 1562 | fs_cachep = kmem_cache_create("fs_cache", |
1538 | sizeof(struct fs_struct), 0, | 1563 | sizeof(struct fs_struct), 0, |
1539 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); | 1564 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
1565 | /* | ||
1566 | * FIXME! The "sizeof(struct mm_struct)" currently includes the | ||
1567 | * whole struct cpumask for the OFFSTACK case. We could change | ||
1568 | * this to *only* allocate as much of it as required by the | ||
1569 | * maximum number of CPU's we can ever have. The cpumask_allocation | ||
1570 | * is at the end of the structure, exactly for that reason. | ||
1571 | */ | ||
1540 | mm_cachep = kmem_cache_create("mm_struct", | 1572 | mm_cachep = kmem_cache_create("mm_struct", |
1541 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, | 1573 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
1542 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); | 1574 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |