Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


Because wait queues can also be modified in interrupts, a spinlock namedlockmust be acquired before
the queue is manipulated (see Chapter 5).task_listis a doubly linked list used to implement what it’s
best at: queues.

The elements in the queue are instances of the following data structure:

<wait.h>
struct __wait_queue {
unsigned int flags;
void *private;
wait_queue_func_t func;
struct list_head task_list;
};

typedef struct __wait_queue wait_queue_t;

❑ flagshas the valueWQ_FLAG_EXCLUSIVEor it does not — other flags are not defined at the
moment. A setWQ_FLAG_EXCLUSIVEflag indicates that the waiting process would like to be
woken up exclusively (this is discussed in more detail shortly).
❑ privateis a pointer to the task structure of the waiting process. The variable can basically point
to some arbitrary private data, but this is only seldom used in the kernel, so I will not discuss
these cases any further.
❑ funcis invoked to wake the element.
❑ task_listis used as a list element to positionwait_queue_tinstances in a wait queue.

Wait queue use is divided into two parts:


  1. To put the current process to sleep in a wait queue, it is necessary to invoke thewait_event
    function (or one of its equivalents, discussed below). The process goes to sleep and relin-
    quishes control to the scheduler.
    The kernel invokes this function typically after it has issued a request to a block device to
    transfer data. Because transfer does not take place immediately and there is nothing else to
    do in the meantime, the process can sleep and therefore make CPU time available to other
    processes in the system.

  2. At another point in the kernel — in our example, after data have arrived from the block
    device — thewake_upfunction (or one of its equivalents, discussed below) must be invoked
    to wake the sleeping processes in the wait queue.


When processes are put to sleep usingwait_event, you must always ensure that
there is a correspondingwake_upcall at another point in the kernel.

Putting Processesto Sleep


Theadd_wait_queuefunction is used to add a task to a wait queue; this function delegates its work to
__add_wait_queueonce the necessary spinlock has been acquired:

<wait.h>
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
Free download pdf