Skip to content

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:

  1. Register the driver's wait queue.
  2. 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 .poll callback 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.