Wait Queue and poll Support¶
Linux poll() provides an event-driven mechanism that allows user-space applications to wait for I/O readiness without repeatedly polling the driver.
The poll subsystem is built on top of wait queues. A driver registers its wait queue through poll_wait(), while the poll framework sleeps until the wait queue is awakened.
Overall Flow¶
Userspace poll()
↓
VFS calls driver .poll()
↓
driver calls poll_wait(file, &wq, wait)
↓
Driver checks current device state
↓
No event?
│
├── Yes
│ ↓
│ Sleep
│ ↓
│ wake_up()
│ ↓
│ Driver .poll() again
│
└── No
↓
Return event mask
poll_table¶
Each poll() operation owns one poll_table.
The poll table records every wait queue that the current poll operation is interested in.
poll_table
│
├── poll_table_entry
│ │
│ ▼
│ wait_queue_head (read)
│
├── poll_table_entry
│ │
│ ▼
│ wait_queue_head (write)
│
└── ...
poll_wait() simply adds a wait queue into the current poll table.
It does not put the task to sleep.
Driver poll Callback¶
A typical driver implements the .poll callback.
static __poll_t mydev_poll(struct file *file, poll_table *wait)
{
struct mydev_data *data = file->private_data;
__poll_t mask = 0;
poll_wait(file, &data->wq, wait);
if (!queue_empty(data))
mask |= EPOLLIN | EPOLLRDNORM;
return mask;
}
The callback performs two independent operations:
- Register the driver's wait queue.
- Report the current readiness state.
Readiness Rule¶
The .poll callback should always report the current device state.
| Driver State | Return Mask |
|---|---|
| No data available | 0 |
| Data available | EPOLLIN \| EPOLLRDNORM |
| Error condition | EPOLLERR |
| Device disconnected | EPOLLHUP |
The same readiness condition should also be used by the driver's read() implementation.
Relationship with Wait Queues¶
The interaction between poll() and wait queues is:
poll()
↓
driver .poll()
↓
poll_wait()
↓
wait_queue_head
↓
wait_event()
↓
wake_up()
↓
driver .poll()
↓
Return POLLIN
Notice that:
poll_wait()only registers a wait queue.wait_event()performs the actual sleep.wake_up()only wakes waiting tasks.- The driver
.pollcallback determines whether the file descriptor is ready by returning an event mask.
Common Pitfalls¶
Warning
poll_wait() never blocks. It only records the wait queue associated with the current poll operation.
Warning
A wakeup does not automatically make the file descriptor readable. The driver must return the appropriate event mask after wakeup.
Warning
Always re-check the device state after wakeup. A wakeup only indicates that the state may have changed.
Warning
The readiness condition used by .poll() and read() should remain consistent. Otherwise, poll() may report readable data while read() still returns -EAGAIN.
Related Labs¶
- Day12 - Poll Driver
- Day15 - User-space Poll Lab
- Day50 - Pollable Character Driver
- Day51 - Timer-based Pollable Driver
- Day84 - Wait Queue Internals
- Day85 - poll() Internals