Chapter 14: Kernel Activities
kernel remembers that another IRQ needs to be served later. After masking the IRQ and sending an
acknowledgment to the controller viamask_ack_irq, processing can be aborted. The second CPU can
thus go back to work as usual, while the first CPU will handle the IRQ later.
Cancel processing
No handler, IRQ in progress or IRQ disabled Set IRQ_PENDING and IRQ_MASKED
Iterate as long as
IRQ_PENDING
is set and IRQ is not disabled
Set IRQ_INPROGRESS
Remove IRQ_PENDING
Handle unmasking
handle_edge_irq
handle_IRQ_event
mask_ack_irq
chip->ack
Figure 14-5: Code flow diagram forhandle_edge_irq.
Note that processing is also aborted if no ISR handler is available for the IRQ or if it is disabled. (Faulty
hardware might nevertheless generate the IRQ, so this case needs to be taken into account by the kernel.)
Now the proper work to handle the IRQ starts. Aftersending an acknowledgment to the interrupt con-
troller with the chip-specific functionchip->ack, the kernel sets theIRQ_INPROGRESSflag. This signals
that the IRQ is being processed and can be used to avoid the same handler executing on multiple CPUs.
Let us assume that only a single IRQ needs to be processed. In this case, the high-level ISR handlers
are activated by callinghandle_IRQ_event,andtheIRQ_INPROGRESSflag can be removed afterward.
However, the situation is more complicated in reality, as the source code shows:
kernel/irq/chip.c
void fastcall
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
...
desc->status |= IRQ_INPROGRESS;
do {
struct irqaction *action = desc->action;
irqreturn_t action_ret;
...
/*
* When another irq arrived while we were handling
* one, we could have masked the irq.
* Renable it, if it was not disabled in meantime.