I was reading the book Linux Kernel Development on Chapter Process Scheduling. On Page 61, section Waking Up, the first paragraph reads:
Waking is handled via wake_up(), which wakes up all the tasks waiting on the given wait queue. It (Q1:what does this
itrefer to?) calls try_to_wake_up(), which sets the task’s(Q2:which task? all awoken tasks?) state to TASK_RUNNING, calls enqueue_task() to add the task to the red-black tree, and sets need_resched if the awakened task’s priority is higher than the priority of the current task.The code that causes the event to occur typically calls wake_up() itself. For example, when data arrives from the hard disk, the VFS calls wake_up() on the wait queue that holds the processes waiting for the data.
I am quite confused about the above. Let me just use the example in the above paragraph, i.e., the disk interrupted after reading data, but with a more complete picture. Please correct me if any of the following is wrong or incomplete:
Some user process issued a blocking read operation, triggering a sys call and the process is in the realm of kernel.
Kernel sets up the disk controller requesting the needed data and puts this process on sleep (this process is put into a wait queue). Kernel schedules another process to run.
Disk interrupt occurs. CPU suspends the current executing process and jumps to the disk interrupt handling.
Disk controller will kick in sometime during the interrupt handling to transfer the data read from disk to main memory (either under the direction of CPU or by DMA)
(Not sure, please correct) As the paragraph says, VFS calls wake_up() on the wait queue that holds the processes waiting for the data.
My specific questions are the following:
Q1 (refer to the quoted paragraph): I assume the It in the second sentence refers to the function
wake_up(). Why does the function
wake_up wakes up all tasks instead of just the one waiting for this disk data?
Q2 (refer to the quoted paragraph): Does
try_to_wake_up() somehow knows the specific task whose state needs to be set to TASK_RUNNING? Or
try_to_wake_up() sets all awoken tasks' state to TASK_RUNNING?
Q3: How many wait queues are there for the kernel to manage? If there are more than 2 such wait queues, how does the kernel know which queue to select, such that the process waiting for the disk data is on that wait queue?
Q4: Now say we know the queue where the waiting process is on. How does the kernel know which process is waiting for the data from the disk. I can only image that some info specific to the process requesting the disk data is passed to the disk controller, like the process's PID, memory address or something. Then upon completing the interrupt handling, the disk controller(or kernel?) uses this info to pinpoint the process on the wait queue.
Please help me complete this picture of process wake_up! Thanks!