How the Linux kernel handles interrupts

How Linux got to be Linux: Test driving 1993-2003 distros

Internet Archive Book Images. Modified by Opensource.com. CC BY-SA 4.0

Interrupts are an essential part of how modern CPUs work. For example, every time you press a key on the keyboard, the CPU is interrupted so that the PC can read user input from the keyboard. This happens so quickly that you don't notice any change or impairment in user experience.

Moreover, the keyboard is not the only component that can cause interrupts. In general, there are three types of events that can cause the CPU to interrupt: Hardware interrupts , software interrupts , and exceptions . Before getting into the different types of interrupts, I'll define some terms.

Definitions

An interrupt request ( IRQ ) is requested by the programmable interrupt controller ( PIC ) with the aim of interrupting the CPU and executing the interrupt service routine ( ISR ). The ISR is a small program that processes certain data depending on the cause of the IRQ. Normal processing is interrupted until the ISR finishes.

In the past, IRQs were handled by a separate microchip—the PIC—and I/O devices were wired directly to the PIC. The PIC managed the various hardware IRQs and could talk directly to the CPU. When an IRQ occurred, the PIC wrote the data to the CPU and raised the interrupt request ( INTR ) pin.

Nowadays, IRQs are handled by an advanced programmable interrupt controller ( APIC ), which is part of the CPU. Each core has its own APIC.

Types of interrupts

As I mentioned, interrupts can be separated into three types depending on their source:

Hardware interrupts

When a hardware device wants to tell the CPU that certain data is ready to process (e.g., a keyboard entry or when a packet arrives at the network interface), it sends an IRQ to signal the CPU that the data is available. This invokes a specific ISR that was registered by the device driver during the kernel's start.

Software interrupts

More Linux resources

  • Linux commands cheat sheet
  • Advanced Linux commands cheat sheet
  • Free online course: RHEL Technical Overview
  • Linux networking cheat sheet
  • SELinux cheat sheet
  • Linux common commands cheat sheet
  • What are Linux containers?
  • Our latest Linux articles

When you're playing a video, it is essential to synchronize the music and video playback so that the music's speed doesn't vary. This is accomplished through a software interrupt that is repetitively fired by a precise timer system (known as jiffies ). This timer enables your music player to synchronize. A software interrupt can also be invoked by a special instruction to read or write data to a hardware device.

Software interrupts are also crucial when real-time capability is required (such as in industrial applications). You can find more information about this in the Linux Foundation's article  Intro to real-time Linux for embedded developers .

Exceptions are the type of interrupt that you probably know about. When the CPU executes a command that would result in division by zero or a page fault, any additional execution is interrupted. In such a case, you will be informed about it by a pop-up window or by seeing segmentation fault (core dumped) in the console output. But not every exception is caused by a faulty instruction.

Exceptions can be further divided into Faults , Traps , and Aborts .

  • Faults:  Faults are an exception that the system can correct, e.g., when a process tries to access data from a memory page that was swapped to the hard drive. The requested address is within the process address space, and the access rights are correct. If the page is not present in RAM, an IRQ is raised and it starts the page fault exception handler to load the desired memory page into RAM. If the operation is successful, execution will continue.
  • Traps:  Traps are mainly used for debugging. If you set a breakpoint in a program, you insert a special instruction that causes it to trigger a trap. A trap can trigger a context switch that allows your debugger to read and display values of local variables. Execution can continue afterward. Traps are also the default way to execute system calls (like killing a process).
  • Aborts:  Aborts are caused by hardware failure or inconsistent values in system tables. An abort does not report the location of the instruction that causes the exception. These are the most critical interrupts. An abort invokes the system's abort exception handler , which terminates the process that caused it.

Get hands-on

IRQs are ordered by priority in a vector on the APIC (0=highest priority). The first 32 interrupts (0–31) have a fixed sequence that is specified by the CPU. You can find an overview of them on OsDev's Exceptions page. Subsequent IRQs can be assigned differently. The interrupt descriptor table ( IDT ) contains the assignment between IRQ and ISR. Linux defines an IRQ vector from 0 to 256 for the assignment.

To print a list of registered interrupts on your system, open a console and type:

You should see something like this:

Registered interrupts list

Registered interrupts in kernel version 5.6.6. (Stephan Avenwedde, CC BY-SA 4.0 )

From left to right, the columns are: IRQ vector, interrupt count per CPU ( 0 .. n ), the hardware source, the hardware source's channel information, and the name of the device that caused the IRQ.

On the bottom of the table, there are some non-numeric interrupts. They are the architecture-specific interrupts, like the local timer interrupt ( LOC ) on IRQ 236. Some of them are specified in the Linux IRQ vector layout in the Linux kernel source tree.

Architecture-specific interrupts

Architecture-specific interrupts (Stephan Avenwedde, CC BY-SA 4.0 )

To get a live view of this table, run:

Proper IRQ handling is essential for the proper interaction of hardware, drivers, and software. Luckily, the Linux kernel does a really good job, and a normal PC user will hardly notice anything about the kernel's entire interrupt handling.

This can get very complicated, and this article gives only a brief overview of the topic. Good sources of information for a deeper dive into the subject are the Linux Inside eBook (CC BY-NC-SA 4.0) and the Linux Kernel Teaching repository.

arrows cycle symbol for failing faster

The lifecycle of Linux kernel testing

The Continuous Kernel Integration (CKI) project aims to prevent bugs from entering the Linux kernel.

Linux kernel source code (C) in Visual Studio Code

Continuous integration testing for the Linux kernel

How this team works to prevent bugs from being merged into the Linux kernel.

User profile image.

Related Content

GNOME

  • Stack Overflow Public questions & answers
  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Talent Build your employer brand
  • Advertising Reach developers & technologists worldwide
  • Labs The future of collective knowledge sharing
  • About the company

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

How IRQS get assigned

I'm having some question regarding PCI and IRQS.

How IRQs get assigned to devices that is connected to PCI bus , does it get assigned by the BIOS at boot time , or the bus choose it or the bus controller choose it automaticlly by itself who is responsable for that choice of IRQS numbers ?

when a device gets connected to a PCI bus can the device fill the IRQ field in the PCI Controller configuration register?

Can the Linux kernel assign and change the IRQS of connected devices ?

What about device controller like USB controller or SATA controller how we can assign an IRQ to the controller since it have more than one device that is connected to it , and how multiple devices like that are connected to the same controller use IRQS ?

How Linux identify devices that gets connected to the machine while it's running and how they get assigned an IRQ number and who is responsable for that ?

  • linux-device-driver

user3718463's user avatar

PCI configuration space is configured by the Bios, which means that Bios is supposed to enumerate all PCI devices at boot time. When a device is enumerated, the Bios routes an IRQ line to the IOAPIC input and set BAR registers, then, the kernel can request_irq() with the appropriate irq number read from the pci configuration space.

Aymen Zayet's user avatar

  • Just to add. The IRQ number and BAR values are volatile...ie they can change with every plug time. +1 –  RootPhoenix Commented Jan 20, 2015 at 18:30

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged linux linux-device-driver pci irq or ask your own question .

  • Featured on Meta
  • Upcoming sign-up experiments related to tags

Hot Network Questions

  • Do differently rendered measure numbers convey meaning?
  • The method of substitution in the problem of finding the integral
  • Is there a category even more general than "thing"?
  • What is the meaning of "Attempt any air"?
  • I did not contest a wrong but inconsequential accusation of plagiarism – can this come back to haunt me?
  • How does MPPT maintain a constant voltage?
  • Correct my understanding of Digital Signature Algorithm for TLS certificates?
  • Is teaching how to solve recurrence relations using generating functions too much for a first year discrete maths course?
  • Definition of the subcategory in book "Category Theory for Computing Science"
  • Best course of action given problematic bottom plates in basement finishing
  • Vertical alignment of array inside array
  • How can I enable read only mode in microSD card
  • What would cause desoldering braid to simply not work?
  • A Colorful explosion
  • Can a star that initially started with less energy output than the sun (when it was young) evolve to be as luminous as the sun in the same time period
  • Numerical approximation of the integral by using data
  • Advice for job application to a university position as a non-student
  • How can UserA programmatically replace a text string within a file they own that's located in /etc?
  • Bulls and Cows meet Sudoku!
  • How to make Region from Spline curve
  • Adding shadows to spiric sections of a torus
  • Are the complex numbers a graded algebra?
  • Mechanistic view of the universe
  • Where did the pronunciation of the word "kilometer/kilometre" as "kl OM iter" rather than "KILL o meeter" originate?

linux irq assignments

Understanding the Linux Kernel, 3rd Edition by

Get full access to Understanding the Linux Kernel, 3rd Edition and 60K+ other titles, with a free 10-day trial of O'Reilly.

There are also live events, courses curated by job role, and more.

Interrupt Handling

As we explained earlier, most exceptions are handled simply by sending a Unix signal to the process that caused the exception. The action to be taken is thus deferred until the process receives the signal; as a result, the kernel is able to process the exception quickly.

This approach does not hold for interrupts, because they frequently arrive long after the process to which they are related (for instance, a process that requested a data transfer) has been suspended and a completely unrelated process is running. So it would make no sense to send a Unix signal to the current process.

Interrupt handling depends on the type of interrupt. For our purposes, we’ll distinguish three main classes of interrupts:

An I/O device requires attention; the corresponding interrupt handler must query the device to determine the proper course of action. We cover this type of interrupt in the later section " I/O Interrupt Handling .”

Some timer, either a local APIC timer or an external timer, has issued an interrupt; this kind of interrupt tells the kernel that a fixed-time interval has elapsed. These interrupts are handled mostly as I/O interrupts; we discuss the peculiar characteristics of timer interrupts in Chapter 6 .

A CPU issued an interrupt to another CPU of a multiprocessor system. We cover such interrupts in the later section " Interprocessor Interrupt Handling .”

I/O Interrupt Handling

In general, an I/O interrupt handler must be flexible enough to service several devices at the same time. In the PCI bus architecture, for instance, several devices may share the same IRQ line. This means that the interrupt vector alone does not tell the whole story. In the example shown in Table 4-3 , the same vector 43 is assigned to the USB port and to the sound card. However, some hardware devices found in older PC architectures (such as ISA) do not reliably operate if their IRQ line is shared with other devices.

Interrupt handler flexibility is achieved in two distinct ways, as discussed in the following list.

The interrupt handler executes several interrupt service routines ( ISRs ). Each ISR is a function related to a single device sharing the IRQ line. Because it is not possible to know in advance which particular device issued the IRQ, each ISR is executed to verify whether its device needs attention; if so, the ISR performs all the operations that need to be executed when the device raises an interrupt.

An IRQ line is associated with a device driver at the last possible moment; for instance, the IRQ line of the floppy device is allocated only when a user accesses the floppy disk device. In this way, the same IRQ vector may be used by several hardware devices even if they cannot share the IRQ line; of course, the hardware devices cannot be used at the same time. (See the discussion at the end of this section.)

Not all actions to be performed when an interrupt occurs have the same urgency. In fact, the interrupt handler itself is not a suitable place for all kind of actions. Long noncritical operations should be deferred, because while an interrupt handler is running, the signals on the corresponding IRQ line are temporarily ignored. Most important, the process on behalf of which an interrupt handler is executed must always stay in the TASK_RUNNING state, or a system freeze can occur. Therefore, interrupt handlers cannot perform any blocking procedure such as an I/O disk operation. Linux divides the actions to be performed following an interrupt into three classes:

Actions such as acknowledging an interrupt to the PIC, reprogramming the PIC or the device controller, or updating data structures accessed by both the device and the processor. These can be executed quickly and are critical, because they must be performed as soon as possible. Critical actions are executed within the interrupt handler immediately, with maskable interrupts disabled.

Actions such as updating data structures that are accessed only by the processor (for instance, reading the scan code after a keyboard key has been pushed). These actions can also finish quickly, so they are executed by the interrupt handler immediately, with the interrupts enabled.

Actions such as copying a buffer’s contents into the address space of a process (for instance, sending the keyboard line buffer to the terminal handler process). These may be delayed for a long time interval without affecting the kernel operations; the interested process will just keep waiting for the data. Noncritical deferrable actions are performed by means of separate functions that are discussed in the later section " Softirqs and Tasklets .”

Regardless of the kind of circuit that caused the interrupt, all I/O interrupt handlers perform the same four basic actions:

Save the IRQ value and the register’s contents on the Kernel Mode stack.

Send an acknowledgment to the PIC that is servicing the IRQ line, thus allowing it to issue further interrupts.

Execute the interrupt service routines (ISRs) associated with all the devices that share the IRQ.

Terminate by jumping to the ret_from_intr( ) address.

Several descriptors are needed to represent both the state of the IRQ lines and the functions to be executed when an interrupt occurs. Figure 4-4 represents in a schematic way the hardware circuits and the software functions used to handle an interrupt. These functions are discussed in the following sections.

Interrupt vectors

As illustrated in Table 4-2 , physical IRQs may be assigned any vector in the range 32-238. However, Linux uses vector 128 to implement system calls.

The IBM-compatible PC architecture requires that some devices be statically connected to specific IRQ lines. In particular:

The interval timer device must be connected to the IRQ 0 line (see Chapter 6 ).

The slave 8259A PIC must be connected to the IRQ 2 line (although more advanced PICs are now being used, Linux still supports 8259A-style PICs).

I/O interrupt handling

Figure 4-4. I/O interrupt handling

The external mathematical coprocessor must be connected to the IRQ 13 line (although recent 80 × 86 processors no longer use such a device, Linux continues to support the hardy 80386 model).

In general, an I/O device can be connected to a limited number of IRQ lines. (As a matter of fact, when playing with an old PC where IRQ sharing is not possible, you might not succeed in installing a new card because of IRQ conflicts with other already present hardware devices.)

Table 4-2. Interrupt vectors in Linux

0–19 -

Nonmaskable interrupts and exceptions

20–31 -

Intel-reserved

32–127 -

External interrupts (IRQs)

128

Programmed exception for system calls (see )

129–238 -

External interrupts (IRQs)

239

Local APIC timer interrupt (see )

240 ( )

Local APIC thermal interrupt (introduced in the Pentium 4 models)

241–250 -

Reserved by Linux for future use

251–253 -

Interprocessor interrupts (see the section " " later in this chapter)

254 ( )

Local APIC error interrupt (generated when the local APIC detects an erroneous condition)

255 ( )

Local APIC spurious interrupt (generated if the CPU masks an interrupt while the hardware device raises it)

There are three ways to select a line for an IRQ-configurable device:

By setting hardware jumpers (only on very old device cards).

By a utility program shipped with the device and executed when installing it. Such a program may either ask the user to select an available IRQ number or probe the system to determine an available number by itself.

By a hardware protocol executed at system startup. Peripheral devices declare which interrupt lines they are ready to use; the final values are then negotiated to reduce conflicts as much as possible. Once this is done, each interrupt handler can read the assigned IRQ by using a function that accesses some I/O ports of the device. For instance, drivers for devices that comply with the Peripheral Component Interconnect (PCI) standard use a group of functions such as pci_read_config_byte( ) to access the device configuration space.

Table 4-3 shows a fairly arbitrary arrangement of devices and IRQs, such as those that might be found on one particular PC.

Table 4-3. An example of IRQ assignment to I/O devices

0

32

Timer

1

33

Keyboard

2

34

PIC cascading

3

35

Second serial port

4

36

First serial port

6

38

Floppy disk

8

40

System clock

10

42

Network interface

11

43

USB port, sound card

12

44

PS/2 mouse

13

45

Mathematical coprocessor

14

46

EIDE disk controller’s first chain

15

47

EIDE disk controller’s second chain

The kernel must discover which I/O device corresponds to the IRQ number before enabling interrupts. Otherwise, for example, how could the kernel handle a signal from a SCSI disk without knowing which vector corresponds to the device? The correspondence is established while initializing each device driver (see Chapter 13 ).

IRQ data structures

As always, when discussing complicated operations involving state transitions, it helps to understand first where key data is stored. Thus, this section explains the data structures that support interrupt handling and how they are laid out in various descriptors. Figure 4-5 illustrates schematically the relationships between the main descriptors that represent the state of the IRQ lines. (The figure does not illustrate the data structures needed to handle softirqs and tasklets; they are discussed later in this chapter.)

IRQ descriptors

Figure 4-5. IRQ descriptors

Every interrupt vector has its own irq_desc_t descriptor, whose fields are listed in Table 4-4 . All such descriptors are grouped together in the irq_desc array.

Table 4-4. The irq_desc_t descriptor

Points to the PIC object ( descriptor) that services the IRQ line.

Pointer to data used by the PIC methods.

Identifies the interrupt service routines to be invoked when the IRQ occurs. The field points to the first element of the list of descriptors associated with the IRQ. The descriptor is described later in the chapter.

A set of flags describing the IRQ line status (see ).

Shows 0 if the IRQ line is enabled and a positive value if it has been disabled at least once.

Counter of interrupt occurrences on the IRQ line (for diagnostic use only).

Counter of unhandled interrupt occurrences on the IRQ line (for diagnostic use only).

A spin lock used to serialize the accesses to the IRQ descriptor and to the PIC (see ).

An interrupt is unexpected if it is not handled by the kernel, that is, either if there is no ISR associated with the IRQ line, or if no ISR associated with the line recognizes the interrupt as raised by its own hardware device. Usually the kernel checks the number of unexpected interrupts received on an IRQ line, so as to disable the line in case a faulty hardware device keeps raising an interrupt over and over. Because the IRQ line can be shared among several devices, the kernel does not disable the line as soon as it detects a single unhandled interrupt. Rather, the kernel stores in the irq_count and irqs_unhandled fields of the irq_desc_t descriptor the total number of interrupts and the number of unexpected interrupts, respectively; when the 100,000 th interrupt is raised, the kernel disables the line if the number of unhandled interrupts is above 99,900 (that is, if less than 101 interrupts over the last 100,000 received are expected interrupts from hardware devices sharing the line).

The status of an IRQ line is described by the flags listed in Table 4-5 .

Table 4-5. Flags describing the IRQ line status

A handler for the IRQ is being executed.

The IRQ line has been deliberately disabled by a device driver.

An IRQ has occurred on the line; its occurrence has been acknowledged to the PIC, but it has not yet been serviced by the kernel.

The IRQ line has been disabled but the previous IRQ occurrence has not yet been acknowledged to the PIC.

The kernel is using the IRQ line while performing a hardware device probe.

The kernel is using the IRQ line while performing a hardware device probe; moreover, the corresponding interrupt has not been raised.

Not used on the 80 × 86 architecture.

Not used.

Not used on the 80 × 86 architecture.

The depth field and the IRQ_DISABLED flag of the irq_desc_t descriptor specify whether the IRQ line is enabled or disabled. Every time the disable_irq( ) or disable_irq_nosync( ) function is invoked, the depth field is increased; if depth is equal to 0, the function disables the IRQ line and sets its IRQ_DISABLED flag. [ * ] Conversely, each invocation of the enable_irq( ) function decreases the field; if depth becomes 0, the function enables the IRQ line and clears its IRQ_DISABLED flag.

During system initialization, the init_IRQ( ) function sets the status field of each IRQ main descriptor to IRQ _DISABLED . Moreover, init_IRQ( ) updates the IDT by replacing the interrupt gates set up by setup_idt( ) (see the section " Preliminary Initialization of the IDT ,” earlier in this chapter) with new ones. This is accomplished through the following statements:

This code looks in the interrupt array to find the interrupt handler addresses that it uses to set up the interrupt gates . Each entry n of the interrupt array stores the address of the interrupt handler for IRQ n (see the later section " Saving the registers for the interrupt handler “). Notice that the interrupt gate corresponding to vector 128 is left untouched, because it is used for the system call’s programmed exception.

In addition to the 8259A chip that was mentioned near the beginning of this chapter, Linux supports several other PIC circuits such as the SMP IO-APIC, Intel PIIX4’s internal 8259 PIC, and SGI’s Visual Workstation Cobalt (IO-)APIC. To handle all such devices in a uniform way, Linux uses a PIC object , consisting of the PIC name and seven PIC standard methods. The advantage of this object-oriented approach is that drivers need not to be aware of the kind of PIC installed in the system. Each driver-visible interrupt source is transparently wired to the appropriate controller. The data structure that defines a PIC object is called hw_interrupt_type (also called hw_irq_controller ).

For the sake of concreteness, let’s assume that our computer is a uniprocessor with two 8259A PICs, which provide 16 standard IRQs. In this case, the handler field in each of the 16 irq_desc_t descriptors points to the i8259A_irq_type variable, which describes the 8259A PIC. This variable is initialized as follows:

The first field in this structure, "XT-PIC" , is the PIC name. Next come the pointers to six different functions used to program the PIC. The first two functions start up and shut down an IRQ line of the chip, respectively. But in the case of the 8259A chip, these functions coincide with the third and fourth functions, which enable and disable the line. The mask_and_ack_8259A( ) function acknowledges the IRQ received by sending the proper bytes to the 8259A I/O ports. The end_8259A_irq( ) function is invoked when the interrupt handler for the IRQ line terminates. The last set_affinity method is set to NULL : it is used in multiprocessor systems to declare the “affinity” of CPUs for specified IRQs — that is, which CPUs are enabled to handle specific IRQs.

As described earlier, multiple devices can share a single IRQ. Therefore, the kernel maintains irqaction descriptors (see Figure 4-5 earlier in this chapter), each of which refers to a specific hardware device and a specific interrupt. The fields included in such descriptor are shown in Table 4-6 , and the flags are shown in Table 4-7 .

Table 4-6. Fields of the irqaction descriptor

Points to the interrupt service routine for an I/O device. This is the key field that allows many devices to share the same IRQ.

This field includes a few fields that describe the relationships between the IRQ line and the I/O device (see ).

Not used.

The name of the I/O device (shown when listing the serviced IRQs by reading the file).

A private field for the I/O device. Typically, it identifies the I/O device itself (for instance, it could be equal to its major and minor numbers; see the section " " in ), or it points to the device driver’s data.

Points to the next element of a list of descriptors. The elements in the list refer to hardware devices that share the same IRQ.

irq

IRQ line.

dir

Points to the descriptor of the directory associated with the IRQ .

Table 4-7. Flags of the irqaction descriptor

The handler must execute with interrupts disabled.

The device permits its IRQ line to be shared with other devices.

The device may be considered a source of events that occurs randomly; it can thus be used by the kernel random number generator. (Users can access this feature by taking random numbers from the and device files.)

Finally, the irq_stat array includes NR_CPUS entries, one for every possible CPU in the system. Each entry of type irq_cpustat_t includes a few counters and flags used by the kernel to keep track of what each CPU is currently doing (see Table 4-8 ).

Table 4-8. Fields of the irq_cpustat_t structure

Set of flags denoting the pending softirqs (see the section " " later in this chapter)

Time when the CPU became idle (significant only if the CPU is currently idle)

Number of occurrences of NMI interrupts

Number of occurrences of local APIC timer interrupts (see )

IRQ distribution in multiprocessor systems

Linux sticks to the Symmetric Multiprocessing model (SMP ); this means, essentially, that the kernel should not have any bias toward one CPU with respect to the others. As a consequence, the kernel tries to distribute the IRQ signals coming from the hardware devices in a round-robin fashion among all the CPUs. Therefore, all the CPUs should spend approximately the same fraction of their execution time servicing I/O interrupts.

In the earlier section " The Advanced Programmable Interrupt Controller (APIC) ,” we said that the multi-APIC system has sophisticated mechanisms to dynamically distribute the IRQ signals among the CPUs.

During system bootstrap, the booting CPU executes the setup_IO_APIC_irqs( ) function to initialize the I/O APIC chip. The 24 entries of the Interrupt Redirection Table of the chip are filled, so that all IRQ signals from the I/O hardware devices can be routed to each CPU in the system according to the “lowest priority” scheme (see the earlier section " IRQs and Interrupts “). During system bootstrap, moreover, all CPUs execute the setup_local_APIC( ) function, which takes care of initializing the local APICs. In particular, the task priority register (TPR) of each chip is initialized to a fixed value, meaning that the CPU is willing to handle every kind of IRQ signal, regardless of its priority. The Linux kernel never modifies this value after its initialization.

All task priority registers contain the same value, thus all CPUs always have the same priority. To break a tie, the multi-APIC system uses the values in the arbitration priority registers of local APICs, as explained earlier. Because such values are automatically changed after every interrupt, the IRQ signals are, in most cases, fairly distributed among all CPUs. [ * ]

In short, when a hardware device raises an IRQ signal, the multi-APIC system selects one of the CPUs and delivers the signal to the corresponding local APIC, which in turn interrupts its CPU. No other CPUs are notified of the event.

All this is magically done by the hardware, so it should be of no concern for the kernel after multi-APIC system initialization. Unfortunately, in some cases the hardware fails to distribute the interrupts among the microprocessors in a fair way (for instance, some Pentium 4-based SMP motherboards have this problem). Therefore, Linux 2.6 makes use of a special kernel thread called kirqd to correct, if necessary, the automatic assignment of IRQs to CPUs.

The kernel thread exploits a nice feature of multi-APIC systems, called the IRQ affinity of a CPU: by modifying the Interrupt Redirection Table entries of the I/O APIC, it is possible to route an interrupt signal to a specific CPU. This can be done by invoking the set_ioapic_affinity_irq( ) function, which acts on two parameters: the IRQ vector to be rerouted and a 32-bit mask denoting the CPUs that can receive the IRQ. The IRQ affinity of a given interrupt also can be changed by the system administrator by writing a new CPU bitmap mask into the /proc/irq/n/smp_affinity file ( n being the interrupt vector).

The kirqd kernel thread periodically executes the do_irq_balance( ) function, which keeps track of the number of interrupt occurrences received by every CPU in the most recent time interval. If the function discovers that the IRQ load imbalance between the heaviest loaded CPU and the least loaded CPU is significantly high, then it either selects an IRQ to be “moved” from a CPU to another, or rotates all IRQs among all existing CPUs.

Multiple Kernel Mode stacks

As mentioned in the section " Identifying a Process " in Chapter 3 , the thread_info descriptor of each process is coupled with a Kernel Mode stack in a thread_union data structure composed by one or two page frames, according to an option selected when the kernel has been compiled. If the size of the thread_union structure is 8 KB, the Kernel Mode stack of the current process is used for every type of kernel control path: exceptions, interrupts, and deferrable functions (see the later section " Softirqs and Tasklets “). Conversely, if the size of the thread_union structure is 4 KB, the kernel makes use of three types of Kernel Mode stacks:

The exception stack is used when handling exceptions (including system calls). This is the stack contained in the per-process thread_union data structure, thus the kernel makes use of a different exception stack for each process in the system.

The hard IRQ stack is used when handling interrupts. There is one hard IRQ stack for each CPU in the system, and each stack is contained in a single page frame.

The soft IRQ stack is used when handling deferrable functions (softirqs or tasklets; see the later section " Softirqs and Tasklets “). There is one soft IRQ stack for each CPU in the system, and each stack is contained in a single page frame.

All hard IRQ stacks are contained in the hardirq_stack array, while all soft IRQ stacks are contained in the softirq_stack array. Each array element is a union of type irq_ctx that span a single page. At the bottom of this page is stored a thread_info structure, while the spare memory locations are used for the stack; remember that each stack grows towards lower addresses. Thus, hard IRQ stacks and soft IRQ stacks are very similar to the exception stacks described in the section " Identifying a Process " in Chapter 3 ; the only difference is that the thread_info structure coupled with each stack is associated with a CPU rather than a process.

The hardirq_ctx and softirq_ctx arrays allow the kernel to quickly determine the hard IRQ stack and soft IRQ stack of a given CPU, respectively: they contain pointers to the corresponding irq_ctx elements.

Saving the registers for the interrupt handler

When a CPU receives an interrupt, it starts executing the code at the address found in the corresponding gate of the IDT (see the earlier section " Hardware Handling of Interrupts and Exceptions “).

As with other context switches, the need to save registers leaves the kernel developer with a somewhat messy coding job, because the registers have to be saved and restored using assembly language code. However, within those operations, the processor is expected to call and return from a C function. In this section, we describe the assembly language task of handling registers; in the next, we show some of the acrobatics required in the C function that is subsequently invoked.

Saving registers is the first task of the interrupt handler. As already mentioned, the address of the interrupt handler for IRQ n is initially stored in the interrupt[n] entry and then copied into the interrupt gate included in the proper IDT entry.

The interrupt array is built through a few assembly language instructions in the arch/i386/kernel/entry.S file. The array includes NR_IRQS elements, where the NR_IRQS macro yields either the number 224 if the kernel supports a recent I/O APIC chip, [ * ] or the number 16 if the kernel uses the older 8259A PIC chips. The element at index n in the array stores the address of the following two assembly language instructions:

The result is to save on the stack the IRQ number associated with the interrupt minus 256. The kernel represents all IRQs through negative numbers, because it reserves positive interrupt numbers to identify system calls (see Chapter 10 ). The same code for all interrupt handlers can then be executed while referring to this number. The common code starts at label common_interrupt and consists of the following assembly language macros and instructions:

The SAVE_ALL macro expands to the following fragment:

SAVE_ALL saves all the CPU registers that may be used by the interrupt handler on the stack, except for eflags , cs , eip , ss , and esp , which are already saved automatically by the control unit (see the earlier section " Hardware Handling of Interrupts and Exceptions “). The macro then loads the selector of the user data segment into ds and es .

After saving the registers, the address of the current top stack location is saved in the eax register; then, the interrupt handler invokes the do_IRQ( ) function. When the ret instruction of do_IRQ( ) is executed (when that function terminates) control is transferred to ret_from_intr( ) (see the later section " Returning from Interrupts and Exceptions “).

The do_IRQ( ) function

The do_IRQ( ) function is invoked to execute all interrupt service routines associated with an interrupt. It is declared as follows:

The regparm keyword instructs the function to go to the eax register to find the value of the regs argument; as seen above, eax points to the stack location containing the last register value pushed on by SAVE_ALL .

The do_IRQ( ) function executes the following actions:

Executes the irq_enter( ) macro, which increases a counter representing the number of nested interrupt handlers. The counter is stored in the preempt_count field of the thread_info structure of the current process (see Table 4-10 later in this chapter).

If the size of the thread_union structure is 4 KB, it switches to the hard IRQ stack.In particular, the function performs the following substeps:

Executes the current_thread_info( ) function to get the address of the thread_info descriptor associated with the Kernel Mode stack addressed by the esp register (see the section " Identifying a Process " in Chapter 3 ).

Compares the address of the thread_info descriptor obtained in the previous step with the address stored in hardirq_ctx[smp_processor_id( )] , that is, the address of the thread_info descriptor associated with the local CPU. If the two addresses are equal, the kernel is already using the hard IRQ stack, thus jumps to step 3. This happens when an IRQ is raised while the kernel is still handling another interrupt.

Here the Kernel Mode stack has to be switched. Stores the pointer to the current process descriptor in the task field of the thread_info descriptor in irq_ctx union of the local CPU. This is done so that the current macro works as expected while the kernel is using the hard IRQ stack (see the section " Identifying a Process " in Chapter 3 ).

Stores the current value of the esp stack pointer register in the previous_esp field of the thread_info descriptor in the irq_ctx union of the local CPU (this field is used only when preparing the function call trace for a kernel oops).

Loads in the esp stack register the top location of the hard IRQ stack of the local CPU (the value in hardirq_ctx[smp_processor_id( )] plus 4096); the previous value of the esp register is saved in the ebx register.

Invokes the _ _do_IRQ( ) function passing to it the pointer regs and the IRQ number obtained from the regs->orig_eax field (see the following section).

If the hard IRQ stack has been effectively switched in step 2e above, the function copies the original stack pointer from the ebx register into the esp register, thus switching back to the exception stack or soft IRQ stack that were in use before.

Executes the irq_exit( ) macro, which decreases the interrupt counter and checks whether deferrable kernel functions are waiting to be executed (see the section " Softirqs and Tasklets " later in this chapter).

Terminates: the control is transferred to the ret_from_intr( ) function (see the later section " Returning from Interrupts and Exceptions “).

The _ _do_IRQ( ) function

The _ _do_IRQ( ) function receives as its parameters an IRQ number (through the eax register) and a pointer to the pt_regs structure where the User Mode register values have been saved (through the edx register).

The function is equivalent to the following code fragment:

Before accessing the main IRQ descriptor, the kernel acquires the corresponding spin lock. We’ll see in Chapter 5 that the spin lock protects against concurrent accesses by different CPUs. This spin lock is necessary in a multiprocessor system, because other interrupts of the same kind may be raised, and other CPUs might take care of the new interrupt occurrences. Without the spin lock, the main IRQ descriptor would be accessed concurrently by several CPUs. As we’ll see, this situation must be absolutely avoided.

After acquiring the spin lock, the function invokes the ack method of the main IRQ descriptor. When using the old 8259A PIC, the corresponding mask_and_ack_8259A( ) function acknowledges the interrupt on the PIC and also disables the IRQ line. Masking the IRQ line ensures that the CPU does not accept further occurrences of this type of interrupt until the handler terminates. Remember that the _ _do_IRQ( ) function runs with local interrupts disabled; in fact, the CPU control unit automatically clears the IF flag of the eflags register because the interrupt handler is invoked through an IDT’s interrupt gate. However, we’ll see shortly that the kernel might re-enable local interrupts before executing the interrupt service routines of this interrupt.

When using the I/O APIC, however, things are much more complicated. Depending on the type of interrupt, acknowledging the interrupt could either be done by the ack method or delayed until the interrupt handler terminates (that is, acknowledgement could be done by the end method). In either case, we can take for granted that the local APIC doesn’t accept further interrupts of this type until the handler terminates, although further occurrences of this type of interrupt may be accepted by other CPUs.

The _ _do_IRQ( ) function then initializes a few flags of the main IRQ descriptor. It sets the IRQ_PENDING flag because the interrupt has been acknowledged (well, sort of), but not yet really serviced; it also clears the IRQ_WAITING and IRQ_REPLAY flags (but we don’t have to care about them now).

Now _ _ do_IRQ( ) checks whether it must really handle the interrupt. There are three cases in which nothing has to be done. These are discussed in the following list.

A CPU might execute the _ _do_IRQ( ) function even if the corresponding IRQ line is disabled; you’ll find an explanation for this nonintuitive case in the later section " Reviving a lost interrupt .” Moreover, buggy motherboards may generate spurious interrupts even when the IRQ line is disabled in the PIC.

In a multiprocessor system, another CPU might be handling a previous occurrence of the same interrupt. Why not defer the handling of this occurrence to that CPU? This is exactly what is done by Linux. This leads to a simpler kernel architecture because device drivers’ interrupt service routines need not to be reentrant (their execution is serialized). Moreover, the freed CPU can quickly return to what it was doing, without dirtying its hardware cache; this is beneficial to system performance. The IRQ_INPROGRESS flag is set whenever a CPU is committed to execute the interrupt service routines of the interrupt; therefore, the _ _do_IRQ( ) function checks it before starting the real work.

This case occurs when there is no interrupt service routine associated with the interrupt. Normally, this happens only when the kernel is probing a hardware device.

Let’s suppose that none of the three cases holds, so the interrupt has to be serviced. The _ _ do_IRQ( ) function sets the IRQ_INPROGRESS flag and starts a loop. In each iteration, the function clears the IRQ_PENDING flag, releases the interrupt spin lock, and executes the interrupt service routines by invoking handle_IRQ_event( ) (described later in the chapter). When the latter function terminates, _ _do_IRQ( ) acquires the spin lock again and checks the value of the IRQ_PENDING flag. If it is clear, no further occurrence of the interrupt has been delivered to another CPU, so the loop ends. Conversely, if IRQ_PENDING is set, another CPU has executed the do_IRQ( ) function for this type of interrupt while this CPU was executing handle_IRQ_event( ) . Therefore, do_IRQ( ) performs another iteration of the loop, servicing the new occurrence of the interrupt. [ * ]

Our _ _do_IRQ( ) function is now going to terminate, either because it has already executed the interrupt service routines or because it had nothing to do. The function invokes the end method of the main IRQ descriptor. When using the old 8259A PIC, the corresponding end_8259A_irq( ) function reenables the IRQ line (unless the interrupt occurrence was spurious). When using the I/O APIC, the end method acknowledges the interrupt (if not already done by the ack method).

Finally, _ _do_IRQ( ) releases the spin lock: the hard work is finished!

Reviving a lost interrupt

The _ _do_IRQ( ) function is small and simple, yet it works properly in most cases. Indeed, the IRQ_PENDING , IRQ_INPROGRESS , and IRQ_DISABLED flags ensure that interrupts are correctly handled even when the hardware is misbehaving. However, things may not work so smoothly in a multiprocessor system.

Suppose that a CPU has an IRQ line enabled. A hardware device raises the IRQ line, and the multi-APIC system selects our CPU for handling the interrupt. Before the CPU acknowledges the interrupt, the IRQ line is masked out by another CPU; as a consequence, the IRQ_DISABLED flag is set. Right afterwards, our CPU starts handling the pending interrupt; therefore, the do_IRQ( ) function acknowledges the interrupt and then returns without executing the interrupt service routines because it finds the IRQ_DISABLED flag set. Therefore, even though the interrupt occurred before the IRQ line was disabled, it gets lost.

To cope with this scenario, the enable_irq( ) function, which is used by the kernel to enable an IRQ line, checks first whether an interrupt has been lost. If so, the function forces the hardware to generate a new occurrence of the lost interrupt:

The function detects that an interrupt was lost by checking the value of the IRQ_PENDING flag. The flag is always cleared when leaving the interrupt handler; therefore, if the IRQ line is disabled and the flag is set, then an interrupt occurrence has been acknowledged but not yet serviced. In this case the hw_resend_irq( ) function raises a new interrupt. This is obtained by forcing the local APIC to generate a self-interrupt (see the later section " Interprocessor Interrupt Handling “). The role of the IRQ_REPLAY flag is to ensure that exactly one self-interrupt is generated. Remember that the _ _ do_IRQ( ) function clears that flag when it starts handling the interrupt.

Interrupt service routines

As mentioned previously, an interrupt service routine handles an interrupt by executing an operation specific to one type of device. When an interrupt handler must execute the ISRs, it invokes the handle_IRQ_event( ) function. This function essentially performs the following steps:

Enables the local interrupts with the sti assembly language instruction if the SA_INTERRUPT flag is clear.

Executes each interrupt service routine of the interrupt through the following code:

At the start of the loop, action points to the start of a list of irqaction data structures that indicate the actions to be taken upon receiving the interrupt (see Figure 4-5 earlier in this chapter).

Disables local interrupts with the cli assembly language instruction.

Terminates by returning the value of the retval local variable, that is, 0 if no interrupt service routine has recognized interrupt, 1 otherwise (see next).

All interrupt service routines act on the same parameters (once again they are passed through the eax , edx , and ecx registers, respectively):

The IRQ number

The device identifier

A pointer to a pt_regs structure on the Kernel Mode (exception) stack containing the registers saved right after the interrupt occurred. The pt_regs structure consists of 15 fields:

The first nine fields are the register values pushed by SAVE_ALL

The tenth field, referenced through a field called orig_eax , encodes the IRQ number

The remaining fields correspond to the register values pushed on automatically by the control unit

The first parameter allows a single ISR to handle several IRQ lines, the second one allows a single ISR to take care of several devices of the same type, and the last one allows the ISR to access the execution context of the interrupted kernel control path. In practice, most ISRs do not use these parameters.

Every interrupt service routine returns the value 1 if the interrupt has been effectively handled, that is, if the signal was raised by the hardware device handled by the interrupt service routine (and not by another device sharing the same IRQ); it returns the value 0 otherwise. This return code allows the kernel to update the counter of unexpected interrupts mentioned in the section " IRQ data structures " earlier in this chapter.

The SA_INTERRUPT flag of the main IRQ descriptor determines whether interrupts must be enabled or disabled when the do_IRQ( ) function invokes an ISR. An ISR that has been invoked with the interrupts in one state is allowed to put them in the opposite state. In a uniprocessor system, this can be achieved by means of the cli (disable interrupts) and sti (enable interrupts) assembly language instructions.

The structure of an ISR depends on the characteristics of the device handled. We’ll give a couple of examples of ISRs in Chapter 6 and Chapter 13 .

Dynamic allocation of IRQ lines

As noted in section " Interrupt vectors ,” a few vectors are reserved for specific devices, while the remaining ones are dynamically handled. There is, therefore, a way in which the same IRQ line can be used by several hardware devices even if they do not allow IRQ sharing. The trick is to serialize the activation of the hardware devices so that just one owns the IRQ line at a time.

Before activating a device that is going to use an IRQ line, the corresponding driver invokes request_irq( ) . This function creates a new irqaction descriptor and initializes it with the parameter values; it then invokes the setup_irq( ) function to insert the descriptor in the proper IRQ list. The device driver aborts the operation if setup_irq( ) returns an error code, which usually means that the IRQ line is already in use by another device that does not allow interrupt sharing. When the device operation is concluded, the driver invokes the free_irq( ) function to remove the descriptor from the IRQ list and release the memory area.

Let’s see how this scheme works on a simple example. Assume a program wants to address the /dev/fd0 device file, which corresponds to the first floppy disk on the system. [ * ] The program can do this either by directly accessing /dev/fd0 or by mounting a filesystem on it. Floppy disk controllers are usually assigned IRQ 6; given this, a floppy driver may issue the following request:

As can be observed, the floppy_interrupt( ) interrupt service routine must execute with the interrupts disabled ( SA_INTERRUPT flag set) and no sharing of the IRQ ( SA_SHIRQ flag missing). The SA_SAMPLE_RANDOM flag set means that accesses to the floppy disk are a good source of random events to be used for the kernel random number generator. When the operation on the floppy disk is concluded (either the I/O operation on /dev/fd0 terminates or the filesystem is unmounted), the driver releases IRQ 6:

To insert an irqaction descriptor in the proper list, the kernel invokes the setup_irq( ) function, passing to it the parameters irq _nr , the IRQ number, and new (the address of a previously allocated irqaction descriptor). This function:

Checks whether another device is already using the irq _nr IRQ and, if so, whether the SA_SHIRQ flags in the irqaction descriptors of both devices specify that the IRQ line can be shared. Returns an error code if the IRQ line cannot be used.

Adds *new (the new irqaction descriptor pointed to by new ) at the end of the list to which irq _desc[irq _nr]->action points.

If no other device is sharing the same IRQ, the function clears the IRQ _DISABLED , IRQ_AUTODETECT , IRQ_WAITING , and IRQ _INPROGRESS flags in the flags field of *new and invokes the startup method of the irq_desc[irq_nr]->handler PIC object to make sure that IRQ signals are enabled.

Here is an example of how setup_irq( ) is used, drawn from system initialization. The kernel initializes the irq0 descriptor of the interval timer device by executing the following instructions in the time_init( ) function (see Chapter 6 ):

First, the irq0 variable of type irqaction is initialized: the handler field is set to the address of the timer_interrupt( ) function, the flags field is set to SA_INTERRUPT , the name field is set to "timer" , and the fifth field is set to NULL to show that no dev_id value is used. Next, the kernel invokes setup_irq( ) to insert irq0 in the list of irqaction descriptors associated with IRQ 0.

Interprocessor Interrupt Handling

Interprocessor interrupts allow a CPU to send interrupt signals to any other CPU in the system. As explained in the section " The Advanced Programmable Interrupt Controller (APIC) " earlier in this chapter, an interprocessor interrupt (IPI) is delivered not through an IRQ line, but directly as a message on the bus that connects the local APIC of all CPUs (either a dedicated bus in older motherboards, or the system bus in the Pentium 4-based motherboards).

On multiprocessor systems, Linux makes use of three kinds of interprocessor interrupts (see also Table 4-2 ):

Sent to all CPUs but the sender, forcing those CPUs to run a function passed by the sender. The corresponding interrupt handler is named call_function_interrupt( ) . The function (whose address is passed in the call_data global variable) may, for instance, force all other CPUs to stop, or may force them to set the contents of the Memory Type Range Registers (MTRRs). [ * ] Usually this interrupt is sent to all CPUs except the CPU executing the calling function by means of the smp_call_function( ) facility function.

When a CPU receives this type of interrupt, the corresponding handler — named reschedule_interrupt( ) — limits itself to acknowledging the interrupt. Rescheduling is done automatically when returning from the interrupt (see the section " Returning from Interrupts and Exceptions " later in this chapter).

Sent to all CPUs but the sender, forcing them to invalidate their Translation Lookaside Buffers. The corresponding handler, named invalidate_interrupt( ) , flushes some TLB entries of the processor as described in the section " Handling the Hardware Cache and the TLB " in Chapter 2 .

The assembly language code of the interprocessor interrupt handlers is generated by the BUILD_INTERRUPT macro: it saves the registers, pushes the vector number minus 256 on the stack, and then invokes a high-level C function having the same name as the low-level handler preceded by smp_ . For instance, the high-level handler of the CALL_FUNCTION_VECTOR interprocessor interrupt that is invoked by the low-level call_function_interrupt( ) handler is named smp_call_function_interrupt( ) . Each high-level handler acknowledges the interprocessor interrupt on the local APIC and then performs the specific action triggered by the interrupt.

Thanks to the following group of functions, issuing interprocessor interrupts (IPIs) becomes an easy task:

Sends an IPI to all CPUs (including the sender)

Sends an IPI to all CPUs except the sender

Sends an IPI to the sender CPU

Sends an IPI to a group of CPUs specified by a bit mask

[ * ] In contrast to disable_irq_nosync( ) , disable_irq(n) waits until all interrupt handlers for IRQ n that are running on other CPUs have completed before returning.

[ * ] There is an exception, though. Linux usually sets up the local APICs in such a way to honor the focus processor , when it exists. A focus process will catch all IRQs of the same type as long as it has received an IRQ of that type, and it has not finished executing the interrupt handler. However, Intel has dropped support for focus processors in the Pentium 4 model.

[ * ] 256 vectors is an architectural limit for the 80×86 architecture. 32 of them are used or reserved for the CPU, so the usable vector space consists of 224 vectors.

[ * ] Because IRQ_PENDING is a flag and not a counter, only the second occurrence of the interrupt can be recognized. Further occurrences in each iteration of the do_IRQ( ) ’s loop are simply lost.

[ * ] Floppy disks are “old” devices that do not usually allow IRQ sharing.

[ * ] Starting with the Pentium Pro model, Intel microprocessors include these additional registers to easily customize cache operations. For instance, Linux may use these registers to disable the hardware cache for the addresses mapping the frame buffer of a PCI/AGP graphic card while maintaining the “write combining” mode of operation: the paging unit combines write transfers into larger chunks before copying them into the frame buffer.

Get Understanding the Linux Kernel, 3rd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.

Don’t leave empty-handed

Get Mark Richards’s Software Architecture Patterns ebook to better understand how to design components—and how they should interact.

It’s yours, free.

Cover of Software Architecture Patterns

Check it out now on O’Reilly

Dive in for free with a 10-day trial of the O’Reilly learning platform—then explore all the other resources our members count on to build skills and solve problems every day.

linux irq assignments

  • Core API Documentation »
  • IRQs »
  • What is an IRQ?
  • View page source

What is an IRQ? ¶

An IRQ is an interrupt request from a device. Currently they can come in over a pin, or over a packet. Several devices may be connected to the same pin thus sharing an IRQ.

An IRQ number is a kernel identifier used to talk about a hardware interrupt source. Typically this is an index into the global irq_desc array, but except for what linux/interrupt.h implements the details are architecture specific.

An IRQ number is an enumeration of the possible interrupt sources on a machine. Typically what is enumerated is the number of input pins on all of the interrupt controller in the system. In the case of ISA what is enumerated are the 16 input pins on the two i8259 interrupt controllers.

Architectures can assign additional meaning to the IRQ numbers, and are encouraged to in the case where there is any manual configuration of the hardware involved. The ISA IRQs are a classic example of assigning this kind of additional meaning.

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

How can I know which IRQ is responsible of high CPU usage

I've moved a server from one mainboard to another due a disk controller failure.

Since then I've noticed that constantly a 25% of one of the cores goes always to IRQ however I haven't managed myself to know which is the IRQ responsible for that.

The kernel is a Linux 2.6.18-194.3.1.el5 (CentOS). mpstat -P ALL shows:

This is the /proc/interrupts

How can I identify which IRQ is causing the high CPU usage?

Output from dmesg | grep -i b4xxp

eproyectos's user avatar

  • 1 is this an asterisk server? what does dmesg | grep -i b4xxp show? –  Tim Kennedy Commented Nov 23, 2011 at 17:39
  • @TimKennedy: yes it is. I've edited my question to show what does dmesg show. –  eproyectos Commented Nov 23, 2011 at 20:10

4 Answers 4

Well, since you're specifically asking how to know which IRQ is responsible for the number in mpstat , you can assume it's not the local interrupt timer (LOC), since those numbers are fairly equal, and yet mpstat shows some of those cpus at 0 %irq.

That leaves IRQ 0, which is the system timer, and which you can't do anything about, and IRQ 177, which is tied to your b4xxp driver.

My guess is that IRQ 177 would be your culprit.

If this is causing a problem, and you would like to change the behavior your see, try:

disabling the software that uses that card, and see if the interrupts decrease.

removing that card from the system, and unloading the driver, and see if there's improvement.

move that card to another slot and see if that helps.

check for updated drivers or patches for the software.

If it's not a problem, and you were just curious, then carry on. :)

Tim Kennedy's user avatar

  • The problem arised after changing the MB. Maybe changing the card to another PCI slot is worth to try. –  eproyectos Commented Nov 23, 2011 at 20:12
  • 1 check this page: voip-info.org/wiki/view/Asterisk+PCI+bus+Troubleshooting good info for identifying problems, including IRQ issues. –  Tim Kennedy Commented Nov 23, 2011 at 20:35

sjas's user avatar

  • 1 This does not answer the actual question OP is asking. –  heemayl Commented Nov 9, 2017 at 5:36
  • That way you see the most interrupt changes, I know it did help me when troubleshooting exactly the issue that was described in the topic. –  sjas Commented Nov 9, 2017 at 23:36
  • +1 for the -d option <3 –  exic Commented Sep 7, 2021 at 10:34

BP410P is a ISDN card with 4 BRI Lines, if all four lines are connected you should be getting four sync packets at a time and when calls are being made you can have 8 voices channels active all sending packets, etc

If you get a high IRQ count without any calls being made this could be a symptom of 2 bad things:

  • There's a sync problem with the operator, you should also get bad voice quality.
  • IRQ lines are conflicting, in this case your ata_piix (ide/sata) is using the same line has the BP410P card, the drivers might not like that very much, in this case do has the previous answer suggested try and change the card to another slot.

To debug you can also try removing the BRI cables and see if it makes a difference.

led42's user avatar

  • +1 I'll check your advices. Thanks –  eproyectos Commented Nov 24, 2011 at 16:29
  • 1 Wow, shocking. The last time I had to play card-jockey was in the mid-Nineties. Haven't even used the term ‘card-jockey’ since. I thought all this was well behind us, what with APICs, MSI etc. –  Alexios Commented Mar 8, 2012 at 19:01

I found myself in such a situation some time ago, and I wrote a little irqtop tool to monitor easily what's going on. It's basically the same thing as doing a watch -n 1 cat /proc/interrupts , with a nicer output.

Source code available here: https://gitlab.com/elboulangero/irqtop

Rui F Ribeiro's user avatar

You must log in to answer this question.

Not the answer you're looking for browse other questions tagged kernel centos cpu ..

  • Featured on Meta
  • Upcoming sign-up experiments related to tags

Hot Network Questions

  • Mechanistic view of the universe
  • What does "the dogs of prescriptivism" mean?
  • Automatic adjustment of arrow endpoints placement of arrows connecting borders of tables
  • What is the purpose of the M1 pin on a Z80
  • My 5-year-old is stealing food and lying
  • Short story about a group of astronauts/scientist that find a sentient planet that seems friendly but is not
  • How to tell if the item language is the fallback language or the regular language version
  • Definition of the subcategory in book "Category Theory for Computing Science"
  • How can UserA programmatically replace a text string within a file they own that's located in /etc?
  • Finding a paper that has only abstract on ADS
  • What is the explicit list of the situations that require RAII?
  • Is Bayes’s theorem based on prejudice?
  • Do differently rendered measure numbers convey meaning?
  • Variable is significant in multiple linear regression but not in t-test of the subgroups
  • Are the complex numbers a graded algebra?
  • RAW, do transparent obstacles generally grant Total Cover?
  • Bulls and Cows meet Sudoku!
  • Paris Taxi with children seats (from and to airport)
  • How does MPPT maintain a constant voltage?
  • Securing HTTP File Transfer over local network
  • Is teaching how to solve recurrence relations using generating functions too much for a first year discrete maths course?
  • Can a star that initially started with less energy output than the sun (when it was young) evolve to be as luminous as the sun in the same time period
  • What is 得な性格? How is it used in this sentence?
  • How to find gaps in mathematics/theoretical physics/mathematical physics ? How to proceed after you found them?

linux irq assignments

  • Technical support

interrupt request (IRQ)

Rahul Awati

  • Rahul Awati

What is an interrupt request (IRQ)?

An interrupt request (IRQ) is a signal sent to a computer's processor to momentarily stop (interrupt) its operations. The signal is usually sent by a hardware device to interrupt the processor so the device gets some time to run its own operation. For example, when a printer finishes printing, it sends an interrupt signal to the computer. This signal momentarily interrupts its central processing unit (CPU) so it can decide what processing to do next.

An IRQ is important when multiple devices are connected to a computer. These devices need time to run their own operations and process some data and must, therefore, ask the processor to stop. They do this with an IRQ.

Once the device sends the IRQ, the processor momentarily stops so the computer can give the device time to run its operation. Every time a user moves a mouse , an interrupt handler tells the processor that it needs to stop what it's currently doing so it can handle and interpret the mouse movements.

IRQ channels and IRQ numbers

All devices connected to the computer communicate their IRQs over a unique data line called a channel . These include disk drive controllers , sound cards , printers , keyboards and mouses. Whenever the IRQ is referenced, it happens alongside the channel number, which is also known as an IRQ number . Each device is assigned its own IRQ number. For example, IRQ 1 may be used for a printer, IRQ 4 for a keyboard and IRQ 7 for a mouse.

Devices require a unique IRQ number to provide inputs to the processor or start a particular action. This number facilitates appropriate CPU response by assigning priorities to the various devices. The lower the IRQ number, the more important the need for the input or action. the system timer is typically assigned an IRQ of 0, while a PS/2 port -- keyboard or mouse -- may have an IRQ of 1. These low numbers prioritize the system timer and PS/2 port over, say, Integrated Drive Electronics primary or IDE secondary ports, which may have high IRQs, like IRQ 14 and IRQ 15, respectively.

IRQ assignments

Usually, IRQs can go up to IRQ 15. Here are typical IRQ assignments for a PC.

IRQ # Device

0

System timer

1

Keyboard (PS/2)

2

Cascade from IRQ 9

3

COM port 2 or 4

4

COM port 1 or 3

5

Parallel (printer) port 2 or sound cards

6

Floppy drive controller

7

Parallel (printer) port 1

8

Real-time clock

9

Video

10

Open

11

Open

12

Mouse (PS/2)

13

Coprocessor

14

Primary IDE controller (hard drives)

15

Secondary IDE controller (hard drives)

IRQ and plug and play

A computer can receive multiple signals on the same interrupt line but may not understand all these signals. To facilitate understanding, a unique value must be specified to the computer for each device and its path. When Industry Standard Architecture devices were in use and before plug-and-play ( PnP ) devices emerged, users had to set IRQ values manually when connecting a new device to a computer. Today, most devices are PnP. So, they are configured automatically, and users don't have to worry about them.

If a user adds a device that does not support PnP, the manufacturer should have provided explicit directions on how to assign IRQ values for it. If they don't know what IRQ value to specify, they'll save time by asking the manufacturer instead of trying to figure it out themselves.

IRQ errors can sometimes occur when installing new hardware or changing the settings of existing hardware (reconfiguration). Conflicts usually occur when two devices or pieces of hardware try to use the same IRQ channel for their IRQs. It is possible for multiple devices to use the same channel, but this is usually not done in practice. So, when simultaneous IRQs come in over the same channel, it results in a conflict.

One example of an IRQ error is IRQL_NOT_LESS_OR_EQUAL. This memory -related error occurs if a system process or a device driver tries to access a memory address but lacks valid access rights to do so. Thus, NOT_LESS_OR_EQUAL, sometimes known simply as IRQL, refers to an attempt to access an address that's outside a set boundary value (upper bound address). This IRQ error may occur due to corrupt system files, incompatible device drivers , faulty hardware or incomplete software installation.

When an IRQL error occurs, an operating system stop is triggered, which causes the OS to crash. If the OS is Windows , the crash triggers a blue screen of death . This is when Windows displays a stop screen with a message like the following: "Your PC ran into a problem and needs to restart. We're just collecting some error info, and then we'll restart for you." The user sees the stop screen as long as Windows is collecting the error data in the background. Once the collection phase ends, the computer reboots by default.

Usually, when an IRQ error occurs, the computer freezes up or devices may stop working. Such errors are a rarity now with PnP devices since there is no need to set IRQ channels manually. That makes it unlikely more than one device tries to use the same IRQ channel and cause a conflict.

How to view and change IRQ settings

In Windows, IRQ settings are usually visible under Device Manager. Changing the View menu option to Resources by type shows the IRQ section. Users can also use System Information. Execute the msinfo32.exe command from the Run dialog box, and navigate to Hardware Resources > IRQs.

memory range and IRQ of a device

To change IRQ settings, go into the BIOS or open Device Manager. To change IRQ settings with Device Manager, do the following:

  • Double-click a device to open its Properties window.
  • In the Resources tab, deselect the Use automatic settings option.
  • Select the hardware configuration that should be changed from the Settings based on drop-down menu.
  • Select IRQ from the Resource settings area of the properties.
  • Edit the IRQ value from the Change Setting button.

Before changing settings, remember that, if users make errors, their computer may not function correctly. Always note the existing settings before changing anything to be able restore them if something goes wrong.

Continue Reading About interrupt request (IRQ)

  • The last resort for troubleshooting hardware resource conflicts
  • 5 embedded system terms IoT admins must know
  • Why do Windows servers hang?
  • Determining the cause of Windows server hang
  • 'CallStranger' vulnerability affects billions of UPNP devices

Related Terms

A subnet, or subnetwork, is a segmented piece of a larger network. More specifically, subnets are a logical partition of an IP ...

Secure access service edge (SASE), pronounced sassy, is a cloud architecture model that bundles together network and cloud-native...

Transmission Control Protocol (TCP) is a standard protocol on the internet that ensures the reliable transmission of data between...

Personally identifiable information (PII) is any data that could potentially identify a specific individual.

A zero-day vulnerability is a security loophole in software, hardware or firmware that threat actors exploit before the vendors ...

A DNS attack is an exploit in which an attacker takes advantage of vulnerabilities in the domain name system.

Data collection is the process of gathering data for use in business decision-making, strategic planning, research and other ...

A chief trust officer (CTrO) in the IT industry is an executive job title given to the person responsible for building confidence...

Green IT (green information technology) is the practice of creating and using environmentally sustainable computing resources.

Diversity, equity and inclusion is a term used to describe policies and programs that promote the representation and ...

ADP Mobile Solutions is a self-service mobile app that enables employees to access work records such as pay, schedules, timecards...

Director of employee engagement is one of the job titles for a human resources (HR) manager who is responsible for an ...

Digital marketing is the promotion and marketing of goods and services to consumers through digital channels and electronic ...

Contact center schedule adherence is a standard metric used in business contact centers to determine whether contact center ...

Customer retention is a metric that measures customer loyalty, or an organization's ability to retain customers over time.

  • Core API Documentation »
  • Linux generic IRQ handling
  • View page source

Linux generic IRQ handling ¶

© 2005-2010: Thomas Gleixner

© 2005-2006: Ingo Molnar

Introduction ¶

The generic interrupt handling layer is designed to provide a complete abstraction of interrupt handling for device drivers. It is able to handle all the different types of interrupt controller hardware. Device drivers use generic API functions to request, enable, disable and free interrupts. The drivers do not have to know anything about interrupt hardware details, so they can be used on different platforms without code changes.

This documentation is provided to developers who want to implement an interrupt subsystem based for their architecture, with the help of the generic IRQ handling layer.

Rationale ¶

The original implementation of interrupt handling in Linux uses the __do_IRQ() super-handler, which is able to deal with every type of interrupt logic.

Originally, Russell King identified different types of handlers to build a quite universal set for the ARM interrupt handler implementation in Linux 2.5/2.6. He distinguished between:

Simple type

During the implementation we identified another type:

Fast EOI type

In the SMP world of the __do_IRQ() super-handler another type was identified:

Per CPU type

This split implementation of high-level IRQ handlers allows us to optimize the flow of the interrupt handling for each specific interrupt type. This reduces complexity in that particular code path and allows the optimized handling of a given type.

The original general IRQ implementation used hw_interrupt_type structures and their ->ack , ->end [etc.] callbacks to differentiate the flow control in the super-handler. This leads to a mix of flow logic and low-level hardware logic, and it also leads to unnecessary code duplication: for example in i386, there is an ioapic_level_irq and an ioapic_edge_irq IRQ-type which share many of the low-level details but have different flow handling.

A more natural abstraction is the clean separation of the ‘irq flow’ and the ‘chip details’.

Analysing a couple of architecture’s IRQ subsystem implementations reveals that most of them can use a generic set of ‘irq flow’ methods and only need to add the chip-level specific code. The separation is also valuable for (sub)architectures which need specific quirks in the IRQ flow itself but not in the chip details - and thus provides a more transparent IRQ subsystem design.

Each interrupt descriptor is assigned its own high-level flow handler, which is normally one of the generic implementations. (This high-level flow handler implementation also makes it simple to provide demultiplexing handlers which can be found in embedded platforms on various architectures.)

The separation makes the generic interrupt handling layer more flexible and extensible. For example, an (sub)architecture can use a generic IRQ-flow implementation for ‘level type’ interrupts and add a (sub)architecture specific ‘edge type’ implementation.

To make the transition to the new model easier and prevent the breakage of existing implementations, the __do_IRQ() super-handler is still available. This leads to a kind of duality for the time being. Over time the new model should be used in more and more architectures, as it enables smaller and cleaner IRQ subsystems. It’s deprecated for three years now and about to be removed.

Known Bugs And Assumptions ¶

None (knock on wood).

Abstraction layers ¶

There are three main levels of abstraction in the interrupt code:

High-level driver API

High-level IRQ flow handlers

Chip-level hardware encapsulation

Interrupt control flow ¶

Each interrupt is described by an interrupt descriptor structure irq_desc. The interrupt is referenced by an ‘unsigned int’ numeric value which selects the corresponding interrupt description structure in the descriptor structures array. The descriptor structure contains status information and pointers to the interrupt flow method and the interrupt chip structure which are assigned to this interrupt.

Whenever an interrupt triggers, the low-level architecture code calls into the generic interrupt code by calling desc->handle_irq(). This high-level IRQ handling function only uses desc->irq_data.chip primitives referenced by the assigned chip descriptor structure.

High-level Driver API ¶

The high-level Driver API consists of following functions:

request_irq()

request_threaded_irq()

disable_irq()

enable_irq()

disable_irq_nosync() (SMP only)

synchronize_irq() (SMP only)

irq_set_irq_type()

irq_set_irq_wake()

irq_set_handler_data()

irq_set_chip()

irq_set_chip_data()

See the autogenerated function documentation for details.

High-level IRQ flow handlers ¶

The generic layer provides a set of pre-defined irq-flow methods:

handle_level_irq()

handle_edge_irq()

handle_fasteoi_irq()

handle_simple_irq()

handle_percpu_irq()

handle_edge_eoi_irq()

handle_bad_irq()

The interrupt flow handlers (either pre-defined or architecture specific) are assigned to specific interrupts by the architecture either during bootup or during device initialization.

Default flow implementations ¶

Helper functions ¶.

The helper functions call the chip primitives and are used by the default flow implementations. The following helper functions are implemented (simplified excerpt):

Default flow handler implementations ¶

Default level irq flow handler ¶.

handle_level_irq provides a generic implementation for level-triggered interrupts.

The following control flow is implemented (simplified excerpt):

Default Fast EOI IRQ flow handler ¶

handle_fasteoi_irq provides a generic implementation for interrupts, which only need an EOI at the end of the handler.

Default Edge IRQ flow handler ¶

handle_edge_irq provides a generic implementation for edge-triggered interrupts.

Default simple IRQ flow handler ¶

handle_simple_irq provides a generic implementation for simple interrupts.

The simple flow handler does not call any handler/chip primitives.

Default per CPU flow handler ¶

handle_percpu_irq provides a generic implementation for per CPU interrupts.

Per CPU interrupts are only available on SMP and the handler provides a simplified version without locking.

EOI Edge IRQ flow handler ¶

handle_edge_eoi_irq provides an abnomination of the edge handler which is solely used to tame a badly wreckaged irq controller on powerpc/cell.

Bad IRQ flow handler ¶

handle_bad_irq is used for spurious interrupts which have no real handler assigned..

Quirks and optimizations ¶

The generic functions are intended for ‘clean’ architectures and chips, which have no platform-specific IRQ handling quirks. If an architecture needs to implement quirks on the ‘flow’ level then it can do so by overriding the high-level irq-flow handler.

Delayed interrupt disable ¶

This per interrupt selectable feature, which was introduced by Russell King in the ARM interrupt implementation, does not mask an interrupt at the hardware level when disable_irq() is called. The interrupt is kept enabled and is masked in the flow handler when an interrupt event happens. This prevents losing edge interrupts on hardware which does not store an edge interrupt event while the interrupt is disabled at the hardware level. When an interrupt arrives while the IRQ_DISABLED flag is set, then the interrupt is masked at the hardware level and the IRQ_PENDING bit is set. When the interrupt is re-enabled by enable_irq() the pending bit is checked and if it is set, the interrupt is resent either via hardware or by a software resend mechanism. (It’s necessary to enable CONFIG_HARDIRQS_SW_RESEND when you want to use the delayed interrupt disable feature and your hardware is not capable of retriggering an interrupt.) The delayed interrupt disable is not configurable.

Chip-level hardware encapsulation ¶

The chip-level hardware descriptor structure irq_chip contains all the direct chip relevant functions, which can be utilized by the irq flow implementations.

irq_mask_ack - Optional, recommended for performance

irq_eoi - Optional, required for EOI flow handlers

irq_retrigger - Optional

irq_set_type - Optional

irq_set_wake - Optional

These primitives are strictly intended to mean what they say: ack means ACK, masking means masking of an IRQ line, etc. It is up to the flow handler(s) to use these basic units of low-level functionality.

__do_IRQ entry point ¶

The original implementation __do_IRQ() was an alternative entry point for all types of interrupts. It no longer exists.

This handler turned out to be not suitable for all interrupt hardware and was therefore reimplemented with split functionality for edge/level/simple/percpu interrupts. This is not only a functional optimization. It also shortens code paths for interrupts.

Locking on SMP ¶

The locking of chip registers is up to the architecture that defines the chip primitives. The per-irq structure is protected via desc->lock, by the generic layer.

Generic interrupt chip ¶

To avoid copies of identical implementations of IRQ chips the core provides a configurable generic interrupt chip implementation. Developers should check carefully whether the generic chip fits their needs before implementing the same functionality slightly differently themselves.

NOOP function

Mask chip via disable register

Description

Chip has separate enable/disable registers instead of a single mask register.

Mask chip via setting bit in mask register

Chip has a single mask register. Values of this register are cached and protected by gc->lock

Mask chip via clearing bit in mask register

Unmask chip via enable register

Ack pending interrupt via setting bit

Set/clr wake bit for an interrupt

Indicates whether the wake bit should be set or cleared

For chips where the wake from suspend functionality is not configured in a separate register and the wakeup active state is just stored in a bitmask.

Allocate a generic chip and initialize it

Name of the irq chip

Number of irq_chip_type instances associated with this

Interrupt base nr for this chip

Register base address (virtual)

Default flow handler associated with this chip

Returns an initialized irq_chip_generic structure. The chip defaults to the primary (index 0) irq_chip_type and handler

Allocate generic chips for an irq domain

irq domain for which to allocate chips

Number of interrupts each chip handles (max 32)

Default flow handler associated with these chips

IRQ_* bits to clear in the mapping function

IRQ_* bits to set in the mapping function

Generic chip specific setup flags

Get a pointer to the generic chip of a hw_irq

irq domain pointer

Hardware interrupt number

Setup a range of interrupts with a generic chip

Generic irq chip holding all data

Bitmask holding the irqs to initialize relative to gc->irq_base

Flags for initialization

IRQ_* bits to clear

IRQ_* bits to set

Set up max. 32 interrupts starting from gc->irq_base. Note, this initializes all interrupts to the primary irq_chip_type and its associated handler.

Switch to alternative chip

irq_data for this interrupt

Flow type to be initialized

Only to be called from chip->irq_set_type() callbacks.

Remove a chip

Remove up to 32 interrupts starting from gc->irq_base.

Structures ¶

This chapter contains the autogenerated documentation of the structures which are used in the generic IRQ layer.

per irq data shared by all irqchips

status information for irq chip functions. Use accessor functions to deal with it

node index useful for balancing

per-IRQ data for the irq_chip methods

MSI descriptor

IRQ affinity on SMP. If this is an IPI related irq, then this is the mask of the CPUs to which an IPI can be sent.

The effective IRQ affinity on SMP as some irq chips do not allow multi CPU destinations. A subset of affinity .

Offset of first IPI target cpu in affinity . Optional.

per irq chip data passed down to chip functions

precomputed bitmask for accessing the chip registers

interrupt number

hardware interrupt number, local to the interrupt domain

point to data shared by all irqchips

low level interrupt hardware access

Interrupt translation domain; responsible for mapping between hwirq number and linux irq number.

pointer to parent struct irq_data to support hierarchy irq_domain

platform-specific per-chip private data for the chip methods, to allow shared chip implementations

hardware interrupt chip descriptor

pointer to parent device for irqchip

name for /proc/interrupts

start up the interrupt (defaults to ->enable if NULL)

shut down the interrupt (defaults to ->disable if NULL)

enable the interrupt (defaults to chip->unmask if NULL)

disable the interrupt

start of a new interrupt

mask an interrupt source

ack and mask an interrupt source

unmask an interrupt source

end of interrupt

Set the CPU affinity on SMP machines. If the force argument is true, it tells the driver to unconditionally apply the affinity setting. Sanity checks against the supplied affinity mask are not required. This is used for CPU hotplug where the target CPU is not yet set in the cpu_online_mask.

resend an IRQ to the CPU

set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ

enable/disable power-management wake-on of an IRQ

function to lock access to slow bus (i2c) chips

function to sync and unlock slow bus (i2c) chips

configure an interrupt source for a secondary CPU

un-configure an interrupt source for a secondary CPU

function called from core code on suspend once per chip, when one or more interrupts are installed

function called from core code on resume once per chip, when one ore more interrupts are installed

function called from core code on shutdown once per chip

Optional function to set irq_data.mask for special cases

optional to print special chip info in show_interrupts

optional to request resources before calling any other callback related to this irq

optional to release resources acquired with irq_request_resources

optional to compose message content for MSI

optional to write message content for MSI

return the internal state of an interrupt

set the internal state of a interrupt

optional to target a vCPU in a virtual machine

send a single IPI to destination cpus

send an IPI to destination cpus in cpumask

function called from core code before enabling an NMI

function called from core code after disabling an NMI

chip specific flags

register offsets for struct irq_gci

Enable register offset to reg_base

Disable register offset to reg_base

Mask register offset to reg_base

Ack register offset to reg_base

Eoi register offset to reg_base

Type configuration register offset to reg_base

Polarity configuration register offset to reg_base

Generic interrupt chip instance for a flow type

The real interrupt chip which provides the callbacks

Register offsets for this chip

Flow handler associated with this chip

Chip can handle these flow types

Cached mask register private to the chip type

Pointer to cached mask register

A irq_generic_chip can have several instances of irq_chip_type when it requires different functions and register offsets for different flow types.

Generic irq chip data structure

Lock to protect register and cache data access

Alternate I/O accessor (defaults to readl if NULL)

Alternate I/O accessor (defaults to writel if NULL)

Function called from core code on suspend once per chip; can be useful instead of irq_chip::suspend to handle chip details even when no interrupts are in use

Function called from core code on resume once per chip; can be useful instead of irq_chip::suspend to handle chip details even when no interrupts are in use

Number of interrupts handled by this chip

Cached mask register shared between all chip types

Cached type register

Cached polarity register

Interrupt can wakeup from suspend

Interrupt is marked as an wakeup from suspend source

Number of available irq_chip_type instances (usually 1)

Private data for non generic chip callbacks

bitfield to denote installed interrupts

bitfield to denote unused interrupts

List head for keeping track of instances

Array of interrupt irq_chip_types

Note, that irq_chip_generic can have multiple irq_chip_type implementations which can be associated to a particular irq line of an irq_chip_generic instance. That allows to share and protect state in an irq_chip_generic instance when we need to implement different flow mechanisms (level/edge) for it.

Initialization flags for generic irq chips

Initialize the mask_cache by reading mask reg

Set the lock class of the irqs to nested for irq chips which need to call irq_set_wake() on the parent irq. Usually GPIO implementations

Mask cache is chip type private

Do not calculate irq_data->mask

Use big-endian register accesses (default: LE)

per interrupt action descriptor

interrupt handler function

cookie to identify the device

pointer to the next irqaction for shared interrupts

interrupt handler function for threaded interrupts

thread pointer for threaded interrupts

pointer to secondary irqaction (force threading)

flags (see IRQF_* above)

flags related to thread

bitmask for keeping track of thread activity

name of the device

pointer to the proc/irq/NN/name entry

Add a handler for an interrupt line

The interrupt line to allocate

Function to be called when the IRQ occurs. Primary handler for threaded interrupts If NULL, the default primary handler is installed

Handling flags

Name of the device generating this interrupt

A cookie passed to the handler function

This call allocates an interrupt and establishes a handler; see the documentation for request_threaded_irq() for details.

context for notification of IRQ affinity changes

Interrupt to which notification applies

Reference count, for internal use

Work item, for internal use

Function to be called on change. This will be called in process context.

Function to be called on release. This will be called in process context. Once registered, the structure must only be freed when this function is called or later.

Description for automatic irq affinity assignements

Don’t apply affinity to pre_vectors at beginning of the MSI(-X) vector space

Don’t apply affinity to post_vectors at end of the MSI(-X) vector space

The number of interrupt sets for which affinity spreading is required

Array holding the size of each interrupt set

Callback for calculating the number and size of interrupt sets

Private data for usage by calc_sets , usually a pointer to driver/device specific data.

Interrupt affinity descriptor

cpumask to hold the affinity assignment

1 if the interrupt is managed internally

Public Functions Provided ¶

This chapter contains the autogenerated documentation of the kernel API functions which are exported.

wait for pending hard IRQ handlers (on other CPUs)

interrupt number to wait for

This function waits for any pending hard IRQ handlers for this interrupt to complete before returning. If you use this function while holding a resource the IRQ handler may need you will deadlock. It does not take associated threaded handlers into account.

Do not use this for shutdown scenarios where you must be sure that all parts (hardirq and threaded handler) have completed.

false if a threaded handler is active.

This function may be called - with care - from IRQ context. It does not check whether there is an interrupt in flight at the hardware level, but not serviced yet, as this might deadlock when called with interrupts disabled and the target CPU of the interrupt is the current CPU.

wait for pending IRQ handlers (on other CPUs)

This function waits for any pending IRQ handlers for this interrupt to complete before returning. If you use this function while holding a resource the IRQ handler may need you will deadlock.

Can only be called from preemptible code as it might sleep when an interrupt thread is associated to irq .

It optionally makes sure (when the irq chip supports that method) that the interrupt is not pending in any CPU and waiting for service.

Check if the affinity of a given irq can be set

Interrupt to check

Check if affinity of a irq can be set from user space

Like irq_can_set_affinity() above, but additionally checks for the AFFINITY_MANAGED flag.

Notify irq threads to adjust affinity

irq descriptor which has affinity changed

We just set IRQTF_AFFINITY and delegate the affinity setting to the interrupt thread itself. We can not call set_cpus_allowed_ptr() here as we hold desc->lock and this code can be called from hard interrupt context.

Update affinity management for an interrupt

The interrupt number to update

Pointer to the affinity descriptor

This interface can be used to configure the affinity management of interrupts which have been allocated already.

There are certain limitations on when it may be used - attempts to use it for when the kernel is configured for generic IRQ reservation mode (in config GENERIC_IRQ_RESERVATION_MODE) will fail, as it may conflict with managed/non-managed interrupt accounting. In addition, attempts to use it on an interrupt which is already started or which has already been configured as managed will also fail, as these mean invalid init state or double init.

Set the irq affinity of a given irq

Interrupt to set affinity

Fails if cpumask does not contain an online CPU

Force the irq affinity of a given irq

Same as irq_set_affinity, but without checking the mask against online cpus.

Solely for low level cpu hotplug code, where we need to make per cpu interrupts affine before the cpu becomes online.

control notification of IRQ affinity changes

Interrupt for which to enable/disable notification

Context for notification, or NULL to disable notification. Function pointers must be initialised; the other fields will be initialised by this function.

Must be called in process context. Notification may only be enabled after the IRQ is allocated and must be disabled before the IRQ is freed using free_irq() .

Set vcpu affinity for the interrupt

interrupt number to set affinity

vCPU specific data or pointer to a percpu array of vCPU specific data for percpu_devid interrupts

This function uses the vCPU specific data to set the vCPU affinity for an irq. The vCPU specific data is passed from outside, such as KVM. One example code path is as below: KVM -> IOMMU -> irq_set_vcpu_affinity() .

disable an irq without waiting

Interrupt to disable

Disable the selected interrupt line. Disables and Enables are nested. Unlike disable_irq() , this function does not ensure existing instances of the IRQ handler have completed before returning.

This function may be called from IRQ context.

disable an irq and wait for completion

Disable the selected interrupt line. Enables and Disables are nested. This function waits for any pending IRQ handlers for this interrupt to complete before returning. If you use this function while holding a resource the IRQ handler may need you will deadlock.

This function may be called - with care - from IRQ context.

disables an irq and waits for hardirq completion

Disable the selected interrupt line. Enables and Disables are nested. This function waits for any pending hard IRQ handlers for this interrupt to complete before returning. If you use this function while holding a resource the hard IRQ handler may need you will deadlock.

When used to optimistically disable an interrupt from atomic context the return value must be checked.

disable an nmi without waiting

Disable the selected interrupt line. Disables and enables are nested. The interrupt to disable must have been requested through request_nmi. Unlike disable_nmi(), this function does not ensure existing instances of the IRQ handler have completed before returning.

enable handling of an irq

Interrupt to enable

Undoes the effect of one call to disable_irq() . If this matches the last disable, processing of interrupts on this IRQ line is re-enabled.

This function may be called from IRQ context only when desc->irq_data.chip->bus_lock and desc->chip->bus_sync_unlock are NULL !

enable handling of an nmi

The interrupt to enable must have been requested through request_nmi. Undoes the effect of one call to disable_nmi(). If this matches the last disable, processing of interrupts on this IRQ line is re-enabled.

control irq power management wakeup

interrupt to control

enable/disable power management wakeup

Enable/disable power management wakeup mode, which is disabled by default. Enables and disables must match, just as they match for non-wakeup mode support.

Wakeup mode lets this IRQ wake the system from sleep states like “suspend to RAM”.

to the enable/disable state of irq wake. An irq can be disabled with disable_irq() and still wake the system as long as the irq has wake enabled. If this does not hold, then the underlying irq chip and the related driver need to be investigated.

wake the irq thread for the action identified by dev_id

Interrupt line

Device identity for which the thread should be woken

free an interrupt allocated with request_irq

Interrupt line to free

Device identity to free

Remove an interrupt handler. The handler is removed and if the interrupt line is no longer in use by any driver it is disabled. On a shared IRQ the caller must ensure the interrupt is disabled on the card it drives before calling this function. The function does not return until any executing interrupts for this IRQ have completed.

This function must not be called from interrupt context.

Returns the devname argument passed to request_irq.

allocate an interrupt line

Interrupt line to allocate

Function to be called when the IRQ occurs. Primary handler for threaded interrupts. If handler is NULL and thread_fn != NULL the default primary handler is installed.

Function called from the irq handler thread If NULL, no irq thread is created

Interrupt type flags

An ascii name for the claiming device

A cookie passed back to the handler function

This call allocates interrupt resources and enables the interrupt line and IRQ handling. From the point this call is made your handler function may be invoked. Since your handler function must clear any interrupt the board raises, you must take care both to initialise your hardware and to set up the interrupt handler in the right order.

If you want to set up a threaded irq handler for your device then you need to supply handler and thread_fn . handler is still called in hard interrupt context and has to check whether the interrupt originates from the device. If yes it needs to disable the interrupt on the device and return IRQ_WAKE_THREAD which will wake up the handler thread and run thread_fn . This split handler design is necessary to support shared interrupts.

Dev_id must be globally unique. Normally the address of the device data structure is used as the cookie. Since the handler receives this value it makes sense to use it.

If your interrupt is shared you must pass a non NULL dev_id as this is required when freeing the interrupt.

IRQF_SHARED Interrupt is shared IRQF_TRIGGER_* Specify active edge(s) or level IRQF_ONESHOT Run thread_fn with interrupt line masked

Function to be called when the IRQ occurs. Threaded handler for threaded interrupts.

This call allocates interrupt resources and enables the interrupt line and IRQ handling. It selects either a hardirq or threaded handling method depending on the context.

On failure, it returns a negative value. On success, it returns either IRQC_IS_HARDIRQ or IRQC_IS_NESTED.

allocate an interrupt line for NMI delivery

This call allocates interrupt resources and enables the interrupt line and IRQ handling. It sets up the IRQ line to be handled as an NMI.

An interrupt line delivering NMIs cannot be shared and IRQ handling cannot be threaded.

Interrupt lines requested for NMI delivering must produce per cpu interrupts and have auto enabling setting disabled.

If the interrupt line cannot be used to deliver NMIs, function will fail and return a negative value.

Check whether the per cpu irq is enabled

Linux irq number to check for

Must be called from a non migratable context. Returns the enable state of a per cpu interrupt on the current cpu.

free a per-cpu interrupt

irqaction for the interrupt

Used to remove interrupts statically setup by the early boot process.

free an interrupt allocated with request_percpu_irq

Remove a percpu interrupt handler. The handler is removed, but the interrupt line is not disabled. This must be done on each CPU before calling this function. The function does not return until any executing interrupts for this IRQ have completed.

setup a per-cpu interrupt

Interrupt line to setup

Used to statically setup per-cpu interrupts in the early boot process.

allocate a percpu interrupt line

Function to be called when the IRQ occurs.

Interrupt type flags (IRQF_TIMER only)

A percpu cookie passed back to the handler function

This call allocates interrupt resources and enables the interrupt on the local CPU. If the interrupt is supposed to be enabled on other CPUs, it has to be done on each CPU using enable_percpu_irq().

Dev_id must be globally unique. It is a per-cpu variable, and the handler gets called with the interrupted CPU’s instance of that variable.

allocate a percpu interrupt line for NMI delivery

This call allocates interrupt resources for a per CPU NMI. Per CPU NMIs have to be setup on each CPU by calling prepare_percpu_nmi() before being enabled on the same CPU by using enable_percpu_nmi().

Interrupt lines requested for NMI delivering should have auto enabling setting disabled.

If the interrupt line cannot be used to deliver NMIs, function will fail returning a negative value.

performs CPU local setup for NMI delivery

Interrupt line to prepare for NMI delivery

This call prepares an interrupt line to deliver NMI on the current CPU, before that interrupt line gets enabled with enable_percpu_nmi().

As a CPU local operation, this should be called from non-preemptible context.

undoes NMI setup of IRQ line

Interrupt line from which CPU local NMI configuration should be removed

This call undoes the setup done by prepare_percpu_nmi() . IRQ line should not be enabled for the current CPU. As a CPU local operation, this should be called from non-preemptible context.

returns the irqchip state of a interrupt.

Interrupt line that is forwarded to a VM

One of IRQCHIP_STATE_* the caller wants to know about

a pointer to a boolean where the state is to be stored

This call snapshots the internal irqchip state of an interrupt, returning into state the bit corresponding to stage which

This function should be called with preemption disabled if the interrupt controller has per-cpu registers.

set the state of a forwarded interrupt.

State to be restored (one of IRQCHIP_STATE_*)

Value corresponding to which

This call sets the internal irqchip state of an interrupt, depending on the value of which .

This function should be called with migration disabled if the interrupt controller has per-cpu registers.

Check whether an interrupt is requested

The linux irq number

A snapshot of the current state

Check whether bits in the irq descriptor status are set

The bitmask to evaluate

True if one of the bits in bitmask is set

set the irq chip for an irq

pointer to irq chip description structure

set the irq trigger type for an irq

IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h

set irq handler data for an irq

Interrupt number

Pointer to interrupt specific data

Set the hardware irq controller data for an irq

set irq chip data for an irq

Pointer to chip specific data

Set the hardware irq chip data for an irq

Simple and software-decoded IRQs.

the interrupt description structure for this irq

Simple interrupts are either sent from a demultiplexing interrupt handler or come from hardware, where no interrupt hardware control is necessary.

unmask issues if necessary.

Untracked interrupts are sent from a demultiplexing interrupt handler when the demultiplexer does not know which device it its multiplexed irq domain generated the interrupt. IRQ’s handled through here are not subjected to stats tracking, randomness, or spurious interrupt detection.

the ack, clear, mask and unmask issues if necessary.

Level type irq handler

Level type interrupts are active as long as the hardware line has the active level. This may require to mask the interrupt and unmask it after the associated handler has acknowledged the device, so the interrupt line is back to inactive.

irq handler for transparent controllers

Only a single callback will be issued to the chip: an ->eoi() call when the interrupt has been serviced. This enables support for modern forms of interrupt handlers, which handle the flow details in hardware, transparently.

irq handler for NMI interrupt lines

A simple NMI-safe handler, considering the restrictions from request_nmi.

edge type IRQ handler

Interrupt occurs on the falling and/or rising edge of a hardware signal. The occurrence is latched into the irq controller hardware and must be acked in order to be reenabled. After the ack another interrupt can happen on the same source even before the first one is handled by the associated event handler. If this happens it might be necessary to disable (mask) the interrupt depending on the controller hardware. This requires to reenable the interrupt inside of the loop which handles the interrupts which have arrived while the handler was running. If all pending interrupts are handled, the loop is left.

irq handler for edge hierarchy stacked on transparent controllers

Like handle_fasteoi_irq() , but for use with hierarchy where the irq_chip also needs to have its ->irq_ack() function called.

irq handler for level hierarchy stacked on transparent controllers

Like handle_fasteoi_irq() , but for use with hierarchy where the irq_chip also needs to have its ->irq_mask_ack() function called.

set the state of a parent interrupt.

Conditional success, if the underlying irqchip does not implement it.

get the state of a parent interrupt.

one of IRQCHIP_STATE_* the caller wants to know

Enable the parent interrupt (defaults to unmask if NULL)

Disable the parent interrupt (defaults to mask if NULL)

Acknowledge the parent interrupt

Mask the parent interrupt

Mask and acknowledge the parent interrupt

Unmask the parent interrupt

Invoke EOI on the parent interrupt

Set affinity on the parent interrupt

The affinity mask to set

Flag to enforce setting (disable online checks)

Conditional, as the underlying parent chip might not implement it.

Set IRQ type on the parent interrupt

Retrigger an interrupt in hardware

Iterate through the domain hierarchy of the interrupt and check whether a hw retrigger function exists. If yes, invoke it.

Set vcpu affinity on the parent interrupt

The vcpu affinity information

Set/reset wake-up on the parent interrupt

Whether to set or reset the wake-up capability of this irq

Request resources on the parent interrupt

Release resources on the parent interrupt

Internal Functions Provided ¶

This chapter contains the autogenerated documentation of the internal functions.

Invoke the handler for a particular irq

The irq number to handle

0 on success, or -EINVAL if conversion has failed

This function must be called from an IRQ context with irq regs initialized.

Invoke the handler for a HW irq belonging to a domain.

The domain where to perform the lookup

The HW irq number to convert to a logical one

Invoke the handler for a HW nmi belonging to a domain.

This function must be called from an NMI context with irq regs initialized.

free irq descriptors

Start of descriptor range

Number of consecutive irqs to free

allocate and initialize a range of irq descriptors

Allocate for specific irq number if irq >= 0

Start the search from this irq number

Number of consecutive irqs to allocate.

Preferred node on which the irq descriptor should be allocated

Owning module (can be NULL)

Optional pointer to an affinity mask array of size cnt which hints where the irq descriptors should be allocated and which default affinities to use

Returns the first irq number or error code

get next allocated irq number

where to start the search

Returns next irq number after offset or nr_irqs if none is found.

Get the statistics for an interrupt on a cpu

The interrupt number

The cpu number

Returns the sum of interrupt counts on cpu since boot for irq . The caller must ensure that the interrupt is not removed concurrently.

Get the statistics for an interrupt from thread context

Returns the sum of interrupt counts on all cpus since boot for irq .

It uses rcu to protect the access since a concurrent removal of an interrupt descriptor is observing an rcu grace period before delayed_free_desc()/irq_kobj_release().

handle spurious and unhandled irqs

description of the interrupt

Handles spurious and unhandled IRQ’s. It also prints a debugmessage.

root irq handler for architectures which do no entry accounting themselves

Register file coming from the low-level handling code

set MSI descriptor data for an irq at offset

Interrupt number base

Interrupt number offset

Pointer to MSI descriptor data

Set the MSI descriptor entry for an irq at offset

set MSI descriptor data for an irq

Set the MSI descriptor entry for an irq

Mark interrupt disabled

irq descriptor which should be disabled

If the chip does not implement the irq_disable callback, we use a lazy disable approach. That means we mark the interrupt disabled, but leave the hardware unmasked. That’s an optimization because we avoid the hardware access for the common case where no interrupt happens after we marked it disabled. If an interrupt happens, then the interrupt flow handler masks the line at the hardware level and marks it pending.

If the interrupt chip does not implement the irq_disable callback, a driver can disable the lazy approach for a particular irq line by calling ‘irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY)’. This can be used for devices which cannot disable the interrupt at the device level under certain circumstances and have to use disable_irq[_nosync] instead.

edge eoi type IRQ handler

Similar as the above handle_edge_irq, but using eoi and w/o the mask/unmask logic.

Per CPU local irq handler

Per CPU interrupts on SMP machines without locking requirements

Per CPU local irq handler with per cpu dev ids

Per CPU interrupts on SMP machines without locking requirements. Same as handle_percpu_irq() above but with the following extras:

action->percpu_dev_id is a pointer to percpu variables which contain the real device id for the cpu on which this handler is called

Per CPU local NMI handler with per cpu dev ids

Similar to handle_fasteoi_nmi, but handling the dev_id cookie as a percpu pointer.

Invoke all irq_cpu_online functions.

no arguments

Iterate through all irqs and invoke the chip. irq_cpu_online() for each.

Invoke all irq_cpu_offline functions.

Iterate through all irqs and invoke the chip. irq_cpu_offline() for each.

Compose msi message for a irq chip

Pointer to the MSI message

For hierarchical domains we find the first chip in the hierarchy which implements the irq_compose_msi_msg callback. For non hierarchical we use the top level chip.

Enable power for an IRQ chip

Enable the power to the IRQ chip referenced by the interrupt data structure.

Disable power for an IRQ chip

Disable the power to the IRQ chip referenced by the interrupt data structure, belongs. Note that power will only be disabled, once this function has been called for all IRQs that have called irq_chip_pm_get() .

The following people have contributed to this document:

Thomas Gleixner tglx @ linutronix . de

Ingo Molnar mingo @ elte . hu

IMAGES

  1. linux IRQ Management(四)- IRQ Domain

    linux irq assignments

  2. linux IRQ Management(四)- IRQ Domain

    linux irq assignments

  3. linux IRQ Management(四)- IRQ Domain

    linux irq assignments

  4. linux IRQ Management(一)- ARM GIC_arm gicv3 and gicv4 software overview

    linux irq assignments

  5. Interrupt request (IRQ)

    linux irq assignments

  6. Zynq and IRQ design to work with linux driver

    linux irq assignments

VIDEO

  1. LinuxでPalworldマルチサーバーを建てる方法

  2. Umineko no Naku Koro ni

  3. Why Don't You Use Linux? (Season 4, Episode 11)

  4. Running Solaris 2.9 (sparc) on qemu-system-sparc in Linux x86_64 (Mint 19)

  5. Vulnerability Scanning| Vulnerability Assessment| WEB Server| Golismero

  6. How to Add Repository in Ubuntu? [2 Simple Methods]

COMMENTS

  1. Linux list all IROs currently in use

    How do I list all IRQs currently used under CentOS Linux? Advertisement. A .. There is a file called /proc/interrupts. The proc filesystem is a pseudo filesystem which is used as an interface to kernel data structures. It is commonly mounted at /proc. This is used to record the number of interrupts per each IRQ on (at least) the i386 architecture.

  2. How the Linux kernel handles interrupts

    Subsequent IRQs can be assigned differently. The interrupt descriptor table (IDT) contains the assignment between IRQ and ISR. Linux defines an IRQ vector from 0 to 256 for the assignment. To print a list of registered interrupts on your system, open a console and type: cat /proc/interrupts. You should see something like this:

  3. linux

    1. PCI configuration space is configured by the Bios, which means that Bios is supposed to enumerate all PCI devices at boot time. When a device is enumerated, the Bios routes an IRQ line to the IOAPIC input and set BAR registers, then, the kernel can request_irq () with the appropriate irq number read from the pci configuration space. Just to ...

  4. What is an IRQ?

    An IRQ number is a kernel identifier used to talk about a hardware interrupt source. Typically this is an index into the global irq_desc array, but except for what linux/interrupt.h implements the details are architecture specific. An IRQ number is an enumeration of the possible interrupt sources on a machine. Typically what is enumerated is ...

  5. Linux generic IRQ handling

    bool irq_percpu_is_enabled (unsigned int irq) ¶ Check whether the per cpu irq is enabled. Parameters. unsigned int irq Linux irq number to check for. Description. Must be called from a non migratable context. Returns the enable state of a per cpu interrupt on the current cpu. void remove_percpu_irq (unsigned int irq, struct irqaction * act) ¶

  6. IRQs

    The Linux Kernel 5.15.0 The Linux kernel user's and administrator's guide; Kernel Build System; The Linux kernel firmware guide; Open Firmware and Devicetree ... What is an IRQ? SMP IRQ affinity; The irq_domain interrupt number mapping library; IRQ-flags state tracing; Next Previous

  7. IRQs

    What is an IRQ? SMP IRQ affinity; The irq_domain interrupt number mapping library; IRQ-flags state tracing; Semantics and Behavior of Local Atomic Operations; The padata parallel execution mechanism; RCU concepts; Linux kernel memory barriers; Low-level hardware management; Memory management; Interfaces for kernel debugging; Everything else

  8. How linux know which irq number should be used?

    For interrupt for MSI, it seems generated by kernel ?? --. In my understanding, the irq number should be read from Interrupt Line Register (offset 3Ch) in PCIe configuration space, I guess that's why kerenl already know which irq number should be used, and Interrupt Line Register should be updated by BIOS ( my guess ) during boot, but there ...

  9. Introduction to IRQs, DMAs and Base Addresses LG #38

    An IRQ is a hardware interrupt, this means that there is a physical line run to each of the ISA slots on the motherboard. There are 2 types of ISA slots: 8 bit and 16 bit. The 16 bit consists of the 8 bit slot plus a 16 bit extension slot. There are 8 IRQ (IRQ0-7) lines that run to the 8 bit ISA slot. There are 8 more (IRQ8-15) that run to the ...

  10. 4.6. Interrupt Handling

    IRQ sharing. The interrupt handler executes several interrupt service routines (ISRs).Each ISR is a function related to a single device sharing the IRQ line. Because it is not possible to know in advance which particular device issued the IRQ, each ISR is executed to verify whether its device needs attention; if so, the ISR performs all the operations that need to be executed when the device ...

  11. What is an IRQ?

    An IRQ is an interrupt request from a device. Currently they can come in over a pin, or over a packet. Several devices may be connected to the same pin thus sharing an IRQ. An IRQ number is a kernel identifier used to talk about a hardware interrupt source. Typically this is an index into the global irq_desc array, but except for what linux ...

  12. How can I know which IRQ is responsible of high CPU usage

    Since then I've noticed that constantly a 25% of one of the cores goes always to IRQ however I haven't managed myself to know which is the IRQ responsible for that. The kernel is a Linux 2.6.18-194.3.1.el5 (CentOS). mpstat -P ALL shows: This is the /proc/interrupts. CPU0 CPU1 CPU2 CPU3.

  13. What is an interrupt request (IRQ) and how does it work?

    IRQ (interrupt request): An IRQ ( interrupt request ) value is an assigned location where the computer can expect a particular device to interrupt it when the device sends the computer signals about its operation. For example, when a printer has finished printing, it sends an interrupt signal to the computer. The signal momentarily interrupts ...

  14. Interrupt request

    Interrupt request. In a computer, an interrupt request (or IRQ) is a hardware signal sent to the processor that temporarily stops a running program and allows a special program, an interrupt handler, to run instead. Hardware interrupts are used to handle events such as receiving data from a modem or network card, key presses, or mouse movements.

  15. The irq_domain interrupt number mapping library

    The irq_domain library adds mapping between hwirq and IRQ numbers on top of the irq_alloc_desc* () API. An irq_domain to manage mapping is preferred over interrupt controller drivers open coding their own reverse mapping scheme. irq_domain also implements translation from an abstract irq_fwspec structure to hwirq numbers (Device Tree and ACPI ...

  16. Linux generic IRQ handling

    unsigned int irq Linux irq number to check for. Description. Must be called from a non migratable context. Returns the enable state of a per cpu interrupt on the current cpu. void remove_percpu_irq (unsigned int irq, struct irqaction *act) ¶ free a per-cpu interrupt. Parameters. unsigned int irq Interrupt line to free struct irqaction *act ...

  17. irq/dma assignments in linux

    With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use. Exclusive for LQ members, get up to 45% off per month. Click here for more info.

  18. The irq_domain interrupt number mapping library

    The irq_domain library adds mapping between hwirq and IRQ numbers on top of the irq_alloc_desc* () API. An irq_domain to manage mapping is preferred over interrupt controller drivers open coding their own reverse mapping scheme. irq_domain also implements translation from an abstract irq_fwspec structure to hwirq numbers (Device Tree and ACPI ...

  19. IRQs

    IRQs. ¶. What is an IRQ? SMP IRQ affinity. The irq_domain interrupt number mapping library. IRQ-flags state tracing. ©The kernel development community. | Powered by Sphinx 5.0.1 & Alabaster 0.7.12 | Page source.

  20. Linux generic IRQ handling

    unsigned int irq. Linux irq number to check for. Description. Must be called from a non migratable context. Returns the enable state of a per cpu interrupt on the current cpu. void remove_percpu_irq (unsigned int irq, struct irqaction *act) ¶ free a per-cpu interrupt. Parameters. unsigned int irq. Interrupt line to free. struct irqaction *act ...