diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 184 |
1 files changed, 89 insertions, 95 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 4854c2c4a82e..e6c04d462ab2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
| 19 | #include <linux/completion.h> | 19 | #include <linux/completion.h> |
| 20 | #include <linux/mnt_namespace.h> | ||
| 21 | #include <linux/personality.h> | 20 | #include <linux/personality.h> |
| 22 | #include <linux/mempolicy.h> | 21 | #include <linux/mempolicy.h> |
| 23 | #include <linux/sem.h> | 22 | #include <linux/sem.h> |
| @@ -60,7 +59,9 @@ | |||
| 60 | #include <linux/tty.h> | 59 | #include <linux/tty.h> |
| 61 | #include <linux/proc_fs.h> | 60 | #include <linux/proc_fs.h> |
| 62 | #include <linux/blkdev.h> | 61 | #include <linux/blkdev.h> |
| 63 | #include <trace/sched.h> | 62 | #include <linux/fs_struct.h> |
| 63 | #include <linux/magic.h> | ||
| 64 | #include <linux/perf_counter.h> | ||
| 64 | 65 | ||
| 65 | #include <asm/pgtable.h> | 66 | #include <asm/pgtable.h> |
| 66 | #include <asm/pgalloc.h> | 67 | #include <asm/pgalloc.h> |
| @@ -69,6 +70,8 @@ | |||
| 69 | #include <asm/cacheflush.h> | 70 | #include <asm/cacheflush.h> |
| 70 | #include <asm/tlbflush.h> | 71 | #include <asm/tlbflush.h> |
| 71 | 72 | ||
| 73 | #include <trace/events/sched.h> | ||
| 74 | |||
| 72 | /* | 75 | /* |
| 73 | * Protected counters by write_lock_irq(&tasklist_lock) | 76 | * Protected counters by write_lock_irq(&tasklist_lock) |
| 74 | */ | 77 | */ |
| @@ -81,8 +84,6 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0; | |||
| 81 | 84 | ||
| 82 | __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ | 85 | __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ |
| 83 | 86 | ||
| 84 | DEFINE_TRACE(sched_process_fork); | ||
| 85 | |||
| 86 | int nr_processes(void) | 87 | int nr_processes(void) |
| 87 | { | 88 | { |
| 88 | int cpu; | 89 | int cpu; |
| @@ -176,7 +177,7 @@ void __init fork_init(unsigned long mempages) | |||
| 176 | /* create a slab on which task_structs can be allocated */ | 177 | /* create a slab on which task_structs can be allocated */ |
| 177 | task_struct_cachep = | 178 | task_struct_cachep = |
| 178 | kmem_cache_create("task_struct", sizeof(struct task_struct), | 179 | kmem_cache_create("task_struct", sizeof(struct task_struct), |
| 179 | ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); | 180 | ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL); |
| 180 | #endif | 181 | #endif |
| 181 | 182 | ||
| 182 | /* do the arch specific task caches init */ | 183 | /* do the arch specific task caches init */ |
| @@ -212,6 +213,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
| 212 | { | 213 | { |
| 213 | struct task_struct *tsk; | 214 | struct task_struct *tsk; |
| 214 | struct thread_info *ti; | 215 | struct thread_info *ti; |
| 216 | unsigned long *stackend; | ||
| 217 | |||
| 215 | int err; | 218 | int err; |
| 216 | 219 | ||
| 217 | prepare_to_copy(orig); | 220 | prepare_to_copy(orig); |
| @@ -237,6 +240,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
| 237 | goto out; | 240 | goto out; |
| 238 | 241 | ||
| 239 | setup_thread_stack(tsk, orig); | 242 | setup_thread_stack(tsk, orig); |
| 243 | stackend = end_of_stack(tsk); | ||
| 244 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | ||
| 240 | 245 | ||
| 241 | #ifdef CONFIG_CC_STACKPROTECTOR | 246 | #ifdef CONFIG_CC_STACKPROTECTOR |
| 242 | tsk->stack_canary = get_random_int(); | 247 | tsk->stack_canary = get_random_int(); |
| @@ -279,7 +284,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
| 279 | mm->free_area_cache = oldmm->mmap_base; | 284 | mm->free_area_cache = oldmm->mmap_base; |
| 280 | mm->cached_hole_size = ~0UL; | 285 | mm->cached_hole_size = ~0UL; |
| 281 | mm->map_count = 0; | 286 | mm->map_count = 0; |
| 282 | cpus_clear(mm->cpu_vm_mask); | 287 | cpumask_clear(mm_cpumask(mm)); |
| 283 | mm->mm_rb = RB_ROOT; | 288 | mm->mm_rb = RB_ROOT; |
| 284 | rb_link = &mm->mm_rb.rb_node; | 289 | rb_link = &mm->mm_rb.rb_node; |
| 285 | rb_parent = NULL; | 290 | rb_parent = NULL; |
| @@ -562,18 +567,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
| 562 | * the value intact in a core dump, and to save the unnecessary | 567 | * the value intact in a core dump, and to save the unnecessary |
| 563 | * trouble otherwise. Userland only wants this done for a sys_exit. | 568 | * trouble otherwise. Userland only wants this done for a sys_exit. |
| 564 | */ | 569 | */ |
| 565 | if (tsk->clear_child_tid | 570 | if (tsk->clear_child_tid) { |
| 566 | && !(tsk->flags & PF_SIGNALED) | 571 | if (!(tsk->flags & PF_SIGNALED) && |
| 567 | && atomic_read(&mm->mm_users) > 1) { | 572 | atomic_read(&mm->mm_users) > 1) { |
| 568 | u32 __user * tidptr = tsk->clear_child_tid; | 573 | /* |
| 574 | * We don't check the error code - if userspace has | ||
| 575 | * not set up a proper pointer then tough luck. | ||
| 576 | */ | ||
| 577 | put_user(0, tsk->clear_child_tid); | ||
| 578 | sys_futex(tsk->clear_child_tid, FUTEX_WAKE, | ||
| 579 | 1, NULL, NULL, 0); | ||
| 580 | } | ||
| 569 | tsk->clear_child_tid = NULL; | 581 | tsk->clear_child_tid = NULL; |
| 570 | |||
| 571 | /* | ||
| 572 | * We don't check the error code - if userspace has | ||
| 573 | * not set up a proper pointer then tough luck. | ||
| 574 | */ | ||
| 575 | put_user(0, tidptr); | ||
| 576 | sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); | ||
| 577 | } | 582 | } |
| 578 | } | 583 | } |
| 579 | 584 | ||
| @@ -639,6 +644,9 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) | |||
| 639 | 644 | ||
| 640 | tsk->min_flt = tsk->maj_flt = 0; | 645 | tsk->min_flt = tsk->maj_flt = 0; |
| 641 | tsk->nvcsw = tsk->nivcsw = 0; | 646 | tsk->nvcsw = tsk->nivcsw = 0; |
| 647 | #ifdef CONFIG_DETECT_HUNG_TASK | ||
| 648 | tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw; | ||
| 649 | #endif | ||
| 642 | 650 | ||
| 643 | tsk->mm = NULL; | 651 | tsk->mm = NULL; |
| 644 | tsk->active_mm = NULL; | 652 | tsk->active_mm = NULL; |
| @@ -676,38 +684,21 @@ fail_nomem: | |||
| 676 | return retval; | 684 | return retval; |
| 677 | } | 685 | } |
| 678 | 686 | ||
| 679 | static struct fs_struct *__copy_fs_struct(struct fs_struct *old) | ||
| 680 | { | ||
| 681 | struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); | ||
| 682 | /* We don't need to lock fs - think why ;-) */ | ||
| 683 | if (fs) { | ||
| 684 | atomic_set(&fs->count, 1); | ||
| 685 | rwlock_init(&fs->lock); | ||
| 686 | fs->umask = old->umask; | ||
| 687 | read_lock(&old->lock); | ||
| 688 | fs->root = old->root; | ||
| 689 | path_get(&old->root); | ||
| 690 | fs->pwd = old->pwd; | ||
| 691 | path_get(&old->pwd); | ||
| 692 | read_unlock(&old->lock); | ||
| 693 | } | ||
| 694 | return fs; | ||
| 695 | } | ||
| 696 | |||
| 697 | struct fs_struct *copy_fs_struct(struct fs_struct *old) | ||
| 698 | { | ||
| 699 | return __copy_fs_struct(old); | ||
| 700 | } | ||
| 701 | |||
| 702 | EXPORT_SYMBOL_GPL(copy_fs_struct); | ||
| 703 | |||
| 704 | static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) | 687 | static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) |
| 705 | { | 688 | { |
| 689 | struct fs_struct *fs = current->fs; | ||
| 706 | if (clone_flags & CLONE_FS) { | 690 | if (clone_flags & CLONE_FS) { |
| 707 | atomic_inc(¤t->fs->count); | 691 | /* tsk->fs is already what we want */ |
| 692 | write_lock(&fs->lock); | ||
| 693 | if (fs->in_exec) { | ||
| 694 | write_unlock(&fs->lock); | ||
| 695 | return -EAGAIN; | ||
| 696 | } | ||
| 697 | fs->users++; | ||
| 698 | write_unlock(&fs->lock); | ||
| 708 | return 0; | 699 | return 0; |
| 709 | } | 700 | } |
| 710 | tsk->fs = __copy_fs_struct(current->fs); | 701 | tsk->fs = copy_fs_struct(fs); |
| 711 | if (!tsk->fs) | 702 | if (!tsk->fs) |
| 712 | return -ENOMEM; | 703 | return -ENOMEM; |
| 713 | return 0; | 704 | return 0; |
| @@ -808,6 +799,12 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig) | |||
| 808 | sig->cputime_expires.virt_exp = cputime_zero; | 799 | sig->cputime_expires.virt_exp = cputime_zero; |
| 809 | sig->cputime_expires.sched_exp = 0; | 800 | sig->cputime_expires.sched_exp = 0; |
| 810 | 801 | ||
| 802 | if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { | ||
| 803 | sig->cputime_expires.prof_exp = | ||
| 804 | secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur); | ||
| 805 | sig->cputimer.running = 1; | ||
| 806 | } | ||
| 807 | |||
| 811 | /* The timer lists. */ | 808 | /* The timer lists. */ |
| 812 | INIT_LIST_HEAD(&sig->cpu_timers[0]); | 809 | INIT_LIST_HEAD(&sig->cpu_timers[0]); |
| 813 | INIT_LIST_HEAD(&sig->cpu_timers[1]); | 810 | INIT_LIST_HEAD(&sig->cpu_timers[1]); |
| @@ -818,16 +815,10 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 818 | { | 815 | { |
| 819 | struct signal_struct *sig; | 816 | struct signal_struct *sig; |
| 820 | 817 | ||
| 821 | if (clone_flags & CLONE_THREAD) { | 818 | if (clone_flags & CLONE_THREAD) |
| 822 | atomic_inc(¤t->signal->count); | ||
| 823 | atomic_inc(¤t->signal->live); | ||
| 824 | return 0; | 819 | return 0; |
| 825 | } | ||
| 826 | sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); | ||
| 827 | |||
| 828 | if (sig) | ||
| 829 | posix_cpu_timers_init_group(sig); | ||
| 830 | 820 | ||
| 821 | sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); | ||
| 831 | tsk->signal = sig; | 822 | tsk->signal = sig; |
| 832 | if (!sig) | 823 | if (!sig) |
| 833 | return -ENOMEM; | 824 | return -ENOMEM; |
| @@ -836,6 +827,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 836 | atomic_set(&sig->live, 1); | 827 | atomic_set(&sig->live, 1); |
| 837 | init_waitqueue_head(&sig->wait_chldexit); | 828 | init_waitqueue_head(&sig->wait_chldexit); |
| 838 | sig->flags = 0; | 829 | sig->flags = 0; |
| 830 | if (clone_flags & CLONE_NEWPID) | ||
| 831 | sig->flags |= SIGNAL_UNKILLABLE; | ||
| 839 | sig->group_exit_code = 0; | 832 | sig->group_exit_code = 0; |
| 840 | sig->group_exit_task = NULL; | 833 | sig->group_exit_task = NULL; |
| 841 | sig->group_stop_count = 0; | 834 | sig->group_stop_count = 0; |
| @@ -865,6 +858,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
| 865 | memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); | 858 | memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); |
| 866 | task_unlock(current->group_leader); | 859 | task_unlock(current->group_leader); |
| 867 | 860 | ||
| 861 | posix_cpu_timers_init_group(sig); | ||
| 862 | |||
| 868 | acct_init_pacct(&sig->pacct); | 863 | acct_init_pacct(&sig->pacct); |
| 869 | 864 | ||
| 870 | tty_audit_fork(sig); | 865 | tty_audit_fork(sig); |
| @@ -879,16 +874,6 @@ void __cleanup_signal(struct signal_struct *sig) | |||
| 879 | kmem_cache_free(signal_cachep, sig); | 874 | kmem_cache_free(signal_cachep, sig); |
| 880 | } | 875 | } |
| 881 | 876 | ||
| 882 | static void cleanup_signal(struct task_struct *tsk) | ||
| 883 | { | ||
| 884 | struct signal_struct *sig = tsk->signal; | ||
| 885 | |||
| 886 | atomic_dec(&sig->live); | ||
| 887 | |||
| 888 | if (atomic_dec_and_test(&sig->count)) | ||
| 889 | __cleanup_signal(sig); | ||
| 890 | } | ||
| 891 | |||
| 892 | static void copy_flags(unsigned long clone_flags, struct task_struct *p) | 877 | static void copy_flags(unsigned long clone_flags, struct task_struct *p) |
| 893 | { | 878 | { |
| 894 | unsigned long new_flags = p->flags; | 879 | unsigned long new_flags = p->flags; |
| @@ -983,6 +968,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 983 | if (!p) | 968 | if (!p) |
| 984 | goto fork_out; | 969 | goto fork_out; |
| 985 | 970 | ||
| 971 | ftrace_graph_init_task(p); | ||
| 972 | |||
| 986 | rt_mutex_init_task(p); | 973 | rt_mutex_init_task(p); |
| 987 | 974 | ||
| 988 | #ifdef CONFIG_PROVE_LOCKING | 975 | #ifdef CONFIG_PROVE_LOCKING |
| @@ -1028,7 +1015,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1028 | p->vfork_done = NULL; | 1015 | p->vfork_done = NULL; |
| 1029 | spin_lock_init(&p->alloc_lock); | 1016 | spin_lock_init(&p->alloc_lock); |
| 1030 | 1017 | ||
| 1031 | clear_tsk_thread_flag(p, TIF_SIGPENDING); | ||
| 1032 | init_sigpending(&p->pending); | 1018 | init_sigpending(&p->pending); |
| 1033 | 1019 | ||
| 1034 | p->utime = cputime_zero; | 1020 | p->utime = cputime_zero; |
| @@ -1041,11 +1027,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1041 | 1027 | ||
| 1042 | p->default_timer_slack_ns = current->timer_slack_ns; | 1028 | p->default_timer_slack_ns = current->timer_slack_ns; |
| 1043 | 1029 | ||
| 1044 | #ifdef CONFIG_DETECT_SOFTLOCKUP | ||
| 1045 | p->last_switch_count = 0; | ||
| 1046 | p->last_switch_timestamp = 0; | ||
| 1047 | #endif | ||
| 1048 | |||
| 1049 | task_io_accounting_init(&p->ioac); | 1030 | task_io_accounting_init(&p->ioac); |
| 1050 | acct_clear_integrals(p); | 1031 | acct_clear_integrals(p); |
| 1051 | 1032 | ||
| @@ -1095,12 +1076,16 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1095 | #ifdef CONFIG_DEBUG_MUTEXES | 1076 | #ifdef CONFIG_DEBUG_MUTEXES |
| 1096 | p->blocked_on = NULL; /* not blocked yet */ | 1077 | p->blocked_on = NULL; /* not blocked yet */ |
| 1097 | #endif | 1078 | #endif |
| 1098 | if (unlikely(current->ptrace)) | 1079 | |
| 1099 | ptrace_fork(p, clone_flags); | 1080 | p->bts = NULL; |
| 1100 | 1081 | ||
| 1101 | /* Perform scheduler related setup. Assign this task to a CPU. */ | 1082 | /* Perform scheduler related setup. Assign this task to a CPU. */ |
| 1102 | sched_fork(p, clone_flags); | 1083 | sched_fork(p, clone_flags); |
| 1103 | 1084 | ||
| 1085 | retval = perf_counter_init_task(p); | ||
| 1086 | if (retval) | ||
| 1087 | goto bad_fork_cleanup_policy; | ||
| 1088 | |||
| 1104 | if ((retval = audit_alloc(p))) | 1089 | if ((retval = audit_alloc(p))) |
| 1105 | goto bad_fork_cleanup_policy; | 1090 | goto bad_fork_cleanup_policy; |
| 1106 | /* copy all the process information */ | 1091 | /* copy all the process information */ |
| @@ -1120,7 +1105,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1120 | goto bad_fork_cleanup_mm; | 1105 | goto bad_fork_cleanup_mm; |
| 1121 | if ((retval = copy_io(clone_flags, p))) | 1106 | if ((retval = copy_io(clone_flags, p))) |
| 1122 | goto bad_fork_cleanup_namespaces; | 1107 | goto bad_fork_cleanup_namespaces; |
| 1123 | retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); | 1108 | retval = copy_thread(clone_flags, stack_start, stack_size, p, regs); |
| 1124 | if (retval) | 1109 | if (retval) |
| 1125 | goto bad_fork_cleanup_io; | 1110 | goto bad_fork_cleanup_io; |
| 1126 | 1111 | ||
| @@ -1137,8 +1122,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1137 | } | 1122 | } |
| 1138 | } | 1123 | } |
| 1139 | 1124 | ||
| 1140 | ftrace_graph_init_task(p); | ||
| 1141 | |||
| 1142 | p->pid = pid_nr(pid); | 1125 | p->pid = pid_nr(pid); |
| 1143 | p->tgid = p->pid; | 1126 | p->tgid = p->pid; |
| 1144 | if (clone_flags & CLONE_THREAD) | 1127 | if (clone_flags & CLONE_THREAD) |
| @@ -1147,7 +1130,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1147 | if (current->nsproxy != p->nsproxy) { | 1130 | if (current->nsproxy != p->nsproxy) { |
| 1148 | retval = ns_cgroup_clone(p, pid); | 1131 | retval = ns_cgroup_clone(p, pid); |
| 1149 | if (retval) | 1132 | if (retval) |
| 1150 | goto bad_fork_free_graph; | 1133 | goto bad_fork_free_pid; |
| 1151 | } | 1134 | } |
| 1152 | 1135 | ||
| 1153 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; | 1136 | p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; |
| @@ -1239,10 +1222,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1239 | spin_unlock(¤t->sighand->siglock); | 1222 | spin_unlock(¤t->sighand->siglock); |
| 1240 | write_unlock_irq(&tasklist_lock); | 1223 | write_unlock_irq(&tasklist_lock); |
| 1241 | retval = -ERESTARTNOINTR; | 1224 | retval = -ERESTARTNOINTR; |
| 1242 | goto bad_fork_free_graph; | 1225 | goto bad_fork_free_pid; |
| 1243 | } | 1226 | } |
| 1244 | 1227 | ||
| 1245 | if (clone_flags & CLONE_THREAD) { | 1228 | if (clone_flags & CLONE_THREAD) { |
| 1229 | atomic_inc(¤t->signal->count); | ||
| 1230 | atomic_inc(¤t->signal->live); | ||
| 1246 | p->group_leader = current->group_leader; | 1231 | p->group_leader = current->group_leader; |
| 1247 | list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); | 1232 | list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); |
| 1248 | } | 1233 | } |
| @@ -1258,8 +1243,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1258 | p->signal->leader_pid = pid; | 1243 | p->signal->leader_pid = pid; |
| 1259 | tty_kref_put(p->signal->tty); | 1244 | tty_kref_put(p->signal->tty); |
| 1260 | p->signal->tty = tty_kref_get(current->signal->tty); | 1245 | p->signal->tty = tty_kref_get(current->signal->tty); |
| 1261 | set_task_pgrp(p, task_pgrp_nr(current)); | ||
| 1262 | set_task_session(p, task_session_nr(current)); | ||
| 1263 | attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); | 1246 | attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); |
| 1264 | attach_pid(p, PIDTYPE_SID, task_session(current)); | 1247 | attach_pid(p, PIDTYPE_SID, task_session(current)); |
| 1265 | list_add_tail_rcu(&p->tasks, &init_task.tasks); | 1248 | list_add_tail_rcu(&p->tasks, &init_task.tasks); |
| @@ -1274,10 +1257,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1274 | write_unlock_irq(&tasklist_lock); | 1257 | write_unlock_irq(&tasklist_lock); |
| 1275 | proc_fork_connector(p); | 1258 | proc_fork_connector(p); |
| 1276 | cgroup_post_fork(p); | 1259 | cgroup_post_fork(p); |
| 1260 | perf_counter_fork(p); | ||
| 1277 | return p; | 1261 | return p; |
| 1278 | 1262 | ||
| 1279 | bad_fork_free_graph: | ||
| 1280 | ftrace_graph_exit_task(p); | ||
| 1281 | bad_fork_free_pid: | 1263 | bad_fork_free_pid: |
| 1282 | if (pid != &init_struct_pid) | 1264 | if (pid != &init_struct_pid) |
| 1283 | free_pid(pid); | 1265 | free_pid(pid); |
| @@ -1289,7 +1271,8 @@ bad_fork_cleanup_mm: | |||
| 1289 | if (p->mm) | 1271 | if (p->mm) |
| 1290 | mmput(p->mm); | 1272 | mmput(p->mm); |
| 1291 | bad_fork_cleanup_signal: | 1273 | bad_fork_cleanup_signal: |
| 1292 | cleanup_signal(p); | 1274 | if (!(clone_flags & CLONE_THREAD)) |
| 1275 | __cleanup_signal(p->signal); | ||
| 1293 | bad_fork_cleanup_sighand: | 1276 | bad_fork_cleanup_sighand: |
| 1294 | __cleanup_sighand(p->sighand); | 1277 | __cleanup_sighand(p->sighand); |
| 1295 | bad_fork_cleanup_fs: | 1278 | bad_fork_cleanup_fs: |
| @@ -1301,6 +1284,7 @@ bad_fork_cleanup_semundo: | |||
| 1301 | bad_fork_cleanup_audit: | 1284 | bad_fork_cleanup_audit: |
| 1302 | audit_free(p); | 1285 | audit_free(p); |
| 1303 | bad_fork_cleanup_policy: | 1286 | bad_fork_cleanup_policy: |
| 1287 | perf_counter_free_task(p); | ||
| 1304 | #ifdef CONFIG_NUMA | 1288 | #ifdef CONFIG_NUMA |
| 1305 | mpol_put(p->mempolicy); | 1289 | mpol_put(p->mempolicy); |
| 1306 | bad_fork_cleanup_cgroup: | 1290 | bad_fork_cleanup_cgroup: |
| @@ -1417,7 +1401,7 @@ long do_fork(unsigned long clone_flags, | |||
| 1417 | } | 1401 | } |
| 1418 | 1402 | ||
| 1419 | audit_finish_fork(p); | 1403 | audit_finish_fork(p); |
| 1420 | tracehook_report_clone(trace, regs, clone_flags, nr, p); | 1404 | tracehook_report_clone(regs, clone_flags, nr, p); |
| 1421 | 1405 | ||
| 1422 | /* | 1406 | /* |
| 1423 | * We set PF_STARTING at creation in case tracing wants to | 1407 | * We set PF_STARTING at creation in case tracing wants to |
| @@ -1469,20 +1453,21 @@ void __init proc_caches_init(void) | |||
| 1469 | { | 1453 | { |
| 1470 | sighand_cachep = kmem_cache_create("sighand_cache", | 1454 | sighand_cachep = kmem_cache_create("sighand_cache", |
| 1471 | sizeof(struct sighand_struct), 0, | 1455 | sizeof(struct sighand_struct), 0, |
| 1472 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU, | 1456 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU| |
| 1473 | sighand_ctor); | 1457 | SLAB_NOTRACK, sighand_ctor); |
| 1474 | signal_cachep = kmem_cache_create("signal_cache", | 1458 | signal_cachep = kmem_cache_create("signal_cache", |
| 1475 | sizeof(struct signal_struct), 0, | 1459 | sizeof(struct signal_struct), 0, |
| 1476 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 1460 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
| 1477 | files_cachep = kmem_cache_create("files_cache", | 1461 | files_cachep = kmem_cache_create("files_cache", |
| 1478 | sizeof(struct files_struct), 0, | 1462 | sizeof(struct files_struct), 0, |
| 1479 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 1463 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
| 1480 | fs_cachep = kmem_cache_create("fs_cache", | 1464 | fs_cachep = kmem_cache_create("fs_cache", |
| 1481 | sizeof(struct fs_struct), 0, | 1465 | sizeof(struct fs_struct), 0, |
| 1482 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 1466 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
| 1483 | mm_cachep = kmem_cache_create("mm_struct", | 1467 | mm_cachep = kmem_cache_create("mm_struct", |
| 1484 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, | 1468 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
| 1485 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 1469 | SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL); |
| 1470 | vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC); | ||
| 1486 | mmap_init(); | 1471 | mmap_init(); |
| 1487 | } | 1472 | } |
| 1488 | 1473 | ||
| @@ -1538,12 +1523,16 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) | |||
| 1538 | { | 1523 | { |
| 1539 | struct fs_struct *fs = current->fs; | 1524 | struct fs_struct *fs = current->fs; |
| 1540 | 1525 | ||
| 1541 | if ((unshare_flags & CLONE_FS) && | 1526 | if (!(unshare_flags & CLONE_FS) || !fs) |
| 1542 | (fs && atomic_read(&fs->count) > 1)) { | 1527 | return 0; |
| 1543 | *new_fsp = __copy_fs_struct(current->fs); | 1528 | |
| 1544 | if (!*new_fsp) | 1529 | /* don't need lock here; in the worst case we'll do useless copy */ |
| 1545 | return -ENOMEM; | 1530 | if (fs->users == 1) |
| 1546 | } | 1531 | return 0; |
| 1532 | |||
| 1533 | *new_fsp = copy_fs_struct(fs); | ||
| 1534 | if (!*new_fsp) | ||
| 1535 | return -ENOMEM; | ||
| 1547 | 1536 | ||
| 1548 | return 0; | 1537 | return 0; |
| 1549 | } | 1538 | } |
| @@ -1659,8 +1648,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) | |||
| 1659 | 1648 | ||
| 1660 | if (new_fs) { | 1649 | if (new_fs) { |
| 1661 | fs = current->fs; | 1650 | fs = current->fs; |
| 1651 | write_lock(&fs->lock); | ||
| 1662 | current->fs = new_fs; | 1652 | current->fs = new_fs; |
| 1663 | new_fs = fs; | 1653 | if (--fs->users) |
| 1654 | new_fs = NULL; | ||
| 1655 | else | ||
| 1656 | new_fs = fs; | ||
| 1657 | write_unlock(&fs->lock); | ||
| 1664 | } | 1658 | } |
| 1665 | 1659 | ||
| 1666 | if (new_mm) { | 1660 | if (new_mm) { |
| @@ -1699,7 +1693,7 @@ bad_unshare_cleanup_sigh: | |||
| 1699 | 1693 | ||
| 1700 | bad_unshare_cleanup_fs: | 1694 | bad_unshare_cleanup_fs: |
| 1701 | if (new_fs) | 1695 | if (new_fs) |
| 1702 | put_fs_struct(new_fs); | 1696 | free_fs_struct(new_fs); |
| 1703 | 1697 | ||
| 1704 | bad_unshare_cleanup_thread: | 1698 | bad_unshare_cleanup_thread: |
| 1705 | bad_unshare_out: | 1699 | bad_unshare_out: |
