copy_process(pid => &init_struct_pid) doesn't do attach_pid/etc. It shouldn't, but this means that the idle threads run with the wrong pids copied from the caller's task_struct. In x86 case the caller is either kernel_init() thread or keventd. In particular, this means that after the series of cpu_up/cpu_down an idle thread (which never exits) can run with .pid pointing to nowhere. Change fork_idle() to initialize idle->pids[] correctly. We only set .pid = &init_struct_pid but do not add .node to list, INIT_TASK() does the same for the boot-cpu idle thread (swapper).
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -1338,6 +1338,16 @@ noinline struct pt_regs * __cpuinit __attribute__((weak)) idle_regs(struct pt_re · 1337 unmodified lines | ||
| 1338 | 1338 | return regs; |
| 1339 | 1339 | } |
| 1340 | 1340 | |
| 1341 | +static inline void init_idle_pids(struct pid_link *links) | |
| 1342 | +{ | |
| 1343 | + enum pid_type type; | |
| 1344 | + | |
| 1345 | + for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) { | |
| 1346 | + INIT_HLIST_NODE(&links[type].node); /* not really needed */ | |
| 1347 | + links[type].pid = &init_struct_pid; | |
| 1348 | + } | |
| 1349 | +} | |
| 1350 | + | |
| 1341 | 1351 | struct task_struct * __cpuinit fork_idle(int cpu) |
| 1342 | 1352 | { |
| 1343 | 1353 | struct task_struct *task; |
| @@ -1345,8 +1355,10 @@ struct task_struct * __cpuinit fork_idle(int cpu) · 1 unmodified line | ||
| 1345 | 1355 | |
| 1346 | 1356 | task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, |
| 1347 | 1357 | &init_struct_pid, 0); |
| 1348 | − if (!IS_ERR(task)) | |
| 1358 | + if (!IS_ERR(task)) { | |
| 1359 | + init_idle_pids(task->pids); | |
| 1349 | 1360 | init_idle(task, cpu); |
| 1361 | + } | |
| 1350 | 1362 | |
| 1351 | 1363 | return task; |
| 1352 | 1364 | } |