Skip to content

Day51 - Timer-Based Pollable Event Driver

Objective

Extend the Day50 pollable character driver into a timer-driven asynchronous event framework.

Features implemented:

  • delayed_work periodic event source
  • timer start/stop commands
  • manual trigger events
  • runtime statistics
  • queue overflow tracking
  • sysfs runtime status
  • epoll integration

Lab 1 - Refactor Event Generation Helper

Goal

Move event generation into a shared helper function.


Implementation

Create shared helper:

static int mypoll_generate_event(struct mypoll_dev *mydev,
                                 enum mypoll_event_source source)

Responsibilities:

  • generate sequence number
  • queue push
  • overflow handling
  • statistics update
  • wait queue wakeup

Lab 2 - Add delayed_work Timer Event Source

Goal

Generate periodic events inside the driver.


Device Structure

Add:

struct delayed_work event_work;
unsigned int event_interval_ms;
bool event_running;

Work Handler

static void mypoll_event_work_handler(struct work_struct *work)
{
    ...
}

Responsibilities:

  • generate timer event
  • re-schedule delayed_work

Initialization

INIT_DELAYED_WORK(&mydev->event_work,
                  mypoll_event_work_handler);

Cleanup

cancel_delayed_work_sync(&mydev->event_work);

Lab 3 - Add Control Commands

Goal

Control timer behavior from userspace.


Supported Commands

Command Description
start Start periodic timer
stop Stop periodic timer
trigger Generate one manual event
reset_stats Clear statistics
show_stats Print runtime statistics

Example

echo start > /dev/mypoll
echo stop > /dev/mypoll
echo trigger > /dev/mypoll

Lab 4 - Add Event Source Information

Goal

Differentiate manual and timer events.


Event Source Enum

enum mypoll_event_source {
    MYPOLL_EVENT_SOURCE_MANUAL = 0,
    MYPOLL_EVENT_SOURCE_TIMER,
};

Event Structure

struct mypoll_event {
    u32 sequence;
    enum mypoll_event_source source;
};

Userspace Output

event=35 source=manual
event=36 source=timer

Lab 5 - Add Runtime Statistics

Goal

Track runtime event behavior.


Statistics Structure

struct mypoll_stats {
    u32 events_generated;
    u32 events_dropped;
    u32 events_manual;
    u32 events_timer;
};

Overflow Policy

When queue is full:

queue full
drop new event
increment dropped counter

Lab 6 - Add sysfs Runtime Status

Goal

Expose runtime driver state through sysfs.


sysfs Node

/sys/class/mypoll/mypoll/stats

sysfs Attribute

static DEVICE_ATTR_RO(stats);

Example Output

event_sequence=83
generated=83
dropped=174
manual_triggered=1
timer_triggered=82
queue_depth=0
timer_running=0

Lab 7 - epoll Integration

Goal

Verify that timer events work with epoll.


Userspace Flow

epoll_wait()
EPOLLIN
read()

Result

Timer-generated events successfully wake epoll waiters.


Lab 8 - Python Integration Test

Goal

Automate runtime validation.


Tested Features

  • manual trigger
  • timer events
  • timer stop
  • epoll wakeup
  • queue overflow
  • reset statistics
  • sysfs stats

Example Output

===== Test 5: Queue overflow should increase dropped counter =====
[OK] Overflow observed: dropped=1, queue_depth=16

Final Result

The driver evolved from a simple pollable character device into a reusable asynchronous event framework.

Key concepts learned:

  • delayed_work scheduling
  • asynchronous event flow
  • runtime observability
  • queue overflow handling
  • epoll integration
  • sysfs runtime statistics