Grasp the design idea of Linux kernel (iii): Soft interrupt of the lower half mechanism

Source: Internet
Author: User
Tags exit in

Copyright Notice: respect for the original. Reprint please retain the Source: Blog.csdn.net/shallnet, the article is only for learning exchange, do not use for commercial use "
The interrupt handler executes asynchronously, which interrupts other important code, and the other interrupts at the interrupt peer are masked when it is executed, and all other interrupts on the current processor are likely to be masked out, and interrupt handlers cannot be blocked, so the interrupt processing needs to be ended as soon as possible. Because of these flaws in the interrupt handler, theinterrupt handlers are only part of the entire hardware interrupt processing process, for tasks that do not require a high time. Left to the other part of the interrupt processing process, which is the lower half of the interrupt processing process that this sectionto is talking about. which work is completed by the interrupt handler. What work is left to the bottom half to run? In fact, the work of the upper and lower halves does not have a strict limit, depending on the driver developer's own inference, and it is generally better to minimize the interrupt handler run time. Interrupt handlers almost always need to confirm the arrival of interrupts through the operating hardware, sometimes doing time-sensitive work (such as copying data), and the rest of the work is largely left to the bottom half to handle,The lower half is the work that runs closely with interrupt processing but the interrupt handler itself does not run.

These tasks, which are generally sensitive to time, are hardware-related, and are guaranteed not to be interrupted by other interrupts (especially the same interrupts) and are run in the interrupt handler. Other tasks are considered to be run on the lower half.

when does the lower half run ? The lower half does not need to specify the time to run, just postpone the task a little bit, so that they will be able to run when the system is not too busy and the recovery is interrupted, and all interrupts can be matched during the run. The top half can only be implemented by an interrupt handler, while the lower half can be implemented in a variety of mechanisms, in the 2.6.32 version number. There are three different forms of the lower half of the implementation mechanism: Soft interrupt, Tasklet, and task queue. Take a look at the implementation of these three lower halves.
Soft InterruptIn the Start_kernerl () function, the system initializes the soft interrupt.


asmlinkage void __init Start_kernel (void) {    char * command_line;    extern struct Kernel_param __start___param[], __stop___param[];    SMP_SETUP_PROCESSOR_ID ();    Softirq_init ();//Initialize soft interrupt    ... /* Do the rest non-__init ' Ed, we ' re now alive *    /Rest_init ();}

two frequently used types of soft interrupts are registered in Softirq_init (), with detailed code such as the following (located in kernel/softirq.c):
void __init softirq_init (void) {    int cpu;    FOR_EACH_POSSIBLE_CPU (CPU) {        int i;        PER_CPU (Tasklet_vec, CPU). Tail =            &per_cpu (Tasklet_vec, CPU). Head;        PER_CPU (Tasklet_hi_vec, CPU). Tail =            &per_cpu (Tasklet_hi_vec, CPU). Head;        for (i = 0; i < Nr_softirqs; i++)            Init_list_head (&per_cpu (softirq_work_list[i], CPU));    }    Register_hotcpu_notifier (&remote_softirq_cpu_notifier);    Register here for two soft interrupt    Open_softirq (TASKLET_SOFTIRQ, tasklet_action);     OPEN_SOFTIRQ (HI_SOFTIRQ, tasklet_hi_action);}

Register Function Open_softirq () The meaning of the parameters:
NR: Soft Interrupt type action: Soft Interrupt handling function
void Open_softirq (int nr, void (*action) (struct softirq_action *)) {    softirq_vec[nr].action = action;}
the softirq_action structure represents a soft interrupt, defined in <include/linux/interrupt.h>
struct softirq_action{    void    (*action) (struct softirq_action *);}
32 Arrays of this struct are defined in file <kernel/softirq.c>:
static struct softirq_action Softirq_vec[nr_softirqs] __cacheline_aligned_in_smp;
A soft interrupt for each register takes up one position in the array. Therefore, the system has a maximum of 32 soft interrupts.

From the code above, we can see: Open_softirq (). In fact, it is the Nr term assignment to the Softirq_vec array. Softirq_vec is an array of 32 elements, and the Linux kernel actually uses only a few:

/* Please, avoid to allocate new SOFTIRQS, if you need not _really_ high   frequency threaded job scheduling. For almost all the purposes   tasklets is more than enough. F.E. All serial device BHs et   al. should is converted to tasklets, not to Softirqs. */enum{    hi_softirq=0,    time R_SOFTIRQ,    Net_tx_softirq,    Net_rx_softirq,    Block_softirq,    Block_iopoll_softirq,    tasklet_ SOFTIRQ,    Sched_softirq,    Hrtimer_softirq,    RCU_SOFTIRQ,/    * Preferable RCU should always being the last SOFTIRQ */    Nr_softirqs};
So when does the soft interrupt handler function run when the software interrupt registration is complete? Typically, a soft interrupt marks the interrupt handler before it returns, making it run at a later time. in the following places. The soft interrupts to be processed are checked and run:
1. After processing a hardware interrupt;
2. In the KSOFTIRQD kernel thread;
3. In the code that shows the check and run of the soft interrupt to be processed, such as in the network subsystem.

About the network subsystem content can be included article: http://blog.csdn.net/shallnet/article/details/26269781


anyway. Soft interrupts run in DO_SOFTIRQ () (in <kernel/softirq.c> ), assuming a soft interrupt to be processed, DO_SOFTIRQ loops through each and calls their soft interrupt handlers.
asmlinkage void Do_softirq (void) {     __u32 pending;     unsigned long flags;     If you exit in a hardware interrupt environment, soft interrupts cannot be used in a hardware interrupt context or in a soft-interrupt environment, using in_interrupt () to prevent soft-break nesting. And seize the hard interrupt environment.

if (In_interrupt ()) return; Prohibit local interrupt local_irq_save (flags); Pending = Local_softirq_pending (); If a soft interrupt is to be processed, enter __DO_SOFTIRQ () if (pending) __do_softirq (); Local_irq_restore (flags);


See below__do_softirq ()implementation of:
asmlinkage void __do_softirq (void) {struct softirq_action *h;       __U32 pending;    int max_restart = Max_softirq_restart;    int CPU;    Pending = Local_softirq_pending ();    The pending is used to retain the pending soft interrupt 32-bit bitmap account_system_vtime (current);    __local_bh_disable ((unsigned long) __builtin_return_address (0));    Lockdep_softirq_enter ();    CPU = smp_processor_id (); restart:/* Reset the pending bitmask before enabling IRQs */set_softirq_pending (0);    Local_irq_enable ();    h = Softirq_vec;            Do {if (pending & 1) {//assuming pending nth bit is set to 1, then the soft interrupt int prev_count = Preempt_count () of the corresponding type of nth bit is processed;            KSTAT_INCR_SOFTIRQS_THIS_CPU (H-softirq_vec);            Trace_softirq_entry (H, Softirq_vec);    H->action (h);            Run the soft interrupt handler function Trace_softirq_exit (h, Softirq_vec);                       if (unlikely (prev_count! = Preempt_count ())) {PRINTK (kern_err "Huh, entered Softirq%td%s%p"              "With Preempt_count%08x,"         "Exited with%08x?\n", H-softirq_vec, Softirq_to_name[h-softirq_vec],                H->action, Prev_count, Preempt_count ());            Preempt_count () = Prev_count;        } rcu_bh_qs (CPU);        } h++;    Pending >>= 1;    Pending one bit to the right, looping through each of its bits} while (pending);    The loop runs up to 32 times until pending becomes 0,pending up to 32 bits.    Local_irq_disable ();    Pending = Local_softirq_pending ();    if (pending &&--max_restart) goto restart;    if (pending) Wakeup_softirqd ();    Lockdep_softirq_exit ();    Account_system_vtime (current); _local_bh_enable ();}
The use of soft interrupts must be in the compilation of static register, generally just like the network, such as high performance requirements to use soft interrupts, the article before we also see that the system of the soft interrupt register is just a few. Most of the time, using the second mechanism of the lower half tasklet a lot of other things. Tasklet is able to dynamically register. Can be seen as a product of finding a balance between performance and ease of use. In fact. Most drivers use Tasklet to implement theirthe lower half of the section.



Grasp the design idea of Linux kernel (iii): Soft interrupt of the lower half mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.