diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 158710d22566..4ae8cfc1c89c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/binfmts.h> | 28 | #include <linux/binfmts.h> |
29 | #include <linux/mman.h> | 29 | #include <linux/mman.h> |
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/capability.h> | ||
31 | #include <linux/cpu.h> | 32 | #include <linux/cpu.h> |
32 | #include <linux/cpuset.h> | 33 | #include <linux/cpuset.h> |
33 | #include <linux/security.h> | 34 | #include <linux/security.h> |
@@ -171,10 +172,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
171 | return NULL; | 172 | return NULL; |
172 | } | 173 | } |
173 | 174 | ||
174 | *ti = *orig->thread_info; | ||
175 | *tsk = *orig; | 175 | *tsk = *orig; |
176 | tsk->thread_info = ti; | 176 | tsk->thread_info = ti; |
177 | ti->task = tsk; | 177 | setup_thread_stack(tsk, orig); |
178 | 178 | ||
179 | /* One for us, one for whoever does the "release_task()" (usually parent) */ | 179 | /* One for us, one for whoever does the "release_task()" (usually parent) */ |
180 | atomic_set(&tsk->usage,2); | 180 | atomic_set(&tsk->usage,2); |
@@ -264,7 +264,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
264 | rb_parent = &tmp->vm_rb; | 264 | rb_parent = &tmp->vm_rb; |
265 | 265 | ||
266 | mm->map_count++; | 266 | mm->map_count++; |
267 | retval = copy_page_range(mm, oldmm, tmp); | 267 | retval = copy_page_range(mm, oldmm, mpnt); |
268 | 268 | ||
269 | if (tmp->vm_ops && tmp->vm_ops->open) | 269 | if (tmp->vm_ops && tmp->vm_ops->open) |
270 | tmp->vm_ops->open(tmp); | 270 | tmp->vm_ops->open(tmp); |
@@ -324,7 +324,6 @@ static struct mm_struct * mm_init(struct mm_struct * mm) | |||
324 | spin_lock_init(&mm->page_table_lock); | 324 | spin_lock_init(&mm->page_table_lock); |
325 | rwlock_init(&mm->ioctx_list_lock); | 325 | rwlock_init(&mm->ioctx_list_lock); |
326 | mm->ioctx_list = NULL; | 326 | mm->ioctx_list = NULL; |
327 | mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm); | ||
328 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 327 | mm->free_area_cache = TASK_UNMAPPED_BASE; |
329 | mm->cached_hole_size = ~0UL; | 328 | mm->cached_hole_size = ~0UL; |
330 | 329 | ||
@@ -745,6 +744,14 @@ int unshare_files(void) | |||
745 | 744 | ||
746 | EXPORT_SYMBOL(unshare_files); | 745 | EXPORT_SYMBOL(unshare_files); |
747 | 746 | ||
747 | void sighand_free_cb(struct rcu_head *rhp) | ||
748 | { | ||
749 | struct sighand_struct *sp; | ||
750 | |||
751 | sp = container_of(rhp, struct sighand_struct, rcu); | ||
752 | kmem_cache_free(sighand_cachep, sp); | ||
753 | } | ||
754 | |||
748 | static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) | 755 | static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) |
749 | { | 756 | { |
750 | struct sighand_struct *sig; | 757 | struct sighand_struct *sig; |
@@ -754,7 +761,7 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t | |||
754 | return 0; | 761 | return 0; |
755 | } | 762 | } |
756 | sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); | 763 | sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); |
757 | tsk->sighand = sig; | 764 | rcu_assign_pointer(tsk->sighand, sig); |
758 | if (!sig) | 765 | if (!sig) |
759 | return -ENOMEM; | 766 | return -ENOMEM; |
760 | spin_lock_init(&sig->siglock); | 767 | spin_lock_init(&sig->siglock); |
@@ -795,19 +802,16 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts | |||
795 | init_sigpending(&sig->shared_pending); | 802 | init_sigpending(&sig->shared_pending); |
796 | INIT_LIST_HEAD(&sig->posix_timers); | 803 | INIT_LIST_HEAD(&sig->posix_timers); |
797 | 804 | ||
798 | sig->it_real_value = sig->it_real_incr = 0; | 805 | hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC); |
806 | sig->it_real_incr.tv64 = 0; | ||
799 | sig->real_timer.function = it_real_fn; | 807 | sig->real_timer.function = it_real_fn; |
800 | sig->real_timer.data = (unsigned long) tsk; | 808 | sig->real_timer.data = tsk; |
801 | init_timer(&sig->real_timer); | ||
802 | 809 | ||
803 | sig->it_virt_expires = cputime_zero; | 810 | sig->it_virt_expires = cputime_zero; |
804 | sig->it_virt_incr = cputime_zero; | 811 | sig->it_virt_incr = cputime_zero; |
805 | sig->it_prof_expires = cputime_zero; | 812 | sig->it_prof_expires = cputime_zero; |
806 | sig->it_prof_incr = cputime_zero; | 813 | sig->it_prof_incr = cputime_zero; |
807 | 814 | ||
808 | sig->tty = current->signal->tty; | ||
809 | sig->pgrp = process_group(current); | ||
810 | sig->session = current->signal->session; | ||
811 | sig->leader = 0; /* session leadership doesn't inherit */ | 815 | sig->leader = 0; /* session leadership doesn't inherit */ |
812 | sig->tty_old_pgrp = 0; | 816 | sig->tty_old_pgrp = 0; |
813 | 817 | ||
@@ -919,7 +923,7 @@ static task_t *copy_process(unsigned long clone_flags, | |||
919 | if (nr_threads >= max_threads) | 923 | if (nr_threads >= max_threads) |
920 | goto bad_fork_cleanup_count; | 924 | goto bad_fork_cleanup_count; |
921 | 925 | ||
922 | if (!try_module_get(p->thread_info->exec_domain->module)) | 926 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) |
923 | goto bad_fork_cleanup_count; | 927 | goto bad_fork_cleanup_count; |
924 | 928 | ||
925 | if (p->binfmt && !try_module_get(p->binfmt->module)) | 929 | if (p->binfmt && !try_module_get(p->binfmt->module)) |
@@ -966,15 +970,20 @@ static task_t *copy_process(unsigned long clone_flags, | |||
966 | p->io_context = NULL; | 970 | p->io_context = NULL; |
967 | p->io_wait = NULL; | 971 | p->io_wait = NULL; |
968 | p->audit_context = NULL; | 972 | p->audit_context = NULL; |
973 | cpuset_fork(p); | ||
969 | #ifdef CONFIG_NUMA | 974 | #ifdef CONFIG_NUMA |
970 | p->mempolicy = mpol_copy(p->mempolicy); | 975 | p->mempolicy = mpol_copy(p->mempolicy); |
971 | if (IS_ERR(p->mempolicy)) { | 976 | if (IS_ERR(p->mempolicy)) { |
972 | retval = PTR_ERR(p->mempolicy); | 977 | retval = PTR_ERR(p->mempolicy); |
973 | p->mempolicy = NULL; | 978 | p->mempolicy = NULL; |
974 | goto bad_fork_cleanup; | 979 | goto bad_fork_cleanup_cpuset; |
975 | } | 980 | } |
976 | #endif | 981 | #endif |
977 | 982 | ||
983 | #ifdef CONFIG_DEBUG_MUTEXES | ||
984 | p->blocked_on = NULL; /* not blocked yet */ | ||
985 | #endif | ||
986 | |||
978 | p->tgid = p->pid; | 987 | p->tgid = p->pid; |
979 | if (clone_flags & CLONE_THREAD) | 988 | if (clone_flags & CLONE_THREAD) |
980 | p->tgid = current->tgid; | 989 | p->tgid = current->tgid; |
@@ -1126,29 +1135,22 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1126 | if (unlikely(p->ptrace & PT_PTRACED)) | 1135 | if (unlikely(p->ptrace & PT_PTRACED)) |
1127 | __ptrace_link(p, current->parent); | 1136 | __ptrace_link(p, current->parent); |
1128 | 1137 | ||
1129 | cpuset_fork(p); | ||
1130 | |||
1131 | attach_pid(p, PIDTYPE_PID, p->pid); | 1138 | attach_pid(p, PIDTYPE_PID, p->pid); |
1132 | attach_pid(p, PIDTYPE_TGID, p->tgid); | 1139 | attach_pid(p, PIDTYPE_TGID, p->tgid); |
1133 | if (thread_group_leader(p)) { | 1140 | if (thread_group_leader(p)) { |
1141 | p->signal->tty = current->signal->tty; | ||
1142 | p->signal->pgrp = process_group(current); | ||
1143 | p->signal->session = current->signal->session; | ||
1134 | attach_pid(p, PIDTYPE_PGID, process_group(p)); | 1144 | attach_pid(p, PIDTYPE_PGID, process_group(p)); |
1135 | attach_pid(p, PIDTYPE_SID, p->signal->session); | 1145 | attach_pid(p, PIDTYPE_SID, p->signal->session); |
1136 | if (p->pid) | 1146 | if (p->pid) |
1137 | __get_cpu_var(process_counts)++; | 1147 | __get_cpu_var(process_counts)++; |
1138 | } | 1148 | } |
1139 | 1149 | ||
1140 | proc_fork_connector(p); | ||
1141 | if (!current->signal->tty && p->signal->tty) | ||
1142 | p->signal->tty = NULL; | ||
1143 | |||
1144 | nr_threads++; | 1150 | nr_threads++; |
1145 | total_forks++; | 1151 | total_forks++; |
1146 | write_unlock_irq(&tasklist_lock); | 1152 | write_unlock_irq(&tasklist_lock); |
1147 | retval = 0; | 1153 | proc_fork_connector(p); |
1148 | |||
1149 | fork_out: | ||
1150 | if (retval) | ||
1151 | return ERR_PTR(retval); | ||
1152 | return p; | 1154 | return p; |
1153 | 1155 | ||
1154 | bad_fork_cleanup_namespace: | 1156 | bad_fork_cleanup_namespace: |
@@ -1175,19 +1177,22 @@ bad_fork_cleanup_security: | |||
1175 | bad_fork_cleanup_policy: | 1177 | bad_fork_cleanup_policy: |
1176 | #ifdef CONFIG_NUMA | 1178 | #ifdef CONFIG_NUMA |
1177 | mpol_free(p->mempolicy); | 1179 | mpol_free(p->mempolicy); |
1180 | bad_fork_cleanup_cpuset: | ||
1178 | #endif | 1181 | #endif |
1182 | cpuset_exit(p); | ||
1179 | bad_fork_cleanup: | 1183 | bad_fork_cleanup: |
1180 | if (p->binfmt) | 1184 | if (p->binfmt) |
1181 | module_put(p->binfmt->module); | 1185 | module_put(p->binfmt->module); |
1182 | bad_fork_cleanup_put_domain: | 1186 | bad_fork_cleanup_put_domain: |
1183 | module_put(p->thread_info->exec_domain->module); | 1187 | module_put(task_thread_info(p)->exec_domain->module); |
1184 | bad_fork_cleanup_count: | 1188 | bad_fork_cleanup_count: |
1185 | put_group_info(p->group_info); | 1189 | put_group_info(p->group_info); |
1186 | atomic_dec(&p->user->processes); | 1190 | atomic_dec(&p->user->processes); |
1187 | free_uid(p->user); | 1191 | free_uid(p->user); |
1188 | bad_fork_free: | 1192 | bad_fork_free: |
1189 | free_task(p); | 1193 | free_task(p); |
1190 | goto fork_out; | 1194 | fork_out: |
1195 | return ERR_PTR(retval); | ||
1191 | } | 1196 | } |
1192 | 1197 | ||
1193 | struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs) | 1198 | struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs) |
@@ -1293,6 +1298,10 @@ long do_fork(unsigned long clone_flags, | |||
1293 | return pid; | 1298 | return pid; |
1294 | } | 1299 | } |
1295 | 1300 | ||
1301 | #ifndef ARCH_MIN_MMSTRUCT_ALIGN | ||
1302 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 | ||
1303 | #endif | ||
1304 | |||
1296 | void __init proc_caches_init(void) | 1305 | void __init proc_caches_init(void) |
1297 | { | 1306 | { |
1298 | sighand_cachep = kmem_cache_create("sighand_cache", | 1307 | sighand_cachep = kmem_cache_create("sighand_cache", |
@@ -1311,6 +1320,6 @@ void __init proc_caches_init(void) | |||
1311 | sizeof(struct vm_area_struct), 0, | 1320 | sizeof(struct vm_area_struct), 0, |
1312 | SLAB_PANIC, NULL, NULL); | 1321 | SLAB_PANIC, NULL, NULL); |
1313 | mm_cachep = kmem_cache_create("mm_struct", | 1322 | mm_cachep = kmem_cache_create("mm_struct", |
1314 | sizeof(struct mm_struct), 0, | 1323 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
1315 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 1324 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
1316 | } | 1325 | } |