Device Drivers & Kernel Modules

polling versus interrupt-driven I/O

There are two ways a driver can find out when a device is ready. Polling is like repeatedly opening the oven to check if the cake is done: the CPU loops, reading the device's status register over and over, asking 'ready yet? ready yet?' until the answer is yes. Interrupt-driven I/O is like setting a timer that rings when the cake is done: the CPU sets the device up, walks away to do other work, and the device raises an interrupt the moment it is ready.

Concretely, in polling the driver runs a loop like while (!(readl(base + STATUS) & DONE_BIT)) ; spinning until the bit flips. This wastes every CPU cycle spent spinning, but it has zero interrupt latency and no setup overhead, so it can be the fastest option when the wait is extremely short or extremely frequent. In interrupt-driven I/O, the driver registers an IRQ handler and yields the CPU; when the device finishes, the hardware interrupt fires, the handler runs, and the work resumes. This frees the CPU during the wait but pays the cost of taking an interrupt (a context switch into the handler) each time — which becomes painful when events arrive in a flood, say millions of packets per second.

The trade-off matters because picking wrong wrecks performance: polling a slow, rare device pins a CPU core doing nothing useful, while taking an interrupt per packet on a 10-gigabit link can collapse under the interrupt rate (this is sometimes called an interrupt storm or livelock). That is exactly why the hybrid approach NAPI exists: take an interrupt to learn that work has arrived, then turn interrupts off and poll to drain the backlog cheaply, switching back to interrupts when the device goes quiet. Neither pure approach is 'better' — the right choice depends on event rate and latency needs.

// polling: burns CPU, but zero latency, no setup while (!(readl(base + STATUS) & DONE_BIT)) ; // spin until ready // interrupt-driven: free the CPU, pay per-event cost request_irq(irq, my_isr, 0, "dev", dev); // wake on signal // NAPI: interrupt once, then poll to drain the backlog

Polling trades CPU for low latency; interrupts free the CPU but cost per event. NAPI blends both.

Neither is universally better: polling wastes cycles on rare events but wins for very frequent or latency-critical ones; interrupts win for infrequent events but can livelock under a flood. Match the method to the event rate.

Also called
polling vs interruptsbusy-wait vs IRQ輪詢與中斷