diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 66 |
1 files changed, 21 insertions, 45 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 17bbf093356d..4799c5f0e6d0 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -86,7 +86,14 @@ int max_threads; /* tunable limit on nr_threads */ | |||
86 | DEFINE_PER_CPU(unsigned long, process_counts) = 0; | 86 | DEFINE_PER_CPU(unsigned long, process_counts) = 0; |
87 | 87 | ||
88 | __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ | 88 | __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ |
89 | EXPORT_SYMBOL_GPL(tasklist_lock); | 89 | |
90 | #ifdef CONFIG_PROVE_RCU | ||
91 | int lockdep_tasklist_lock_is_held(void) | ||
92 | { | ||
93 | return lockdep_is_held(&tasklist_lock); | ||
94 | } | ||
95 | EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held); | ||
96 | #endif /* #ifdef CONFIG_PROVE_RCU */ | ||
90 | 97 | ||
91 | int nr_processes(void) | 98 | int nr_processes(void) |
92 | { | 99 | { |
@@ -329,15 +336,17 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
329 | if (!tmp) | 336 | if (!tmp) |
330 | goto fail_nomem; | 337 | goto fail_nomem; |
331 | *tmp = *mpnt; | 338 | *tmp = *mpnt; |
339 | INIT_LIST_HEAD(&tmp->anon_vma_chain); | ||
332 | pol = mpol_dup(vma_policy(mpnt)); | 340 | pol = mpol_dup(vma_policy(mpnt)); |
333 | retval = PTR_ERR(pol); | 341 | retval = PTR_ERR(pol); |
334 | if (IS_ERR(pol)) | 342 | if (IS_ERR(pol)) |
335 | goto fail_nomem_policy; | 343 | goto fail_nomem_policy; |
336 | vma_set_policy(tmp, pol); | 344 | vma_set_policy(tmp, pol); |
345 | if (anon_vma_fork(tmp, mpnt)) | ||
346 | goto fail_nomem_anon_vma_fork; | ||
337 | tmp->vm_flags &= ~VM_LOCKED; | 347 | tmp->vm_flags &= ~VM_LOCKED; |
338 | tmp->vm_mm = mm; | 348 | tmp->vm_mm = mm; |
339 | tmp->vm_next = NULL; | 349 | tmp->vm_next = NULL; |
340 | anon_vma_link(tmp); | ||
341 | file = tmp->vm_file; | 350 | file = tmp->vm_file; |
342 | if (file) { | 351 | if (file) { |
343 | struct inode *inode = file->f_path.dentry->d_inode; | 352 | struct inode *inode = file->f_path.dentry->d_inode; |
@@ -392,6 +401,8 @@ out: | |||
392 | flush_tlb_mm(oldmm); | 401 | flush_tlb_mm(oldmm); |
393 | up_write(&oldmm->mmap_sem); | 402 | up_write(&oldmm->mmap_sem); |
394 | return retval; | 403 | return retval; |
404 | fail_nomem_anon_vma_fork: | ||
405 | mpol_put(pol); | ||
395 | fail_nomem_policy: | 406 | fail_nomem_policy: |
396 | kmem_cache_free(vm_area_cachep, tmp); | 407 | kmem_cache_free(vm_area_cachep, tmp); |
397 | fail_nomem: | 408 | fail_nomem: |
@@ -455,8 +466,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | |||
455 | (current->mm->flags & MMF_INIT_MASK) : default_dump_filter; | 466 | (current->mm->flags & MMF_INIT_MASK) : default_dump_filter; |
456 | mm->core_state = NULL; | 467 | mm->core_state = NULL; |
457 | mm->nr_ptes = 0; | 468 | mm->nr_ptes = 0; |
458 | set_mm_counter(mm, file_rss, 0); | 469 | memset(&mm->rss_stat, 0, sizeof(mm->rss_stat)); |
459 | set_mm_counter(mm, anon_rss, 0); | ||
460 | spin_lock_init(&mm->page_table_lock); | 470 | spin_lock_init(&mm->page_table_lock); |
461 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 471 | mm->free_area_cache = TASK_UNMAPPED_BASE; |
462 | mm->cached_hole_size = ~0UL; | 472 | mm->cached_hole_size = ~0UL; |
@@ -825,23 +835,14 @@ void __cleanup_sighand(struct sighand_struct *sighand) | |||
825 | */ | 835 | */ |
826 | static void posix_cpu_timers_init_group(struct signal_struct *sig) | 836 | static void posix_cpu_timers_init_group(struct signal_struct *sig) |
827 | { | 837 | { |
838 | unsigned long cpu_limit; | ||
839 | |||
828 | /* Thread group counters. */ | 840 | /* Thread group counters. */ |
829 | thread_group_cputime_init(sig); | 841 | thread_group_cputime_init(sig); |
830 | 842 | ||
831 | /* Expiration times and increments. */ | 843 | cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur); |
832 | sig->it[CPUCLOCK_PROF].expires = cputime_zero; | 844 | if (cpu_limit != RLIM_INFINITY) { |
833 | sig->it[CPUCLOCK_PROF].incr = cputime_zero; | 845 | sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit); |
834 | sig->it[CPUCLOCK_VIRT].expires = cputime_zero; | ||
835 | sig->it[CPUCLOCK_VIRT].incr = cputime_zero; | ||
836 | |||
837 | /* Cached expiration times. */ | ||
838 | sig->cputime_expires.prof_exp = cputime_zero; | ||
839 | sig->cputime_expires.virt_exp = cputime_zero; | ||
840 | sig->cputime_expires.sched_exp = 0; | ||
841 | |||
842 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | ||
843 | sig->cputime_expires.prof_exp = | ||
844 | secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); | ||
845 | sig->cputimer.running = 1; | 846 | sig->cputimer.running = 1; |
846 | } | 847 | } |
847 | 848 | ||
@@ -858,7 +859,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
858 | if (clone_flags & CLONE_THREAD) | 859 | if (clone_flags & CLONE_THREAD) |
859 | return 0; | 860 | return 0; |
860 | 861 | ||
861 | sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); | 862 | sig = kmem_cache_zalloc(signal_cachep, GFP_KERNEL); |
862 | tsk->signal = sig; | 863 | tsk->signal = sig; |
863 | if (!sig) | 864 | if (!sig) |
864 | return -ENOMEM; | 865 | return -ENOMEM; |
@@ -866,46 +867,21 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
866 | atomic_set(&sig->count, 1); | 867 | atomic_set(&sig->count, 1); |
867 | atomic_set(&sig->live, 1); | 868 | atomic_set(&sig->live, 1); |
868 | init_waitqueue_head(&sig->wait_chldexit); | 869 | init_waitqueue_head(&sig->wait_chldexit); |
869 | sig->flags = 0; | ||
870 | if (clone_flags & CLONE_NEWPID) | 870 | if (clone_flags & CLONE_NEWPID) |
871 | sig->flags |= SIGNAL_UNKILLABLE; | 871 | sig->flags |= SIGNAL_UNKILLABLE; |
872 | sig->group_exit_code = 0; | ||
873 | sig->group_exit_task = NULL; | ||
874 | sig->group_stop_count = 0; | ||
875 | sig->curr_target = tsk; | 872 | sig->curr_target = tsk; |
876 | init_sigpending(&sig->shared_pending); | 873 | init_sigpending(&sig->shared_pending); |
877 | INIT_LIST_HEAD(&sig->posix_timers); | 874 | INIT_LIST_HEAD(&sig->posix_timers); |
878 | 875 | ||
879 | hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 876 | hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
880 | sig->it_real_incr.tv64 = 0; | ||
881 | sig->real_timer.function = it_real_fn; | 877 | sig->real_timer.function = it_real_fn; |
882 | 878 | ||
883 | sig->leader = 0; /* session leadership doesn't inherit */ | ||
884 | sig->tty_old_pgrp = NULL; | ||
885 | sig->tty = NULL; | ||
886 | |||
887 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; | ||
888 | sig->gtime = cputime_zero; | ||
889 | sig->cgtime = cputime_zero; | ||
890 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
891 | sig->prev_utime = sig->prev_stime = cputime_zero; | ||
892 | #endif | ||
893 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | ||
894 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | ||
895 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | ||
896 | sig->maxrss = sig->cmaxrss = 0; | ||
897 | task_io_accounting_init(&sig->ioac); | ||
898 | sig->sum_sched_runtime = 0; | ||
899 | taskstats_tgid_init(sig); | ||
900 | |||
901 | task_lock(current->group_leader); | 879 | task_lock(current->group_leader); |
902 | memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); | 880 | memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); |
903 | task_unlock(current->group_leader); | 881 | task_unlock(current->group_leader); |
904 | 882 | ||
905 | posix_cpu_timers_init_group(sig); | 883 | posix_cpu_timers_init_group(sig); |
906 | 884 | ||
907 | acct_init_pacct(&sig->pacct); | ||
908 | |||
909 | tty_audit_fork(sig); | 885 | tty_audit_fork(sig); |
910 | 886 | ||
911 | sig->oom_adj = current->signal->oom_adj; | 887 | sig->oom_adj = current->signal->oom_adj; |
@@ -1034,7 +1010,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1034 | #endif | 1010 | #endif |
1035 | retval = -EAGAIN; | 1011 | retval = -EAGAIN; |
1036 | if (atomic_read(&p->real_cred->user->processes) >= | 1012 | if (atomic_read(&p->real_cred->user->processes) >= |
1037 | p->signal->rlim[RLIMIT_NPROC].rlim_cur) { | 1013 | task_rlimit(p, RLIMIT_NPROC)) { |
1038 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && | 1014 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && |
1039 | p->real_cred->user != INIT_USER) | 1015 | p->real_cred->user != INIT_USER) |
1040 | goto bad_fork_free; | 1016 | goto bad_fork_free; |