This article from: http://blog.chinaunix.net/uid-24203478-id-3111803.html
An important concept that is closely related to Linux interrupt is that Linux interrupt is divided into two parts: top half (tophalf) and bottom half (bottom half ). The upper half function is "registration interruption". When an interruption occurs, it reads and writes the relevant hardware and then mounts the lower half of the Interrupt Routine to the execution queue of the device. Therefore, the execution speed in the upper half is very fast, and more interrupt requests can be served. However, only "registration interruption" is far from enough, because the interruption event may be complicated. Therefore, Linux introduces a lower half to accomplish the vast majority of the mission of Interrupt events. The biggest difference between the lower half and the upper half is that the lower half can be interrupted, while the upper half cannot be interrupted. The lower half has almost done all the things of the interrupt handler and can be interrupted by new interruptions! In the lower half, it is not very urgent and usually time-consuming. Therefore, the system schedules the running time on its own and does not execute it in the context of the interrupted service.
In Linux, the lower half of the implementation mechanism mainly includes tasklet and work queue.
Tasklet is based on Linux softirq. It is quite simple to use. We only need to define tasklet and its processing functions and associate them:
Void my_tasklet_func (unsigned long); // defines a processing function:
Declare_tasklet (my_tasklet, my_tasklet_func, data); // defines a tasklet structure my_tasklet, which corresponds
The my_tasklet_func (data) function is associated. |
Then, when tasklet needs to be scheduled, a simple API can be referenced to enable the system to schedule and run as appropriate:
Tasklet_schedule (& my_tasklet ); |
In addition, Linux provides other APIs for controlling tasklet scheduling and running:
Declare_tasklet_disabled (name, function, data); // similar to declare_tasklet, but wait for the tasklet to be enabled
Tasklet_enable (struct tasklet_struct *); // enable tasklet
Tasklet_disble (struct tasklet_struct *); // disable tasklet
Tasklet_init (struct tasklet_struct *, void (* func) (unsigned long), unsigned long); // similar
Declare_tasklet ()
Tasklet_kill (struct tasklet_struct *); // clear the scheduling bit of the specified tasklet, that is, the tasklet cannot be scheduled. |
Let's first look at a tasklet running instance. This instance has no practical significance, just for demonstration. Its function is to schedule a tasklet once globalvar is written, and the function outputs "tasklet is executing ":
# Include
...
// Define and bind the tasklet Function
Void test_tasklet_action (unsigned long T );
Declare_tasklet (test_tasklet, test_tasklet_action, 0 );
Void test_tasklet_action (unsigned long T)
{
Printk ("tasklet is executing \ n ");
}
...
Ssize_t globalvar_write (struct file * filp, const char * Buf, size_t Len, loff_t * Off)
{
...
If (copy_from_user (& global_var, Buf, sizeof (INT )))
{
Return-efault;
}
// Schedule tasklet execution
Tasklet_schedule (& test_tasklet );
Return sizeof (INT );
} |
The task in the lower half is to execute the work closely related to the interrupt processing, but the interrupt processing program itself is not executed. There are three different forms of lower half implementation mechanisms in the kernel of linux2.6: Soft Interrupt, tasklet and work queue.
The following compares the differences and links between the three mechanisms.
Soft Interrupt: 1. Soft Interrupt is statically allocated during compilation.
2. A maximum of 32 soft interruptions are allowed.
3. Soft Interrupt does not preempt another Soft Interrupt. The only thing that can preempt Soft Interrupt is the interrupt processing program.
4. It can run concurrently on multiple CPUs (even for the same type ). Therefore, the Soft Interrupt must be designed as a reentrant function (multiple CPUs can be operated simultaneously ),
Therefore, we also need to use spin locks to protect its data structure.
5. Currently, only two sub-systems use soft breaks: Network and SCSI.
6. execution time: When the hardware interrupt code is returned, In the ksoftirqd kernel thread and some code that displays the check and executes the Soft Interrupt.
Tasklet: 1. tasklet is implemented using two types of soft interruptions: hi_softirq and tasklet_softirq.
2. You can increase and decrease dynamically without limit on quantity.
3. The same tasklet class cannot be executed concurrently.
4. Different types can be executed concurrently.
5. Use tasklet in most cases.
Working queue: 1. It is executed by the kernel thread. In other words, it is always executed in the process context.
2. Sleep and congestion.