Skip to content

Workqueue Internals

Overview

Workqueue is a kernel mechanism that executes deferred work in process context.

Unlike interrupt context, workqueue callbacks can:

  • Sleep
  • Acquire mutexes
  • Perform blocking I/O
  • Execute long-running operations

Typical flow:

IRQ Handler
schedule_work()
Workqueue
Worker Thread
Work Function

Why Workqueue Exists

Interrupt handlers should execute quickly and must not sleep.

Instead of performing heavy processing inside an interrupt handler:

IRQ
schedule_work()
Deferred Processing

This moves the work into process context.


Core Components

A Linux workqueue can be viewed as:

work_struct
workqueue
worker_pool
worker
work function

work_struct

Represents a deferred work item.

Contains:

  • Work callback
  • State information
  • Queue linkage

Workqueue

Represents a queue of pending work items.

Responsibilities:

  • Store pending work
  • Dispatch work to workers
  • Manage synchronization

Worker Pool

Modern Linux workqueues use worker pools.

Worker Pool
    ├─ Worker-1
    ├─ Worker-2
    ├─ Worker-3
    └─ Worker-4

Benefits:

  • Parallel execution
  • Better CPU utilization
  • Reduced latency

System Workqueue

Linux provides shared workqueues.

Most drivers use:

schedule_work(&work);

instead of creating dedicated workqueues.

Conceptually:

schedule_work()
queue_work(system_wq, work)

This reduces thread creation overhead.


Work Lifecycle

A work item transitions through multiple states.

IDLE
PENDING
RUNNING
IDLE

IDLE

The work item is not scheduled.

PENDING

The work item is waiting in a workqueue.

RUNNING

A worker thread is executing the callback.


Duplicate Scheduling Prevention

The same work item must not be queued multiple times.

Typical logic:

if (work->pending || work->running)
    return false;

This prevents duplicate execution.


Work Synchronization

flush_work()

Wait until a specific work item completes.

flush_work(&work);

flush_workqueue()

Wait until all work items complete.

flush_workqueue(wq);

cancel_work_sync()

Cancel a pending work item or wait for a running work item.

Behavior:

State Action
PENDING Remove from queue
RUNNING Wait for completion
IDLE Return immediately

Workqueue vs kthread

Item Workqueue kthread
Thread Creation Kernel managed Driver managed
Sleepable Yes Yes
Deferred Work Excellent Possible
Long-running Loop Not ideal Excellent
Resource Management Simple Flexible

Workqueue vs Threaded IRQ

Item Threaded IRQ Workqueue
Trigger Source IRQ Software
Execution Context Process Context Process Context
Sleepable Yes Yes
Typical Usage Interrupt processing Deferred work

  • Day80 - IRQ Bottom Half and Deferred Work
  • Day81 - Workqueue Internals
  • schedule_work()
  • queue_work()
  • flush_work()
  • flush_workqueue()
  • cancel_work_sync()