History

pids: fix fork_idle() to setup ->pids correctly

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).

Oleg Nesterov committed 16 years ago

Commit f106eee1 parent f2001141 file · +13 −1Browse files

Unified · Split

kernel/fork.c+13−1
@@ -1338,6 +1338,16 @@ noinline struct pt_regs * __cpuinit __attribute__((weak)) idle_regs(struct pt_re · 1337 unmodified lines
13381338 return regs;
13391339 }
13401340
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+
13411351 struct task_struct * __cpuinit fork_idle(int cpu)
13421352 {
13431353 struct task_struct *task;
@@ -1345,8 +1355,10 @@ struct task_struct * __cpuinit fork_idle(int cpu) · 1 unmodified line
13451355
13461356 task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
13471357 &init_struct_pid, 0);
1348− if (!IS_ERR(task))
1358+ if (!IS_ERR(task)) {
1359+ init_idle_pids(task->pids);
13491360 init_idle(task, cpu);
1361+ }
13501362
13511363 return task;
13521364 }