Task 2: AI-Assisted Linux Interrupt Understanding
What is an interrupt?
An interrupt is an event that alters the normal execution flow of a program and can be generated by hardware devices or by the CPU itself. When an interrupt occurs, the current flow of execution is suspended and an interrupt handler runs. After the interrupt handler runs, the previous execution flow is resumed.
Interrupts can be grouped into categories based on source and maskability:
- synchronous: generated by executing an instruction
- asynchronous: generated by an external event
- maskable
- can be ignored/postponed
- signaled via INT pin
- non-maskable
- cannot be ignored
- signaled via NMI pin
Synchronous interrupts (usually called exceptions) handle conditions detected by the processor during instruction execution. Divide-by-zero and system call related events are examples.
Asynchronous interrupts are external events generated by I/O devices. For example, a network card can generate an interrupt to signal packet arrival.
Most interrupts are maskable, meaning handling can be postponed while interrupts are disabled and resumed later. However, some critical interrupts cannot be disabled/postponed.
Exceptions
There are two sources for exceptions:
- processor-detected
- faults
- traps
- aborts
- programmed
- int n
Processor-detected exceptions are raised when an abnormal condition is detected while executing an instruction.
A fault is reported before instruction completion and can usually be corrected. The saved EIP/RIP points to the faulting instruction, so execution may retry that instruction after correction (e.g., page fault).
A trap is reported after instruction completion. The saved EIP/RIP points to the next instruction after the one that caused the trap (e.g., debug trap).
Question
Quiz: For each item, think about which labels apply: Exception, Interrupt, Maskable, Nonmaskable, Trap, Fault.
- Watchdog
- Demand paging
- Division by zero
- Timer
- System call
- Breakpoint
Hardware Concepts
Programmable Interrupt Controller
A device that supports interrupts has an output pin for signaling an Interrupt Request (IRQ). IRQ pins connect to a Programmable Interrupt Controller (PIC), and PIC connects to the CPU INTR pin.
A PIC usually has ports used to exchange information with the CPU. When a device on an IRQ line needs CPU attention, a high-level flow is:
- Device raises interrupt on IRQn.
- PIC converts IRQ to a vector number.
- PIC raises interrupt on CPU INTR.
- PIC waits for CPU acknowledgment before raising the next interrupt.
- CPU acknowledges and starts handling the interrupt.
Once an interrupt is acknowledged, the controller can request another interrupt even if previous handling has not fully completed, so nested interrupts are possible depending on OS control.
The interrupt controller can disable each IRQ line individually, helping ensure serialized execution for selected handlers.
Interrupt controllers in SMP systems
In SMP systems, there can be multiple controllers. On x86, each core has a local APIC for local interrupts (e.g., timers, thermal sensors), while I/O APIC distributes external IRQs to CPU cores.
Interrupt Control
To synchronize shared data between interrupt handlers and concurrent code paths (driver init/processing), interrupts are enabled/disabled in a controlled way.
This can be done at multiple levels:
- device level
- program device control registers
- PIC/controller level
- disable a specific IRQ line
- CPU level
- on x86, classic instructions include:
cli(clear interrupt flag)sti(set interrupt flag)
- on x86, classic instructions include:
Interrupt priorities
Most architectures support interrupt priorities. When enabled, nested interrupts are typically allowed only for interrupts with higher priority than the current priority level.
Interrupt handling on x86 architecture
Interrupt Descriptor Table (IDT)
On x86, each interrupt/exception vector maps to an IDT entry (gate). The IDT is used by the CPU as a jump table to find the corresponding handler.
Key points:
- vector space has 256 entries
- low vectors are generally reserved for exceptions
- a dedicated vector is used for the syscall interface
- the CPU locates the IDT via
IDTR
Gate types and handler address
Common x86 gate types:
- interrupt gate: enters handler and clears IF (maskable interrupts disabled)
- trap gate: enters handler without clearing IF
- task gate: generally not used in Linux fast-path interrupt handling
Handler target is computed from segment selector + offset fields in the gate descriptor.
Interrupt stack frame and return
On entry, CPU saves execution state on stack (e.g., flags and return address fields). Some exceptions also push an error code.
On return, x86 uses iret/iretq to restore saved state and resume interrupted execution.
If privilege level changed on entry, return also restores prior privilege/stack context.
High-level request handling sequence
When an interrupt/exception is taken, CPU performs a sequence that includes:
- checking privilege transition needs
- switching stack if required
- saving return state
- transferring control to the selected handler
Interrupt handling in Linux
Linux handling is often explained in phases:
- critical entry/dispatch phase
- immediate device-handler phase
- deferred phase for non-urgent work
In early phases, local interrupt state is tightly controlled to protect critical handling. Later, deferred execution improves latency and throughput.
Interrupt context
Code running between interrupt entry and return is in interrupt context. Important properties:
- not associated with a normal user process context
- should not sleep or perform operations that require scheduling
- should keep work short and deterministic
Shared interrupts and generic dispatch
One IRQ line may be shared by multiple devices.
Generic IRQ code dispatches the line to registered actions (irqaction) under descriptor control (irq_desc).
This is where handler chains and per-line flow handlers are coordinated.
Deferrable work
Linux defers non-critical work out of hard IRQ handling. Common mechanisms include:
- softirq/tasklet style bottom-half execution
- threaded interrupt handlers
- workqueues (process context)
Timers
Timer events are a canonical interrupt-driven workload. Architecture entry and generic IRQ dispatch eventually connect to timer framework callbacks, which then drive periodic time accounting and scheduled timer callbacks.
Question
Task: Use AI tools plus source reading to recover the complete interrupt-related function path for this scope:
- Start function (init/main.c):
trap_init() - Target vector:
X86_TRAP_NMI
You must identify relevant functions on this path and explain each function's concrete role with source evidence.
Required output
Create task2/interrupt_flow.md with:
-
Prompt LogAt least 3 prompts used for AI-assisted code navigation. -
Verified Function PathA function chain fromtrap_init()to end (at least 8 steps) -
Function NotesFor every function in your chain, write 1-3 sentences about what it does in this specific flow. -
Short SummaryNo more than 250 words summarizing the whole flow in your own words.
Rules
- AI may help search/summarize/propose candidate paths.
- You must verify all key claims from source code.
- Do not submit AI-generated code.