Skip to content

Day67 - Workqueue Fundamentals

Date

2026-06-02


Objectives

Learn Linux Workqueue fundamentals and understand how deferred execution moves work from interrupt context into sleepable process context.

Topics covered:

  • Why deferred execution exists
  • IRQ Context vs Process Context
  • Workqueue architecture
  • Delayed Work
  • Workqueue lifecycle
  • Workqueue cleanup APIs
  • Workqueue vs Threaded IRQ
  • Workqueue vs Kernel Thread

What I Learned

Deferred Execution

Interrupt handlers should complete as quickly as possible.

Hard IRQ Context cannot:

  • Sleep
  • Schedule
  • Acquire mutexes
  • Perform long-running operations

To perform operations that require a sleepable context, Linux provides deferred execution mechanisms.

Common approaches include:

  • Threaded IRQ
  • Workqueue
  • Kernel Thread

Workqueue Architecture

A Workqueue provides a mechanism for scheduling background jobs to run in process context.

Basic workflow:

IRQ
schedule_work()
Workqueue
kworker thread
Work Handler

Work handlers execute in process context and may:

  • Sleep
  • Acquire mutexes
  • Access I2C/SPI devices
  • Allocate memory with GFP_KERNEL

system_wq vs alloc_workqueue()

Linux provides a default global workqueue:

schedule_work(&work);

Equivalent to:

queue_work(system_wq, &work);

For driver-specific workloads:

alloc_workqueue(...)

creates a private workqueue and worker pool.

Advantages:

  • Isolation from global worker activity
  • Independent lifecycle management
  • Better control over concurrency

Delayed Work

Delayed Work combines:

Timer
+
Workqueue

Instead of immediate execution:

schedule_work(...)

Delayed execution can be scheduled:

schedule_delayed_work(...)

or rescheduled:

mod_delayed_work(...)

Typical use cases:

  • Retry mechanisms
  • Debounce handling
  • Periodic monitoring
  • State machine timeouts

Workqueue Cleanup

Workqueue cleanup APIs are important during driver removal.

Common APIs:

cancel_work_sync()

cancel_delayed_work_sync()

flush_workqueue()

destroy_workqueue()

Key understanding:

cancel_*_sync()

may block until currently running work handlers complete.

Therefore these APIs must be called only from sleepable contexts.


Driver Remove Sequence

Typical safe shutdown flow:

disable_irq()
cancel_work_sync()
cancel_delayed_work_sync()
destroy_workqueue()
free_irq()
release resources

This prevents use-after-free issues caused by pending work items.


Workqueue vs Threaded IRQ

Threaded IRQ:

IRQ
IRQ Thread
Handle Event
Return

Best suited for:

  • Immediate interrupt processing
  • I2C/SPI transactions triggered by interrupts
  • Short operations

Workqueue vs Kernel Thread

Workqueue:

Background Job

Kernel Thread:

Long-lived Service

Workqueue is event-driven.

Kernel threads are suitable for:

  • State machines
  • Monitoring services
  • Reclaimers
  • Connection managers
  • Protocol engines

Key Takeaways

  • Workqueue is a deferred execution mechanism.
  • Work handlers execute in process context.
  • Delayed Work combines timers and workqueues.
  • Private workqueues isolate driver workloads from system workqueues.
  • Workqueue is intended for jobs, not permanent services.
  • Kernel threads are a better fit for long-lived state machines.
  • Threaded IRQ, Workqueue, and Kernel Threads all move work into sleepable contexts, but serve different purposes.

Next Steps

Day68:

  • Kernel Thread Fundamentals
  • kthread_run()
  • kthread_should_stop()
  • wait_event()
  • wake_up_process()
  • Long-lived service design
  • State machine execution patterns