First : Credit goes
https://stackoverflow.com/questions/15983872/difference-between-user-level-and-kernel-supported-threads
User threads and Kernel threads are exactly the same. (You can see by looking in /proc/ and see that the kernel threads are there too.)
A User thread is one that executes user-space code. But it can call into kernel space at any time. It's still considered a "User" thread, even though it's executing kernel code at elevated security levels.
A Kernel thread is one that only runs kernel code and isn't associated with a user-space process. These are like "UNIX daemons", except they are kernel-only daemons. So you could say that the kernel is a multi-threaded program. For example, there is a kernel thread for swap. This forces all swap issues to get "serialized" into a single stream.
If a user thread needs something, it will call into the kernel, which marks that thread as sleeping. Later, the swap thread finds the data, so it marks the user thread as runnable. Later still, the "user thread" returns from the kernel back to userland as if nothing happened.
In fact, all threads start off in kernel space, because the clone() operation happens in kernel space. (And there's lots of kernel accounting to do before you can 'return' to a new process in user space.)
Q1: “It” is wake_up
. It wakes up all tasks that are waiting for the disk data. If they weren't waiting for that data, they wouldn't be waiting on that queue.
Q2: I'm not sure I understand the question. Each wake queue entry contains a pointer to the task. try_to_wake_up
receives a pointer to the task that it's supposed to wake up. It is called once per function.
Q3: There are lots of wait queues. There's one for every event that can happen. The disk driver sets up a wait queue for each request to the disk. For example, when the filesystem driver wants the content of a certain disk block, it asks the disk driver for that block, and then the request starts with the task that made the filesystem request. Other entries may be added to the wait queue if another request for the same block comes in while this one is still outstanding.
When an interrupt happens, the disk driver determines which disk has data available from the information passed by the hardware and looks up the data structure that contains the kernel data for this disk to find which request was to be filled. In this data structure, among others, are the location where the data is to be written and the corresponding wake queue indicating what to do next.
Q4: The process makes a system call, let's say to read a file. This triggers some code in the filesystem driver which determines that the data needs to be loaded from the disk. That code makes a request to the disk driver and adds the calling process to the request's wait queue. (There are actually more layers than that, but you get the idea.) When the disk read completes, the wait queue event triggers, and the process is thus removed from the disk's wait queue. The code triggered by the wait queue event is a function supplied by the filesystem driver, which copies the data to the process's memory and causes the read
system call to return.
Best Answer
If you're not doing synchronous IOs, the user doing the write will just create transactions for the kjournald thread to dequeue (note here: I'm using an ext3 file system with journal=ordered, traces given using Linux 3.0-rc7)
We can have a look at what is happening by putting a breakpoint on the IO scheduler elevator_dispatch_fn method, for example deadline_dispatch_requests for the deadline IO scheduler:
There are two ways the device queue will run:
either called from the kjournald thread that will run (ext3 file system, mounted with the default commit=5, and is therefore scheduled to run every 5s)
Either called from an interrupt:
Now if you are doing synchronous calls, the request_fn method will run directly within the write system call, as seen below: