Skip to content

Day68 - Kernel Thread Fundamentals

Summary

Today focused on Linux kernel threads (kthread) and how they differ from workqueues and threaded IRQ handlers.

The goal was not simply to learn the APIs, but to understand the role of kernel threads as long-lived event-loop execution contexts for driver state machines and protocol processing.

Key topics included:

  • Kernel thread lifecycle
  • kthread_run()
  • kthread_should_stop()
  • kthread_stop()
  • Wait queues
  • wait_event()
  • wake_up()
  • wait_event_timeout()
  • Event-driven thread design
  • State machine integration

A simple kernel module was implemented to create a kernel thread and later evolved into an event-driven architecture using wait queues and sysfs-triggered events.


What I Learned

Workqueue vs Kernel Thread

A workqueue executes individual jobs and returns when the work function completes.

A kernel thread is a long-lived execution context that continuously waits for events and processes state transitions.

Conceptually:

Workqueue
    = Job Execution

Kernel Thread
    = Event Loop

Kernel threads are more suitable when implementing protocol stacks, connection managers, retry logic, and state machines.


Kernel Thread Lifecycle

A kernel thread is typically created during module initialization:

kthread_run(...)

The thread executes until:

kthread_should_stop()

becomes true.

Module cleanup requests termination through:

kthread_stop(...)

Unlike process termination, kthread_stop() does not forcibly kill the thread. It sets a stop flag, wakes the thread if necessary, and waits until the thread exits.


Wait Queue Integration

Replacing polling with wait queues significantly improves efficiency.

Instead of:

while (...)
    msleep(...)

the thread can sleep until work becomes available:

wait_event(...)

and producers can wake the thread through:

wake_up(...)

This is conceptually similar to RTOS tasks waiting on semaphores or event objects.


wait_event_timeout()

wait_event_timeout() allows a thread to wake up when:

  • an event occurs
  • a timeout expires

Return value behavior:

ret > 0
    Condition became true

ret == 0
    Timeout occurred

This differs from many Linux APIs where zero usually indicates success.


State Machine Design

A simple state machine was implemented:

IDLE
    ↓ trigger

PROCESSING
    ↓ timeout

IDLE

The exercise demonstrated how a kernel thread naturally becomes the execution engine of a state machine while wait queues provide event-driven scheduling.


Architecture Comparison

Feature Threaded IRQ Workqueue Kernel Thread
Process Context Yes Yes Yes
Sleep Allowed Yes Yes Yes
Dedicated Thread IRQ-specific No Yes
Long-lived State Machine Limited Moderate Excellent
Event Loop Design No No Yes
Background Service Pattern No Limited Yes

Key Takeaways

  • Workqueues are designed for deferred jobs.
  • Kernel threads are designed for long-lived event loops.
  • Wait queues provide efficient event-driven scheduling.
  • wait_event_timeout() is useful for timeout-driven state transitions.
  • State machines should avoid blocking for long periods.
  • Kernel threads are often the foundation of protocol managers and complex driver logic.

Next Steps

Day69 will introduce Completion synchronization primitives.

Topics:

  • struct completion
  • init_completion()
  • complete()
  • wait_for_completion()
  • wait_for_completion_timeout()
  • Completion vs Wait Queue
  • Typical driver synchronization patterns