Understanding Linux Tasklet and Workqueue Mechanisms: A Deep Dive
This article explains why the Linux kernel introduced the tasklet mechanism, details its core data structures and execution flow, and then compares it with the workqueue system, covering creation, scheduling, and processing of work items in kernel space.
Tasklet Mechanism Analysis
The Linux kernel adds the tasklet mechanism because soft‑interrupts have a limited 32‑bit pending flag and lack a generic interface for adding new handlers; tasklet provides a reusable, re‑entrant mechanism that cannot sleep and runs on a single CPU at a time.
Key characteristics of tasklets are that they cannot sleep, a single tasklet cannot run on two CPUs simultaneously, but different tasklets may run concurrently on different CPUs, requiring careful protection of shared data.
Main data structures
static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);How to Use Tasklet
Using a tasklet is straightforward: initialize a struct tasklet_struct and call tasklet_schedule to execute the associated function.
The tasklet_schedule routine simply links the tasklet_struct into either tasklet_vec or tasklet_hi_vec and triggers the soft‑interrupt TASKLET_SOFTIRQ or HI_SOFTIRQ.
Tasklet Execution Process
When the soft‑interrupt TASKLET_SOFTIRQ fires, tasklet_action extracts each tasklet_struct from tasklet_vec and runs its function. If t->count is zero, the tasklet was disabled after scheduling; it is placed back into the list and the interrupt is re‑triggered, to be executed again after the tasklet is re‑enabled.
Linux Workqueue
Workqueues were introduced because tasklet callbacks cannot sleep and have other restrictions. Workqueue handlers run in process context, allowing sleeping operations, though they sacrifice the real‑time responsiveness of tasklets.
Data Structure Description
The primary structures are struct workqueue_struct (the queue itself) and struct cpu_workqueue_struct (per‑CPU management). Each work item is represented by struct work_struct.
The relationship among these structures is illustrated in the following diagram:
Workqueue Creation
Creating a workqueue involves allocating workqueue_struct and cpu_workqueue_struct objects, initializing the per‑CPU structures in init_cpu_workqueue, and spawning a kernel thread via create_workqueue_thread.
Inside create_workqueue_thread the kernel thread is created with:
p = kthread_create(worker_thread, cwq, fmt, wq->name, cpu);After creation, start_workqueue_thread starts the thread.
Adding Work to the Queue
The schedule_work function enqueues a work item; its implementation is a straightforward series of list operations.
Workqueue Kernel Thread Processing
When a workqueue is created, one or more kernel threads run the worker_thread function. This thread runs at a lowered priority, so under heavy system load the execution of queued work may experience noticeable latency.
The processing flow simply removes a work item from the queue, clears its pending flag, and invokes the callback defined in the work_struct.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
