Skip to content

Wait Queue and poll Support

A pollable driver allows user space to wait for driver events using poll, select, or epoll. This is the bridge between a kernel event source and a user-space event loop.

Core Idea

The driver does not directly call epoll. Instead, it implements the .poll file operation and registers its wait queue through poll_wait().

user space epoll_wait()
VFS calls driver .poll()
driver calls poll_wait(file, &wq, wait)
IRQ/timer/write event calls wake_up_interruptible()
epoll_wait() returns EPOLLIN

Driver 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;
}

Readiness Rule

The .poll callback should report readiness based on actual driver state.

State Return Mask
Event queue empty 0
Event queue has data EPOLLIN | EPOLLRDNORM
Error condition EPOLLERR
Device hangup EPOLLHUP

Common Pitfalls

Warning

poll_wait() does not sleep by itself. It only registers the wait queue with the poll infrastructure.

Warning

wake_up_interruptible() does not automatically mean the fd is readable. The .poll callback must return a readable mask after wakeup.

Warning

The condition used by .poll and read() should be consistent. Otherwise, epoll may report readiness but read() may still return -EAGAIN unexpectedly.