Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


If theTASKLET_STATE_SCHEDbit is set, registration is terminated because the tasklet is already regis-
tered. Otherwise, the tasklet is placed at the start of a list whose list header is the CPU-specific variable
tasklet_vec. This list contains all registered tasklets and uses thenextelement for linking purposes.

The tasklet list is marked for processing once a tasklet has been registered.

14.3.3 Executing Tasklets


The most important part in the life of a tasklet is its execution. Because tasklets are implemented on top
of softIRQs, they are always executedwhen software interrupts are handled.

Tasklets are linked with theTASKLET_SOFTIRQsoftIRQ. Consequently, it is sufficient to invoke
raise_softirq(TASKLET_SOFTIRQ)to execute the tasklets of the current processor at the next
opportunity. The kernel usestasklet_actionas the action function of the softIRQ.

The function first determines the CPU-specific list in which the tasklets marked for execution are linked.
It then redirects the list header to a local element, and thus removes all entries from the public list. They
are then processed one after the other in the following loop:

kernel/softirq.c
static void tasklet_action(struct softirq_action a)
...
while (list) {
struct tasklet_struct
t = list;
list = list->next;


if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
BUG();
t->func(t->data);
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}
...
}
...
}


Executing tasklets in awhileloop is similar to the mechanism used when handling softIRQs.

Because a tasklet can be executed on only one processor at a time, but other tasklets may run in parallel,
tasklet-specific locking is required. Thestatestate is used as the locking variable. Before the handler
function of a tasklet is executed, the kernel usestasklet_trylockto check whether the state of the
tasklet isTASKLET_STATE_RUN; in other words, whether it is already running on another processor of the
system:
<interrupt.h>
static inline int tasklet_trylock(struct tasklet_struct *t)
{
return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state);
}
Free download pdf