Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


14.1.4 Data Structures


There are two facets to the technical implementation of interrupts — assembly language code, which
is highly processor-dependent and is used to process the relevant lower-level details on the particular
platform; and an abstracted interface, which is required by device drivers and other kernel code to install
and manage IRQ handlers. I focus on the second aspect. The countless details needed to describe the
functioning of the assembly language part are best left to books and manuals on processor architecture.

To respond to the IRQs of peripheral devices, the kernel must provide a function for each potential IRQ.
This function must be able to register and de-register itself dynamically. A static table organization is not
sufficient because modules may also be written for devices that interact with the rest of the system by
means of interrupts.

The central point at which information on IRQs is managed is a global array with an entry for each IRQ
number. Because array position and interrupt number are identical, it is easy to locate the entry associated
with a specific IRQ: IRQ 0 is at position 0, IRQ 15 at position 15, and so on; to which processor interrupt
the IRQs are ultimately mapped is of no relevance here.

Thearrayisdefinedasfollows:

kernel/irq/handle.c
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
...
}
};

Although an architecture-independent data type is used for the individual entries, the maximum pos-
sible number of IRQs is specified by a platform-dependent constant:NR_IRQS. This constant is for most
architectures defined in the processor-specific header fileinclude/asm-arch/irq.h.^5 Its value varies
widely not only between the different processors but also within processor families depending on which
auxiliary chip is used to help the CPU manage IRQs. Alpha computers support between 32 interrupts on
‘‘smaller‘‘ systems and a fabulous 2,048 interrupts on Wildfire boards; IA-64 processors always have 256
interrupts. IA-32 systems, in conjunction with the classical 8256A controller, provide a meager 16 IRQs.
This number can be increased to 224 using the IO-APIC (advanced programmable interrupt controller)
expansion that is found on all multiprocessor systems but that can also be deployed on UP machines.
Initially, all interrupt slots usehandle_bad_irqas a handler function that just acknowledges interrupts
for which no specific handler function is installed.

More interesting than the maximum number of IRQs is the data type used for the array entries (in contrast
to the simple example above, it is not merely a pointer to a function). Before I get into the technical details,
I need to present an overview of the kernel’s IRQ-handling subsystem.

(^5) The IA-32 architecture, however, uses/include/asm-x86/mach-type/irq_vectors_limits.h.

Free download pdf