aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 1020977b57ca..166b8c49257c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -63,6 +63,7 @@
63#include <linux/fs_struct.h> 63#include <linux/fs_struct.h>
64#include <linux/magic.h> 64#include <linux/magic.h>
65#include <linux/perf_event.h> 65#include <linux/perf_event.h>
66#include <linux/posix-timers.h>
66 67
67#include <asm/pgtable.h> 68#include <asm/pgtable.h>
68#include <asm/pgalloc.h> 69#include <asm/pgalloc.h>
@@ -90,7 +91,7 @@ int nr_processes(void)
90 int cpu; 91 int cpu;
91 int total = 0; 92 int total = 0;
92 93
93 for_each_online_cpu(cpu) 94 for_each_possible_cpu(cpu)
94 total += per_cpu(process_counts, cpu); 95 total += per_cpu(process_counts, cpu);
95 96
96 return total; 97 return total;
@@ -433,6 +434,14 @@ __setup("coredump_filter=", coredump_filter_setup);
433 434
434#include <linux/init_task.h> 435#include <linux/init_task.h>
435 436
437static void mm_init_aio(struct mm_struct *mm)
438{
439#ifdef CONFIG_AIO
440 spin_lock_init(&mm->ioctx_lock);
441 INIT_HLIST_HEAD(&mm->ioctx_list);
442#endif
443}
444
436static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) 445static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
437{ 446{
438 atomic_set(&mm->mm_users, 1); 447 atomic_set(&mm->mm_users, 1);
@@ -446,10 +455,9 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
446 set_mm_counter(mm, file_rss, 0); 455 set_mm_counter(mm, file_rss, 0);
447 set_mm_counter(mm, anon_rss, 0); 456 set_mm_counter(mm, anon_rss, 0);
448 spin_lock_init(&mm->page_table_lock); 457 spin_lock_init(&mm->page_table_lock);
449 spin_lock_init(&mm->ioctx_lock);
450 INIT_HLIST_HEAD(&mm->ioctx_list);
451 mm->free_area_cache = TASK_UNMAPPED_BASE; 458 mm->free_area_cache = TASK_UNMAPPED_BASE;
452 mm->cached_hole_size = ~0UL; 459 mm->cached_hole_size = ~0UL;
460 mm_init_aio(mm);
453 mm_init_owner(mm, p); 461 mm_init_owner(mm, p);
454 462
455 if (likely(!mm_alloc_pgd(mm))) { 463 if (likely(!mm_alloc_pgd(mm))) {
@@ -510,6 +518,8 @@ void mmput(struct mm_struct *mm)
510 spin_unlock(&mmlist_lock); 518 spin_unlock(&mmlist_lock);
511 } 519 }
512 put_swap_token(mm); 520 put_swap_token(mm);
521 if (mm->binfmt)
522 module_put(mm->binfmt->module);
513 mmdrop(mm); 523 mmdrop(mm);
514 } 524 }
515} 525}
@@ -560,12 +570,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
560 570
561 /* Get rid of any futexes when releasing the mm */ 571 /* Get rid of any futexes when releasing the mm */
562#ifdef CONFIG_FUTEX 572#ifdef CONFIG_FUTEX
563 if (unlikely(tsk->robust_list)) 573 if (unlikely(tsk->robust_list)) {
564 exit_robust_list(tsk); 574 exit_robust_list(tsk);
575 tsk->robust_list = NULL;
576 }
565#ifdef CONFIG_COMPAT 577#ifdef CONFIG_COMPAT
566 if (unlikely(tsk->compat_robust_list)) 578 if (unlikely(tsk->compat_robust_list)) {
567 compat_exit_robust_list(tsk); 579 compat_exit_robust_list(tsk);
580 tsk->compat_robust_list = NULL;
581 }
568#endif 582#endif
583 if (unlikely(!list_empty(&tsk->pi_state_list)))
584 exit_pi_state_list(tsk);
569#endif 585#endif
570 586
571 /* Get rid of any cached register state */ 587 /* Get rid of any cached register state */
@@ -635,9 +651,14 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
635 mm->hiwater_rss = get_mm_rss(mm); 651 mm->hiwater_rss = get_mm_rss(mm);
636 mm->hiwater_vm = mm->total_vm; 652 mm->hiwater_vm = mm->total_vm;
637 653
654 if (mm->binfmt && !try_module_get(mm->binfmt->module))
655 goto free_pt;
656
638 return mm; 657 return mm;
639 658
640free_pt: 659free_pt:
660 /* don't put binfmt in mmput, we haven't got module yet */
661 mm->binfmt = NULL;
641 mmput(mm); 662 mmput(mm);
642 663
643fail_nomem: 664fail_nomem:
@@ -805,10 +826,10 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
805 thread_group_cputime_init(sig); 826 thread_group_cputime_init(sig);
806 827
807 /* Expiration times and increments. */ 828 /* Expiration times and increments. */
808 sig->it_virt_expires = cputime_zero; 829 sig->it[CPUCLOCK_PROF].expires = cputime_zero;
809 sig->it_virt_incr = cputime_zero; 830 sig->it[CPUCLOCK_PROF].incr = cputime_zero;
810 sig->it_prof_expires = cputime_zero; 831 sig->it[CPUCLOCK_VIRT].expires = cputime_zero;
811 sig->it_prof_incr = cputime_zero; 832 sig->it[CPUCLOCK_VIRT].incr = cputime_zero;
812 833
813 /* Cached expiration times. */ 834 /* Cached expiration times. */
814 sig->cputime_expires.prof_exp = cputime_zero; 835 sig->cputime_expires.prof_exp = cputime_zero;
@@ -866,6 +887,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
866 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 887 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
867 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; 888 sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
868 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; 889 sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
890 sig->maxrss = sig->cmaxrss = 0;
869 task_io_accounting_init(&sig->ioac); 891 task_io_accounting_init(&sig->ioac);
870 sig->sum_sched_runtime = 0; 892 sig->sum_sched_runtime = 0;
871 taskstats_tgid_init(sig); 893 taskstats_tgid_init(sig);
@@ -977,6 +999,16 @@ static struct task_struct *copy_process(unsigned long clone_flags,
977 if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) 999 if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM))
978 return ERR_PTR(-EINVAL); 1000 return ERR_PTR(-EINVAL);
979 1001
1002 /*
1003 * Siblings of global init remain as zombies on exit since they are
1004 * not reaped by their parent (swapper). To solve this and to avoid
1005 * multi-rooted process trees, prevent global and container-inits
1006 * from creating siblings.
1007 */
1008 if ((clone_flags & CLONE_PARENT) &&
1009 current->signal->flags & SIGNAL_UNKILLABLE)
1010 return ERR_PTR(-EINVAL);
1011
980 retval = security_task_create(clone_flags); 1012 retval = security_task_create(clone_flags);
981 if (retval) 1013 if (retval)
982 goto fork_out; 1014 goto fork_out;
@@ -1018,9 +1050,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1018 if (!try_module_get(task_thread_info(p)->exec_domain->module)) 1050 if (!try_module_get(task_thread_info(p)->exec_domain->module))
1019 goto bad_fork_cleanup_count; 1051 goto bad_fork_cleanup_count;
1020 1052
1021 if (p->binfmt && !try_module_get(p->binfmt->module))
1022 goto bad_fork_cleanup_put_domain;
1023
1024 p->did_exec = 0; 1053 p->did_exec = 0;
1025 delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ 1054 delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
1026 copy_flags(clone_flags, p); 1055 copy_flags(clone_flags, p);
@@ -1094,6 +1123,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1094 1123
1095 p->bts = NULL; 1124 p->bts = NULL;
1096 1125
1126 p->stack_start = stack_start;
1127
1097 /* Perform scheduler related setup. Assign this task to a CPU. */ 1128 /* Perform scheduler related setup. Assign this task to a CPU. */
1098 sched_fork(p, clone_flags); 1129 sched_fork(p, clone_flags);
1099 1130
@@ -1306,9 +1337,6 @@ bad_fork_cleanup_cgroup:
1306#endif 1337#endif
1307 cgroup_exit(p, cgroup_callbacks_done); 1338 cgroup_exit(p, cgroup_callbacks_done);
1308 delayacct_tsk_free(p); 1339 delayacct_tsk_free(p);
1309 if (p->binfmt)
1310 module_put(p->binfmt->module);
1311bad_fork_cleanup_put_domain:
1312 module_put(task_thread_info(p)->exec_domain->module); 1340 module_put(task_thread_info(p)->exec_domain->module);
1313bad_fork_cleanup_count: 1341bad_fork_cleanup_count:
1314 atomic_dec(&p->cred->user->processes); 1342 atomic_dec(&p->cred->user->processes);