Everything comes together. This is the camera frame pipeline in miniature.
Drivers 01–05 each taught one concept. This one combines all of them into a single working pipeline: a kernel timer generates events, a workqueue processes them safely, a ring buffer stores them, and userspace can read via blocking read, non-blocking read, or poll(). It's a minimal but real model of how a camera driver feeds frames to an application.
timer_callback() /* softirq — fires every 1000ms */
└─ schedule_work()
└─ workqueue_fn() /* process context */
├─ spin_lock_irqsave
├─ snprintf → ring buffer
├─ advance write_indexer, update count
├─ spin_unlock_irqrestore
└─ wake_up_interruptible
├─ unblocks blocking read()
└─ signals poll() waitersUnlike driver 02 which used mutex, here poll() must use a spinlock — the workqueue holds a spinlock when updating count, so anything that reads count must use the same lock.
static __poll_t etx_poll(struct file *filp, poll_table *wait)
{
unsigned long flags;
__poll_t mask = 0;
poll_wait(filp, &etx_wait_queue, wait);
spin_lock_irqsave(&kernel_logger.lock, flags);
if (kernel_logger.count > 0)
mask = POLLIN | POLLRDNORM;
spin_unlock_irqrestore(&kernel_logger.lock, flags);
return mask;
}| Pattern | What userspace does | What the driver does |
|---|---|---|
| Blocking read | Calls read(), goes to sleep | Wakes it when data arrives |
| Non-blocking read | Calls read() with O_NONBLOCK | Returns EAGAIN if empty |
| poll() | Waits on fd with timeout | Returns POLLIN when buffer has data |