When writing device drivers, the tasklet mechanism is a relatively common mechanism that is typically used to reduce the time to interrupt processing and to convert tasks that should have been done in an interrupt service program into a soft interrupt completion.
In order to minimize interrupt loss due to excessive processing time, sometimes we need to put some tasks that are not very urgent in the interrupt processing to be executed later, and let the interrupt handler return as soon as possible. In older versions of Linux, interrupt processing is typically divided into top half handler, bottom half handler. Using the top half handler to handle the tasks that interrupts must handle, and bottom half handler processing is not an urgent task.
However, after linux2.6 Linux has taken another mechanism, is soft interrupt to replace the bottom half handler processing. And the tasklet mechanism is to use soft interrupt to complete the processing of driving bottom half. Soft interrupts in Linux2.6 are usually fixed in several ways: HI_SOFTIRQ (high-priority tasklet, a special Tasklet), TIMER_SOFTIRQ (Timers), NET_TX_SOFTIRQ (Network port forwarding), net_rx_sof TIRQ (Network port reception), BLOCK_SOFTIRQ (block device), TASKLET_SOFTIRQ (General Tasklet). Of course, you can also add their own soft interrupts by directly modifying the kernel, but generally this is unreasonable, the priority of soft interrupts is relatively high, if not in the kernel processing frequent tasks are not recommended to use. It is usually enough to drive the user to use Tasklet.
The relationship between soft interrupts and Tasklet is as follows:
As you can see, KSOFTIRQD is a kernel thread running in the background, it will cycle through the list of soft interrupt vectors, if the soft interrupt vector is found to be suspended (pend), the corresponding processing function is executed, for Tasklet, this handler function is Tasklet_action, This handler is hooked up when the soft interrupt is initialized at system startup.
The Tasklet_action function iterates through a global list of Tasklet_vec (this list has one for each CPU of the SMP system), and the elements in this list are tasklet_struct. This structure is as follows:
struct TASKLET_STRUCT
{
struct Tasklet_struct *next;
unsigned long state;
atomic_t count;
void (*func) (unsigned long);
unsigned long data;
};
Each structure is a function pointer that points to your own defined function. When we want to use Tasklet, we first define a TASKLET_STRUCT structure and initialize it to execute the function pointer, then attach it to the Task_vec linked list, and a soft interrupt can wait to be executed.
This is probably the case, and for Linux-powered authors there's really no need to care about that, the key is how we use the Tasklet mechanism.
The following interfaces are available in Linux:
Declare_tasklet (name,function,data): This interface Initializes a tasklet, where name is the name of the Tasklet and function is the functions that perform tasklet; data is unsigned lon The function parameter of type G.
static inline void Tasklet_schedule (struct tasklet_struct *t): This interface connects the defined Tasklet to the Tasklet_vec linked list of the CPU, specifically which CPU TASKL The Et_vec list is determined based on which CPU the current thread is running on. This function not only hooks up the tasklet, but also a soft tasklet soft interrupt that suspends the tasklet corresponding interrupt vector (pend).
After two work is done, basically can, the tasklet mechanism is not complex, it is easy to make the program as soon as possible to interrupt the response to avoid loss of interruption.
Linux device driver authoring _tasklet Mechanism (RPM)