static noinline void __ref rest_init(void) { int pid; kernel_thread(kernel_init, NULL, CLONE_FS); numa_default_policy(); pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); rcu_read_lock(); kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); }
int kthreadd(void *unused) { struct task_struct *tsk = current;
/* Setup a clean context for our children to inherit. */ set_task_comm(tsk, "kthreadd"); ignore_signals(tsk); set_cpus_allowed_ptr(tsk, cpu_all_mask); set_mems_allowed(node_states[N_MEMORY]);
current->flags |= PF_NOFREEZE;
for (;;) { set_current_state(TASK_INTERRUPTIBLE); if (list_empty(&kthread_create_list))如果为真,继续放弃CPU。 schedule(); __set_current_state(TASK_RUNNING);设置内核线程状态
spin_lock(&kthread_create_lock); while (!list_empty(&kthread_create_list)) {取得链表每个元素进行创建内核线程 struct kthread_create_info *create;
create = list_entry(kthread_create_list.next, struct kthread_create_info, list); list_del_init(&create->list); spin_unlock(&kthread_create_lock);
create_kthread(create);//真正创建处理
spin_lock(&kthread_create_lock); } spin_unlock(&kthread_create_lock); }
return 0; }
static void create_kthread(struct kthread_create_info *create) { int pid;
#ifdef CONFIG_NUMA current->pref_node_fork = create->node; #endif /* We want our own signal handler (we take no signals by default). */ pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
需要注意这里给的是kthread,所以,所有的内核线程第一个函数都是kthread if (pid < 0) { /* If user was SIGKILLed, I release the structure. */ struct completion *done = xchg(&create->done, NULL);
if (!done) { kfree(create); return; } create->result = ERR_PTR(pid); complete(done);唤醒原先需要创建线程的线程 } }
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, (unsigned long)arg, NULL, NULL, 0);fork处理 }