diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 5721f0e3f2da..a17621c6cd42 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -800,14 +800,11 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
800 | * Allocate a new mm structure and copy contents from the | 800 | * Allocate a new mm structure and copy contents from the |
801 | * mm structure of the passed in task structure. | 801 | * mm structure of the passed in task structure. |
802 | */ | 802 | */ |
803 | struct mm_struct *dup_mm(struct task_struct *tsk) | 803 | static struct mm_struct *dup_mm(struct task_struct *tsk) |
804 | { | 804 | { |
805 | struct mm_struct *mm, *oldmm = current->mm; | 805 | struct mm_struct *mm, *oldmm = current->mm; |
806 | int err; | 806 | int err; |
807 | 807 | ||
808 | if (!oldmm) | ||
809 | return NULL; | ||
810 | |||
811 | mm = allocate_mm(); | 808 | mm = allocate_mm(); |
812 | if (!mm) | 809 | if (!mm) |
813 | goto fail_nomem; | 810 | goto fail_nomem; |
@@ -1035,6 +1032,11 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
1035 | sig->nr_threads = 1; | 1032 | sig->nr_threads = 1; |
1036 | atomic_set(&sig->live, 1); | 1033 | atomic_set(&sig->live, 1); |
1037 | atomic_set(&sig->sigcnt, 1); | 1034 | atomic_set(&sig->sigcnt, 1); |
1035 | |||
1036 | /* list_add(thread_node, thread_head) without INIT_LIST_HEAD() */ | ||
1037 | sig->thread_head = (struct list_head)LIST_HEAD_INIT(tsk->thread_node); | ||
1038 | tsk->thread_node = (struct list_head)LIST_HEAD_INIT(sig->thread_head); | ||
1039 | |||
1038 | init_waitqueue_head(&sig->wait_chldexit); | 1040 | init_waitqueue_head(&sig->wait_chldexit); |
1039 | sig->curr_target = tsk; | 1041 | sig->curr_target = tsk; |
1040 | init_sigpending(&sig->shared_pending); | 1042 | init_sigpending(&sig->shared_pending); |
@@ -1087,8 +1089,10 @@ static void rt_mutex_init_task(struct task_struct *p) | |||
1087 | { | 1089 | { |
1088 | raw_spin_lock_init(&p->pi_lock); | 1090 | raw_spin_lock_init(&p->pi_lock); |
1089 | #ifdef CONFIG_RT_MUTEXES | 1091 | #ifdef CONFIG_RT_MUTEXES |
1090 | plist_head_init(&p->pi_waiters); | 1092 | p->pi_waiters = RB_ROOT; |
1093 | p->pi_waiters_leftmost = NULL; | ||
1091 | p->pi_blocked_on = NULL; | 1094 | p->pi_blocked_on = NULL; |
1095 | p->pi_top_task = NULL; | ||
1092 | #endif | 1096 | #endif |
1093 | } | 1097 | } |
1094 | 1098 | ||
@@ -1172,7 +1176,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1172 | * do not allow it to share a thread group or signal handlers or | 1176 | * do not allow it to share a thread group or signal handlers or |
1173 | * parent with the forking task. | 1177 | * parent with the forking task. |
1174 | */ | 1178 | */ |
1175 | if (clone_flags & (CLONE_SIGHAND | CLONE_PARENT)) { | 1179 | if (clone_flags & CLONE_SIGHAND) { |
1176 | if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) || | 1180 | if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) || |
1177 | (task_active_pid_ns(current) != | 1181 | (task_active_pid_ns(current) != |
1178 | current->nsproxy->pid_ns_for_children)) | 1182 | current->nsproxy->pid_ns_for_children)) |
@@ -1222,7 +1226,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1222 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) | 1226 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) |
1223 | goto bad_fork_cleanup_count; | 1227 | goto bad_fork_cleanup_count; |
1224 | 1228 | ||
1225 | p->did_exec = 0; | ||
1226 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ | 1229 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ |
1227 | copy_flags(clone_flags, p); | 1230 | copy_flags(clone_flags, p); |
1228 | INIT_LIST_HEAD(&p->children); | 1231 | INIT_LIST_HEAD(&p->children); |
@@ -1311,7 +1314,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1311 | #endif | 1314 | #endif |
1312 | 1315 | ||
1313 | /* Perform scheduler related setup. Assign this task to a CPU. */ | 1316 | /* Perform scheduler related setup. Assign this task to a CPU. */ |
1314 | sched_fork(clone_flags, p); | 1317 | retval = sched_fork(clone_flags, p); |
1318 | if (retval) | ||
1319 | goto bad_fork_cleanup_policy; | ||
1315 | 1320 | ||
1316 | retval = perf_event_init_task(p); | 1321 | retval = perf_event_init_task(p); |
1317 | if (retval) | 1322 | if (retval) |
@@ -1403,13 +1408,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1403 | p->tgid = p->pid; | 1408 | p->tgid = p->pid; |
1404 | } | 1409 | } |
1405 | 1410 | ||
1406 | p->pdeath_signal = 0; | ||
1407 | p->exit_state = 0; | ||
1408 | |||
1409 | p->nr_dirtied = 0; | 1411 | p->nr_dirtied = 0; |
1410 | p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10); | 1412 | p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10); |
1411 | p->dirty_paused_when = 0; | 1413 | p->dirty_paused_when = 0; |
1412 | 1414 | ||
1415 | p->pdeath_signal = 0; | ||
1413 | INIT_LIST_HEAD(&p->thread_group); | 1416 | INIT_LIST_HEAD(&p->thread_group); |
1414 | p->task_works = NULL; | 1417 | p->task_works = NULL; |
1415 | 1418 | ||
@@ -1472,6 +1475,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1472 | atomic_inc(¤t->signal->sigcnt); | 1475 | atomic_inc(¤t->signal->sigcnt); |
1473 | list_add_tail_rcu(&p->thread_group, | 1476 | list_add_tail_rcu(&p->thread_group, |
1474 | &p->group_leader->thread_group); | 1477 | &p->group_leader->thread_group); |
1478 | list_add_tail_rcu(&p->thread_node, | ||
1479 | &p->signal->thread_head); | ||
1475 | } | 1480 | } |
1476 | attach_pid(p, PIDTYPE_PID); | 1481 | attach_pid(p, PIDTYPE_PID); |
1477 | nr_threads++; | 1482 | nr_threads++; |
@@ -1645,7 +1650,7 @@ SYSCALL_DEFINE0(fork) | |||
1645 | return do_fork(SIGCHLD, 0, 0, NULL, NULL); | 1650 | return do_fork(SIGCHLD, 0, 0, NULL, NULL); |
1646 | #else | 1651 | #else |
1647 | /* can not support in nommu mode */ | 1652 | /* can not support in nommu mode */ |
1648 | return(-EINVAL); | 1653 | return -EINVAL; |
1649 | #endif | 1654 | #endif |
1650 | } | 1655 | } |
1651 | #endif | 1656 | #endif |
@@ -1653,7 +1658,7 @@ SYSCALL_DEFINE0(fork) | |||
1653 | #ifdef __ARCH_WANT_SYS_VFORK | 1658 | #ifdef __ARCH_WANT_SYS_VFORK |
1654 | SYSCALL_DEFINE0(vfork) | 1659 | SYSCALL_DEFINE0(vfork) |
1655 | { | 1660 | { |
1656 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, | 1661 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, |
1657 | 0, NULL, NULL); | 1662 | 0, NULL, NULL); |
1658 | } | 1663 | } |
1659 | #endif | 1664 | #endif |