X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=kernel%2Ffork.c;h=ab5211b9e622cf94d07b7bfb4ccfd9bac85e7b79;hb=8c50c817566dfa4581f82373aac39f3e608a7dc8;hp=31a32c7dd16953c8167914a3ec4f84fce23f3c20;hpb=a70f35af4e49f87ba4b6c4b30220fbb66cd74af6;p=uclinux-h8%2Flinux.git diff --git a/kernel/fork.c b/kernel/fork.c index 31a32c7dd169..ab5211b9e622 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -787,9 +787,6 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) /* Get rid of any cached register state */ deactivate_mm(tsk, mm); - if (tsk->vfork_done) - complete_vfork_done(tsk); - /* * If we're exiting normally, clear a user-space tid field if * requested. We leave this alone when dying by signal, to leave @@ -810,6 +807,13 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) } tsk->clear_child_tid = NULL; } + + /* + * All done, finally we can wake up parent and return this mm to him. + * Also kthread_stop() uses this completion for synchronization. + */ + if (tsk->vfork_done) + complete_vfork_done(tsk); } /* @@ -1411,6 +1415,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, */ p->group_leader = p; INIT_LIST_HEAD(&p->thread_group); + INIT_HLIST_HEAD(&p->task_works); /* Now that the task is set up, run cgroup callbacks if * necessary. We need to run them before the task is visible