diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index a28d11e10877..2c7806873bfd 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1003,9 +1003,6 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1003 | p->pdeath_signal = 0; | 1003 | p->pdeath_signal = 0; |
1004 | p->exit_state = 0; | 1004 | p->exit_state = 0; |
1005 | 1005 | ||
1006 | /* Perform scheduler related setup */ | ||
1007 | sched_fork(p); | ||
1008 | |||
1009 | /* | 1006 | /* |
1010 | * Ok, make it visible to the rest of the system. | 1007 | * Ok, make it visible to the rest of the system. |
1011 | * We dont wake it up yet. | 1008 | * We dont wake it up yet. |
@@ -1014,18 +1011,24 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1014 | INIT_LIST_HEAD(&p->ptrace_children); | 1011 | INIT_LIST_HEAD(&p->ptrace_children); |
1015 | INIT_LIST_HEAD(&p->ptrace_list); | 1012 | INIT_LIST_HEAD(&p->ptrace_list); |
1016 | 1013 | ||
1014 | /* Perform scheduler related setup. Assign this task to a CPU. */ | ||
1015 | sched_fork(p, clone_flags); | ||
1016 | |||
1017 | /* Need tasklist lock for parent etc handling! */ | 1017 | /* Need tasklist lock for parent etc handling! */ |
1018 | write_lock_irq(&tasklist_lock); | 1018 | write_lock_irq(&tasklist_lock); |
1019 | 1019 | ||
1020 | /* | 1020 | /* |
1021 | * The task hasn't been attached yet, so cpus_allowed mask cannot | 1021 | * The task hasn't been attached yet, so its cpus_allowed mask will |
1022 | * have changed. The cpus_allowed mask of the parent may have | 1022 | * not be changed, nor will its assigned CPU. |
1023 | * changed after it was copied first time, and it may then move to | 1023 | * |
1024 | * another CPU - so we re-copy it here and set the child's CPU to | 1024 | * The cpus_allowed mask of the parent may have changed after it was |
1025 | * the parent's CPU. This avoids alot of nasty races. | 1025 | * copied first time - so re-copy it here, then check the child's CPU |
1026 | * to ensure it is on a valid CPU (and if not, just force it back to | ||
1027 | * parent's CPU). This avoids alot of nasty races. | ||
1026 | */ | 1028 | */ |
1027 | p->cpus_allowed = current->cpus_allowed; | 1029 | p->cpus_allowed = current->cpus_allowed; |
1028 | set_task_cpu(p, smp_processor_id()); | 1030 | if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed))) |
1031 | set_task_cpu(p, smp_processor_id()); | ||
1029 | 1032 | ||
1030 | /* | 1033 | /* |
1031 | * Check for pending SIGKILL! The new thread should not be allowed | 1034 | * Check for pending SIGKILL! The new thread should not be allowed |