- keventd(ワークキュ)
- kswapd(メモリー回収)
- ksoftoirqd(ソフト割り込み
カーネルスレッドという名前はついているがLinuxからみたカーネルスレッドの一つ一つはスケージューリングにおいてユーザプロセスと同じ物。
ユーザプロセス作成と同じようにCLONE_VMなどから生成される。
static inline void context_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next) { struct mm_struct *mm, *oldmm; : : mm = next->mm; oldmm = prev->active_mm; : : if (unlikely(!mm)) { next->active_mm = oldmm; atomic_inc(&oldmm->mm_count); } else switch_mm(oldmm, mm, next); if (unlikely(!prev->mm)) { prev->active_mm = NULL; rq->prev_mm = oldmm; } switch_to(prev, next, prev); : finish_task_switch(this_rq(), prev); }
カーネルスレッドの生成はkernel_thread()を呼び出して行われる。
関数の定義はkernel/process.cあたりにある
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { struct pt_regs regs; memset(®s, 0, sizeof(regs)); regs.ebx = (unsigned long) fn; regs.edx = (unsigned long) arg; regs.xds = __USER_DS; regs.xes = __USER_DS; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; regs.xcs = __KERNEL_CS; regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); }
この辺を追っていくことで見覚えのあるdo_forkが出てくる。
フラグによってカーネルスレッドであろうがユーザスレッドであろうがLinuxからは同一のものとしてスケジューリングされるのであろう。
全貌を追いたい方は是非
ちなみにカーネルスレッドをユーザランド側から殺そうとしても死なない。カーネルスレッドをカーネル側からのアクションが必要。