Linux Interrupt Complete Analysis

Source: Internet
Author: User

Learning this article can be a comprehensive and profound understanding of Linux outages. This article makes a complete analysis of the requirements, management mechanisms, interrupt implementations, interrupt interfaces (top and bottom halves) of the Linux outage, and drive usage.

I. Interruption of demand

Software is demand-driven and software is designed to address needs and problems. Know the requirements first, that understanding the code is to verify the known problems, do not know the requirements, the understanding of the code is to figure out the purpose of the designer. Compared with the two, the former natural efficiency and high.

Interrupts are intended to address asynchronous requirements. Urgent things or higher priority things need to be done first, which represents Asynchrony. For example, a phone needs to respond to a user key or touch the event at all times, or the user experience becomes worse. The signal is the asynchronous mechanism on the software, and the interrupt is the asynchronous mechanism on the hardware. For the design principle of the Interrupt controller (SOC), refer to the article "software and hardware are highly abstract---the Theory of Interrupt control (ARM system programming)."

Second, Linux outage requirements

These interrupt requirements apply to all real-time devices, whether it's an advanced processor (such as an arm system phone) or a low-end controller (such as a 51 system). But for different systems and different multitasking environments, the need for disruption is further subdivided. such as different CPU system in memory performance will be different, advanced processor configured memory is larger, m-level above, and low-end processor configuration memory is relatively small, are K-level. The size of the memory also determines the amount and complexity of software code. The Linux operating system is suitable for advanced processors and large memory, capable of handling a large number of multitasking concurrent executions. In multi-process multi-threaded environments, the demand for interrupts is also complicated, so the interrupt processing of Linux is also relatively complex. We hit analyze where the requirements for Linux outages come from and how Linux is coping.

We envision the following scenario: Suppose that there was a company in the early 90 with only one telephone (the scene was out of date, and for a moment did not think of a better J), the company only general manager A and Executive B and employee C three people. It is easy to think of the importance of the three things being done by the general manager to the supervisor and then to the employees. When using the telephone to communicate with each other, the general manager should be preferred, then the supervisor, and finally the staff. OK, three people are in the normal job, the need for telephone communication represents an asynchronous emergency. We analyze the problems we encounter and consider how to deal with them:

1. First, Supervisor B has an urgent need to interrupt the work at hand to call, while General Manager A in the B phone call during the emergency. If the Supervisor B has been holding the phone to boil porridge, the general manager must be very uncomfortable, because the general manager's things urgent and more important. So the reasonable way is, the general manager has the right to seize the phone to deal with urgent matters first. This is where the software is allowed to interrupt nesting, allowing higher-priority interrupts to get a timely response .

2. Supervisor B on the phone, if the employee C has an urgent matter also to call, he naturally can't rob to fight. This raises the question of how reasonable it would be if B had been on the phone for a long time. The Supervisor B and the customer must first put the urgent matter (set as B1) finished, and then in order to maintain customer relations, with the customer blowing water or something (set as B2). Employee c It should be more important than B2 to call and handle urgent matters. Suppose C and the other party communicate the emergency (set to C1), also with the customer blowing water (set to C2). From a fair point of view, C1 is more important than B2. How do we deal with this situation? Linux interrupts use the upper and lower halves of the mechanism. Each interrupt service is divided into two phases, the upper half dealing with hardware-related and very urgent operations (such as reading hardware data), while the lower half handles less urgent operations (putting hardware data into a queue, etc.), and specifies that the upper half of a low-priority interrupt can preempt the lower half of the high-priority interrupt. The emergency treatment of Supervisor B is divided into two parts of B1 and B2, and the emergency treatment of employee C is divided into C1 and C2 two parts. C1 can be preempted by B2. interrupts the upper and lower halves of the mechanism to allow low-priority interrupts to be executed as well.

3. If c in a period of time need to communicate with a lot of customers, and then with each customer to blow the water, that is, C to launch a lot of C1 and C2, that the director B want to say a thing with C can not find the opportunity ah, if it is the morning of Monday, C so do, then this meeting must not be opened. Regular process is the normal work flow (non-emergency, if the emergency is B to call), that B should wait for C and the customer to communicate the urgent thing is C1, also can tolerate C with one or two customers blowing water is C2, but can not always wait C with each customer is blowing water, c why all have to rest for a meeting with the supervisor, and so the Supervisor B set up a good task to continue to blow water is not too late. How does Linux interrupt handle this situation? Linux interrupts continue to process part of the lower half after the top half of all interrupts have been processed, but the maximum number of n lower halves is processed at a time. If there is still the lower half of the processing left, then give a background control thread called KSOFTIRQD, then exit the interrupt and schedule the task so that the high-priority process can get the chance to execute. The KSOFTIRQD can also be executed by the normal dispatch, and the rest of the lower half is completed. KSOFTIRQD is a kernel thread with a higher priority, which can be executed more quickly, so the entire interrupted service can be completed more quickly. Of course, if the KSOFTIRQD can have the opportunity to execute, but also on behalf of the interruption is very frequent, you can consider the system-level optimization.

There are two implementation mechanisms for the lower half of Linux, one is Tasklet, which is executed by the above KSOFTIRQD, and the other is the work queue workqueue, which is executed by the kernel thread eventx. The difference between the two is that the tasklet corresponding to the lower half can not sleep, and the workqueue corresponding to the lower half can not sleep.

In addition, Linux starting from 2.6 is also supported in the disconnection process, in fact, it is also an implementation of the lower half of the interrupt, that is, the creation of a thread to execute the lower half, and interrupt threads are priority, so the higher priority of the task process will be able to get the opportunity to execute.

This article only describes the lower half of the tasklet mechanism. Workqueue and middle thread breakage are not discussed.

4. Summary:

1) Execution order: High priority interrupt top half, lower priority top half (low priority interrupt), high priority process--low priority process. Where the lower half is excessive, it is transferred to the KSOFTIRQD kernel thread execution.

2) The interrupt nesting is to let the high priority interrupt get the timely response; the interrupt upper and lower half mechanism is for the low priority interrupt to get a timely response; Ksoftirqd kernel thread scheduling is the opportunity for high-priority task processes to be executed.

Third, interrupt management mechanism

The following analysis is based on the Linux2.6 core and arm (S5PV210) system, in which the hardware programming of the arm (S5PV210) system interrupts is referenced in the article "software and hardware are highly abstract---of life" interrupt control (ARM system programming). This article focuses on the management of Linux interrupts.

However, we note that the SOC interrupt controller based on the arm system will generally have several two-level interrupt source merging (or circuit) for a one-stage disconnection, and then all the first level of disconnection (or circuit) after the connection to the CPU IRQ signal line. S5PV210 four sets of registers that correspond to VIC0, VIC1, VIC2, and VIC3 to manage a primary interrupt source, for example, the UART0 interrupt corresponds to the 10th bit of the VIC1 Register group, but the UART0 has a receive interrupt and a send interrupt, which belongs to the two level interrupt source.

1. Data structure

--include/linux/irq.h

struct IRQ_DESC is the core data structure of interrupt management, which connects the hardware interrupt controller and the service function corresponding to the interrupt.

struct IRQ_DESC {

The interrupt number refers to a first-level interrupt number, such as UART0, which is 32+10=42.

unsigned int IRQ;

Corresponding interrupt controller operation, such as mask,enable operation, etc.

struct Irq_chip *chip;

Primary public interrupt service functions, such as receive and send interrupts, have common pending operations.

irq_flow_handler_t Handle_irq;

Specific level two Interrupt service function linked list

Structirqaction *action;

...

}

--kernel/irq/handle.c

Defines a IRQ_DESC global array, which is 128 elements.

Structirq_desc Irq_desc[nr_irqs];

--include/linux/irq.h

The structirq_chip represents the hardware control of the interrupt controller. Why do you want to connect the control of the hardware as a function pointer and then to the IRQ_DESC instead of directly in the interrupt service? This is because the outage service is a driving category, if the driver directly to the hardware register programming, it will lead to the portability of the drive is poor, should be the platform hardware-related operations to separate, when the Linux boot is initialized, and registered to the system, the driver needs to be controlled by acquiring to Irq_ The chip data structure, and call inside the function to achieve control. This tells the driver to migrate to different platforms, only need to modify the BSP board-level initialization process, without the need to modify the driver. This is the same as using a gpio attached to a peripheral device as a resource and attaching it to a device's data structure, while driving through a resource interface to obtain a gpio. Linux is a highly portable system as much as possible, and is definitely an example of object-oriented design programming.

structirq_chip {

const char *name;

void (*enable) (Unsignedint IRQ);

void (*disable) (Unsignedint IRQ);

void (*mask) (Unsignedint IRQ);

void (*unmask) (Unsignedint IRQ);

Int (*set_wake) (unsigned int IRQ, unsignedint on);

....

}

--include/linux/irq.h

typedef void (*irq_flow_handler_t) (unsigned int IRQ, Structirq_desc *desc);

irq_flow_handler_t HANDLE_IRQ interrupts public service operations on behalf of the first level.

--include/linux/interrupt.h

structirqaction {

typedef irqreturn_t (*irq_handler_t) (int, void *); Secondary Interrupt Service interface

irq_handler_t handler;

Trigger interrupt mode, such as Edge or level trigger

unsigned long flags;

const char *name;

is usually the data structure of the interrupt device

void *dev_id;

Two-stage interrupt chain contact

struct Irqaction *next;

Interrupt number

int IRQ;

Proc Image Path

struct Proc_dir_entry *dir;

We do not discuss this and set NULL.

irq_handler_t THREAD_FN;

struct Task_struct *thread;

unsigned long thread_flags;

};

2. Initialization of the IRQ_DESC

struct Irq_descirq_desc[nr_irqs] = {

[0 ... Nr_irqs-1] = {

. Status = irq_disabled,//Initial state is disable

. Chip = &no_irq_chip,//does not correspond to actual hardware

. HANDLE_IRQ = Handle_bad_irq,

...

}

};

The second session of Linux startup calls:

Start_kernel

1) early_irq_init

---desc = irq_desc;

---count= array_size (IRQ_DESC);

---for (i = 0; i < count; i++) {

---desc[i].irq= i;//interrupt number setting

----------...

---}

Arch_early_irq_init ()

2) INIT_IRQ

-----for (IRQ = 0; IRQ < Nr_irqs; irq++)

----------Irq_desc[irq].status |= Irq_norequest | Irq_noprobe;

-----INIT_ARCH_IRQ ()

namely S5PV210_INIT_IRQ-ARCH/ARM/MACH-S5PV210/SMDK210.C

----------S5P_INIT_IRQ (Vic,array_size (VIC));

---------------Vic_init (Va_vic (IRQ), Vic_base (IRQ), VIC[IRQ], 0);

--------------------vic_disable (base);//default is not enabled to interrupt

--------------------vic_set_irq_sources

-------------------------//Initialize the irq_chip of each Irq_desc

-------------------------set_irq_chip (irq,&vic_chip);

-------------------------//Default first-level interrupts and related registers.

-------------------------Set_irq_handler (IRQ,HANDLE_LEVEL_IRQ);

3. Initialization of each IRQ_DESC corresponding hardware irq_chip

Set_irq_chip (Irq,&vic_chip), of which vic_chip in \ARCH\ARM\COMMON\VIC.C

static struct irq_chipvic_chip = {

. Name = "VIC",

. Ack =vic_ack_irq,

. Mask =vic_mask_irq,//Shielded interrupts

. unmask =VIC_UNMASK_IRQ,

. Retrigger = Vic_retrigger_irq,

. Set_wake =vic_set_wake,//Wake-up

};

The interface in the Irq_chip is based on the interrupt number parameter, so that the corresponding Vic registers can be found to achieve the shielding and other functions.

4. Summarize interrupt-related data structures prior to application interruption

Before interrupt registration, that is, after the Linux boot, each element of the Irq_desc array (that is, the first interrupt) part of the data structure and the corresponding hardware control register irq_chip have been initialized. However, the Irq_desc action, that is, the specific interrupt service is empty, and the state is disable.

5. Interrupt Request Registration Interface

int REQUEST_IRQ (unsigned int irq,irq_handler_t handler, unsigned long flags,

const char *name, void *dev);

1) IRQ is a primary interrupt number, but we should not fill in the first interrupt number according to the SOC spec, but should follow

The interrupt number set by the macro is defined in Arch\arm\plat-s5p\include\plat\irqs.h, it is expanded by a level-one macro, and the first-level interrupt number can be obtained, but the programming is clearer by the break number defined by the macro. Such as:

#defineIRQ_S5P_UART_RX0 (Irq_s5p_uart_base0 +uart_irq_rxd).

The irq_s5p_uart_rx0 represents the UART0 receive interrupt.

2) handler Interrupt handling function

3) Flags trigger mode

4) name, which appears in the/proc/interrupt/directory.

5) Dev generally fills in the data structure of the interrupt corresponding device.

6. The image after the interruption of registration


After registering, you can also see a directory with the name of the REQUEST_IRQ parameter named in the/proc/interrupts/directory, which has several properties files, the number of times the interrupt occurred, and so on.

As you can see, Irq_desc is connected to the hardware-related chip and the corresponding software handles the action. The initialization of chip is initialized at the start of the Linux process, and the action completes the fill in the Request_irq interface.

Iv. interruption of processing

Interrupts are an exception, and exceptions include missing pages, Syscall, and so on. For the general low-end MCU, the interrupt vector table is the direct entrance when the asynchronous signal occurs, and for Cortex A8 advanced CPU, the anomaly vector table is the direct entrance when the asynchronous signal occurs. In the event of an IRQ interrupt, the PC goes to the IRQ offset in the exception vector table to fetch the instruction and execute it, which is the total entry for the IRQ interrupt. The s5pv210 is based on the cortex A8 core, the interrupt controller is the SOC level control module, Samsung is the system design, and cortex A8 is provided by arm. The interrupt controller manages up to 128 primary interrupt sources, which also correspond to a single interrupt vector. The specific choice of which vector address to execute is the call that is distributed by the IRQ interrupt total ingress based on the current IRQ pending bit.

The exception vector address is made up of exception vector base addresses and offsets, such as IRQ interrupt offset 0x18. When an exception occurs, the cortex A8 pc jumps to the base address of the exception vector addresses that can be configured. It is set by the coprocessor CP15. The default base address is 0x0000 0000, while the Linux boot process is set to 0xffff 0000.

Linux interrupts the following learning please pay attention to the blogger's public number---embedded Penguin Circle, Bo Master for the listed company senior embedded architect and senior trainer, through the embedded Penguin Circle public number to share embedded and Linux-related original technical articles, please pay attention. Thank you!


1. Initialization of the exception vector table

2. Interruption of services and distribution

V. Interruption of the lower half of the Tasklet

The interrupt processing described above refers to the upper half of the interrupt, and the lower half is created and dispatched from the top half.

1. Interface

2. Interrupt Scheduling

3. KSOFTIRQ execution

Six, the typical Linux interrupt programming design

Vii. Summary

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Linux Interrupt Complete Analysis

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.