ยง36.4โ€“36.7Lowering CPU Overhead With Interrupts โ€ฆ Fitting Into The OS: The Device Driver

Part III OSTEP pp. 423โ€“426 ยท ~6 min read

  • interrupt
  • interrupt handler
  • interrupt coalescing
  • direct memory access
  • memory-mapped i/o

Polling burns the CPU. The fix is an old friend from the process chapters: the interrupt.

36.4 Lowering CPU Overhead With Interrupts

Instead of polling, the OS issues the request, puts the process to sleep, and context-switches to other work. When the device finishes it raises a hardware interrupt , and the CPU jumps into an OS interrupt handler (ISR) that completes the request and wakes the waiting process. This lets computation and I/O overlap:

With interrupts, the CPU overlaps other work with slow I/O. (Without them, the CPU would just spin polling in ticks 2โ€“3.)
t =
CPU
Disk
tick 1 / 5 ยท time โ†’Process 1Process 2serving I/Odone โ†’ interruptDMA copyidle

Process 1 issues an I/O request; the OS puts it to sleep โ€” no polling needed.

Tip: Interrupts Are Not Always Better Than Polling

Interrupts win for slow devices. For a fast one, the first poll usually finds it already done โ€” and the cost of sleeping, handling the interrupt, and switching back outweighs the benefit, so polling is better. A flood of interrupts (e.g. a burst of network packets) can even livelock the system โ€” only ever handling interrupts, never running user code โ€” where polling regains control. If speed varies, a hybrid (poll briefly, then switch to interrupts) can be best. Another trick, interrupt coalescing , delays an interrupt briefly so several completions batch into one delivery โ€” lower overhead, slightly more latency.

36.5 More Efficient Data Movement With DMA

Interrupts fix polling, but PIO still wastes the CPU copying data by hand. Direct Memory Access (DMA) is a dedicated engine that copies data between device and memory without the CPU: the OS tells it what to move, where, and to which device, then does other work; the DMA controller raises an interrupt when done.

DMA offloads the data COPY too: a dedicated engine moves data memoryโ†”device while the CPU runs another process.
t =
CPU
DMA engine
Disk
tick 1 / 5 ยท time โ†’Process 1Process 2serving I/Odone โ†’ interruptDMA copyidle

Process 1 wants to write to disk. With PIO the CPU would copy every word by hand โ€” instead it programs the DMA engine and moves on.

36.6 Methods Of Device Interaction

How does the OS actually reach a deviceโ€™s registers? Two methods evolved โ€” and the second one, memory-mapped I/O , needs no special instructions at all:

Two ways for the OS to reach a device's registers โ€” both still in use.
how it worksexample
Explicit I/O instructionsspecial privileged instructions name a device port and move data to/from its registersx86 in / out (register โ†” port)
Memory-mapped I/Odevice registers appear as memory addresses; the OS reads/writes them with ordinary load/store, and the hardware routes the access to the deviceload / store to a mapped address
Dotted-underlined cells have explanations โ€” click one.

36.7 Fitting Into The OS: The Device Driver

Devices have wildly different interfaces; the OS wants to stay device-neutral. The fix is abstraction: the low-level device specifics live in a device driver , and higher layers issue generic block reads/writes that get routed to the right driver:

Figure 36.4: the Linux file-system stack. A file system (and the app above) is oblivious to which disk itโ€™s using โ€” it just issues block reads/writes.

ApplicationPOSIX API [open, read, write, close]userkernelFile SystemRawGeneric Block Interface [block read/write]Generic Block LayerSpecific Block Interface [protocol-specific read/write]Device Driver [SCSI, ATA, โ€ฆ]specifics hidden here โ†’ the rest of the OS stays device-neutral

The stack also exposes a raw interface, letting tools like a disk defragmenter or file-system checker read/write blocks directly. Abstraction has costs, though: special device features get flattened away (SCSIโ€™s rich errors collapse to a generic EIO). And drivers are huge โ€” over 70% of Linux kernel code is device drivers, and, often written by non-experts, theyโ€™re a top source of kernel crashes.

Check yourself: interrupts, DMA, and drivers

1.How do interrupts improve on polling for a slow device?

2.When is polling actually BETTER than interrupts?

3.What does DMA (Direct Memory Access) offload, and how?

4.What's the difference between explicit I/O instructions and memory-mapped I/O?

5.What role does a device driver play in the OS?

6.What is interrupt coalescing, and its trade-off?

6 questions