diff options
| -rw-r--r-- | arch/mips/kernel/smp.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 383aeb95cb49..32a256101082 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
| @@ -193,6 +193,22 @@ void __devinit smp_prepare_boot_cpu(void) | |||
| 193 | */ | 193 | */ |
| 194 | static struct task_struct *cpu_idle_thread[NR_CPUS]; | 194 | static struct task_struct *cpu_idle_thread[NR_CPUS]; |
| 195 | 195 | ||
| 196 | struct create_idle { | ||
| 197 | struct work_struct work; | ||
| 198 | struct task_struct *idle; | ||
| 199 | struct completion done; | ||
| 200 | int cpu; | ||
| 201 | }; | ||
| 202 | |||
| 203 | static void __cpuinit do_fork_idle(struct work_struct *work) | ||
| 204 | { | ||
| 205 | struct create_idle *c_idle = | ||
| 206 | container_of(work, struct create_idle, work); | ||
| 207 | |||
| 208 | c_idle->idle = fork_idle(c_idle->cpu); | ||
| 209 | complete(&c_idle->done); | ||
| 210 | } | ||
| 211 | |||
| 196 | int __cpuinit __cpu_up(unsigned int cpu) | 212 | int __cpuinit __cpu_up(unsigned int cpu) |
| 197 | { | 213 | { |
| 198 | struct task_struct *idle; | 214 | struct task_struct *idle; |
| @@ -203,8 +219,19 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
| 203 | * Linux can schedule processes on this slave. | 219 | * Linux can schedule processes on this slave. |
| 204 | */ | 220 | */ |
| 205 | if (!cpu_idle_thread[cpu]) { | 221 | if (!cpu_idle_thread[cpu]) { |
| 206 | idle = fork_idle(cpu); | 222 | /* |
| 207 | cpu_idle_thread[cpu] = idle; | 223 | * Schedule work item to avoid forking user task |
| 224 | * Ported from arch/x86/kernel/smpboot.c | ||
| 225 | */ | ||
| 226 | struct create_idle c_idle = { | ||
| 227 | .cpu = cpu, | ||
| 228 | .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), | ||
| 229 | }; | ||
| 230 | |||
| 231 | INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle); | ||
| 232 | schedule_work(&c_idle.work); | ||
| 233 | wait_for_completion(&c_idle.done); | ||
| 234 | idle = cpu_idle_thread[cpu] = c_idle.idle; | ||
| 208 | 235 | ||
| 209 | if (IS_ERR(idle)) | 236 | if (IS_ERR(idle)) |
| 210 | panic(KERN_ERR "Fork failed for CPU %d", cpu); | 237 | panic(KERN_ERR "Fork failed for CPU %d", cpu); |
