Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 14: Kernel Activities


❑ IRQ_PENDINGis active when the CPU has noticed an interrupt but has not yet executed the corre-
sponding handler.
❑ IRQ_MASKEDis required to properly handle interrupts that occur during interrupt processing; see
Section 14.1.4.
❑ IRQ_PER_CPUis set when an IRQ can occur on a single CPU only. (On SMP systems this renders
several protection mechanisms against concurrent accesses superfluous.)
❑ IRQ_LEVELis used on Alpha and PowerPC to differentiate level-triggered and edge-triggered
IRQs.
❑ IRQ_REPLAYmeans that the IRQ has been disabled but a previous interrupt has not yet been
acknowledged.
❑ IRQ_AUTODETECTandIRQ_WAITINGare used for the automatic detection and configuration of
IRQs. I will not discuss this in more detail, but mention that the respective code is located in
kernel/irq/autoprobe.c.
❑ IRQ_NOREQUESTis set if the IRQ can be shared between devices and must thus not be exclusively
requested by a single device.

Using the current contents ofstatus, it is easy for the kernel to query the status of a certain IRQ with-
out having to know the hardware-specific features of the underlying implementation. Of course, just
settingthe corresponding flags does not produce the desired effect. Disabling an interrupt by setting the
IRQ_DISABLEDflag is not possible. The underlying hardware must also be informed of the new state. Con-
sequently, the flags may be set only by controller-specific functions that are simultaneously responsible
for making the required low-level hardware settings. In many cases, this mandates the use of assembly
language code or the writing of magic numbers to magic addresses by means ofoutcommands.

Finally, the fieldsirq_countandirq_unhandledofirq_descprovide some statistics that can be used
to detect stalled and unhandled, but permanently occurring interrupts. The latter ones are usually called
spurious interrupts. I will not discuss how this is done in more detail.^7

IRQ ControllerAbstraction


handleris an instance of thehw_irq_controllerdata type that abstracts the specific characteristics of
an IRQ controller for the architecture-independent part of the kernel. The functions it provides are used
to change the status of an IRQ, which is why they are also responsible for settingflag:

<irq.h>
struct irq_chip {
const char *name;
unsigned int (*startup)(unsigned int irq);
void (*shutdown)(unsigned int irq);
void (*enable)(unsigned int irq);
void (*disable)(unsigned int irq);

void (*ack)(unsigned int irq);
void (*mask)(unsigned int irq);
void (*mask_ack)(unsigned int irq);
void (*unmask)(unsigned int irq);
void (*eoi)(unsigned int irq);

(^7) If you are interested in how this detection is performed, see the functionnote_interruptinkernel/irq/spurious.c.

Free download pdf