diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index dfa736c98d17..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 | ||
| @@ -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 |
