Link

Interrupt

Table of contents

  1. Exceptions
    1. Triple Fault
  2. Interrupts
    1. Issue an IRQ
    2. Interrupt in SMP Architecture
    3. IRQ sharing
  3. Gates
  4. Deferrable Functions
    1. Bottom Half (BH)
    2. Softirq
    3. Tasklet
    4. Work Queue
  5. Syscall

Interrupts are often divided into synchronous and asynchronous interrupts:

 synchronousasynchronous
produced byCPU control unitother hardware devices
also referred to asexceptionsinterrupts

Classification:

  • Exception
    • Processor-detected exceptions
      • Faults: when the exception handler terminates, restart the instruction that caused the exception.
      • Traps: on the contrary, there is no need to reexecute the instruction that terminated
      • Aborts: the handler has no choice but to force the affected process to terminate
    • Programmed exceptions (also known as software interrupts): e.g., int, int3, into (check for overflow), bound
  • Interrupt
    • Maskable interrupts
    • Nonmaskable interrupts (as referred to as NMI)

Exceptions

# ExceptionSignal
0 Divide error Exception handlerSIGFPE
1 DebugSIGTRAP
2 NMINone
3 BreakpointSIGTRAP
4 OverflowSIGSEGV
5 Bounds checkSIGSEGV
6 Invalid opcodeSIGILL
7 Device not availableNone
8 Double faultNone
9 Coprocessor segment overrunSIGFPE
10 Invalid TSSSIGSEGV
11 Segment not presentSIGBUS
12 Stack segment faultSIGBUS
13 General protectionSIGSEGV
14 Page FaultSIGSEGV
15 Intel-reservedNone
16 Floating-point errorSIGFPE
17 Alignment checkSIGBUS
18 Machine checkNone
19 SIMD floating pointSIGFPE

Triple Fault

  • an interrupt => not set up to handle
  • a general protection exception => can not handle
  • a double fault exception => can not handle
  • give up, reboot

It’s used in some legacy machine to switch from protected mode back to real mode in a very fast way:

lidt -1  # sets the interrupt descriptor table to an invalid physical address
int 1    # the IDT couldn't be found, raise an exceptions

Interrupts

Issue an IRQ

Each hardware device controller capable of issuing interrupt requests usually has a single output line designated as the Interrupt ReQuest (IRQ) line. This line is connected to the Programmable Interrupt Controller (PIC). When a signal is raised, the PIC:

  1. Stores the raised signal vector in an I/O port (Intel’s default vector associated with IRQn is n+32)
  2. raised signal to the processor INTR pin
  3. Waits until the CPU acknowledges the interrupt signal by writing into one of the PIC I/O ports.

Interrupt in SMP Architecture

We need I/O Advanced Programmable Interrupt Controller (I/O APIC) and a local APIC at each processor. Each local APIC has:

  • an internal clock
  • a local timer device
  • two additional IRQ lines, LINT0 and LINT1 for local APIC interrupt. These registers allow CPUs in multi-APIC system to generate interprocessor interrupts (IPI).
  • Interrupt Command Register (ICR): used for IPI

The local APIC and the I/O APIC are connected by Interrupt Controller Communication (ICC) bus.

By default, distributing interrupts among processors in a round-robin fashion. It uses a technique called arbitration.

Depending on the type of interrupt, acknowledging the interrupt could either be done by the ack method or delayed until the interrupt handler terminates. 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. This leads to a simpler kernel architecture because device drivers’ interrupt service routines need not to be reentrant (their execution is serialized).

/proc/interrupt tells us the number of interrupts per IRQ on the x86 architecture. The first column refers to the IRQ number. Each CPU in the system has its own column and its own number of interrupts per IRQ.

Every local APIC has a programmable task priority register (TPR), which is used to compute the priority of the currently running process. You can adjust the which CPUs each of those IRQs will be handled by modifying /proc/irq/IRQ_NUMBER/smp_affinity for each IRQ number and the OS will set the TPR accordingly.

IRQ sharing

Kenel simply invokes all the handlers that registered for the same shared IRQ. Each tim ea device registers for a IRQ line, it needs to explicitly say whether it supports interrupt sharing. It is up to the handlers to filter spurious invocations.

Gates

Deferrable Functions

Bottom Half (BH)

A bottom half is essentially a high-priority tasklet that cannot be executed concurrently with any other bottom half, even if it is of a different type and on another CPU. The global_bh_lock spin lock is used to ensure that at most one bottom half is running.

The BH concept is outdated.

Softirq

Although the kernel supports up to 32 softirq, only 6 of them are effectively used (from index 0 to 5):

  • HI_SOFTIRQ: high-priority tasklet
    • All the BH in the old model have been reimplemented to run as HI_SOFTIRQ
  • TIMER_SOFTIRQ
  • NET_TX_SOFTIRQ
  • NET_RX_SOFTIRQ
  • SCSI_SOFTIRQ: Post-interrupt processing of SCSI commands
  • TASKLET_SOFTIRQ: low-priority tasklet

Sofirq can run concurrently on several CPUs, even if they are of the same type. Thus, they need spinlock to proctect the data. The only restriction on concurrency is that only one instance of each softirq can run at the same time on a CPU.

Up to 10 softirq are processed when do_softirq() is called. The remaining softirq is processed by the kernel thread ksoftirq/n. There are several softirq chceckpoints:

  • local_bh_enabled() is called
  • after handing a local timer interrput
  • in the schedule() function, before deciding what to execute next on the CPU.

Tasklet

Tasklets are implemented on the top of softirqs. Tasklets of different types can run concurrently on several CPUs, but tasklets of the same type cannot. It can be dynamically allocated.

Work Queue

The main difference between work queues and others deferrable functions is that it run in process context. Running in process context is the only way to execute functions that can block, while no process switch can take place in interrupt context.

Use create_workqueue(foo) to create a work queue and n thread threads named foo/0, foo/1. The kernel offers a predefined work queue named events. Noted that work function can be put to sleep and even migrated to another CPU when resumed.

Syscall