I am kind of a newbie when it comes to the Linux Kernel, but I was reading this article about fibrils where it mentions that they are (or were? not sure if they were ultimately kept in the Kernel) kernel space threads.

The article goes on saying:

A fibril is an execution thread which only runs in kernel space. ... Fibrils have their own stack, but otherwise they share all of the resources of their parent process. They are kept in a linked list attached to the task structure.

Having its own stack but sharing the rest of the memory with the parent process looks like the very definition of thread.

But what I'm wondering here is: can a process or thread in the kernel be a child of a userspace process? Or am I not understanding what the article meant and there's like one big parent process for all fibrils? I would not think so due to this:

A process can have any number of fibrils active, but only one of them can actually execute in the processor(s) at any given time

and in general the fact that a fibril should carry on a task from a calling userspace process.

  • 3
    The article is from 2007. The current recent hot stuff for AIO is io_uring. See this article instead (which references yours as a mere proposal, among a few other attempts): lwn.net/Articles/810414
    – A.B
    Aug 15 '20 at 16:06
  • It does sound like that was the proposal, but as @A.B mentioned, it was only a proposal. Had it been implemented, it would have been a new abstraction. Aug 15 '20 at 16:18

Kernel threads are threads running permanently in kernel mode.

issue a ps -efl command. You'll recognize these kernel threads to the fact their names stand between square brackets. And, paying attention to the parent process ID, you'll notice that most of them are sons of PID 2 ([kthreadd]) others being sons of PID 1 (init[3])

So, basically, the answer to your question is : no!

This however does not prevent whatever thread to issue system calls that will make them switch temporarily into kernel mode for the time of the execution of the call. But that does not make them kernel threads it's simply threads running, for some time, in kernel mode.

Therefore, while you won't find user processes parents of kernel threads, you can have user processes parents of threads, sometimes executing, in kernel mode.

EDIT : Following interesting comment from @Stephen Kitt:

while it is true that init will commute to userland, it is essentialy, from the very beginning (kernel inits) nothing but an authentic kernel thread. (v.g. not a "regular process") Kernel thread that must be created first (in order to get PID=1) but would create the kthreads if it happened to be scheduled prior to kthreadd.

We just need to have a look into the code (init/main.c)

static noinline void __ref rest_init(void){
pid = kernel_thread(kernel_init, NULL, CLONE_FS);
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
  • init is a regular process, spending most of its time in user-space... Aug 15 '20 at 16:30
  • Then was the fibril proposal sugesting to do some sort of approach that was not present in the kernel before? Or did I misunderstand what it was proposing?
    – memememe
    Aug 16 '20 at 3:33
  • @StephenKitt : "A regular process" ? Hmm not really. I edited my answer.
    – MC68020
    Aug 16 '20 at 18:33

Kernel threads can only be started by other kernel threads (or the kernel itself, before there are any kernel threads). Quoting Al Viro’s email describing the design:

Except for the initial process (init_task, eventual idle thread on the boot CPU) all processes are created by do_fork(). There are three classes of those: kernel threads, userland processes and idle threads to be. There are few low-level operations involved:

  • a kernel thread can spawn a new kernel thread; the primitive doing that is kernel_thread().
  • a userland process can spawn a new userland process; that's done by sys_fork()/sys_vfork()/sys_clone()/sys_clone2().
  • a kernel thread can become a userland process. The primitive is kernel_execve().
  • a kernel thread can spawn a future idle thread; that's done by fork_idle(). Result is not scheduled until the secondary CPU gets initialized and its state is heavily overwritten in process.

Under no circumstances a userland process can become a kernel thread or spawn one. And kernel threads never do fork(2) et.al.

(Emphasis mine.) This is old but the rules still apply.

Kernel threads are always children of kthreadd, which has pid 2 (pid 1 being reserved for init). This is done in particular so that kernel threads have a clean environment, regardless of how they are created. It is also helpful for cgroup initialisation.

Actions initiated by user-space components can cause kernel threads to be started; for example, loading a kernel module, or mounting a file system. But the kernel threads are started by the kernel, to perform work for the kernel, not associated with any individual user-space process; they must not be related to anything other than kthreadd e.g. for signal-handling purposes.

Processes shown between square brackets aren’t necessarily kernel threads, they are processes with no command line.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.