Completions
A completion (
struct completion) is the Linux kernel’s race-free primitive for the very common pattern “start some work, then block until that work signals it is done.” It is a tiny object — adonecounter plus a wait queue — that closes the window a hand-rolled flag-plus-waitqueue leaves open: the case where the worker finishes before the waiter has gone to sleep. A waiter callswait_for_completion(); the worker callscomplete()(wake one) orcomplete_all()(wake everyone and latch the event permanently). Becausecomplete()may legitimately run beforewait_for_completion(), the design “will work properly even ifcomplete()is called beforewait_for_completion()” (LWN, Completions). The header dates the file to “(C) Copyright 2001 Linus Torvalds — Atomic wait-for-completion handler data structures” (perinclude/linux/completion.hv6.12).
This note pins to the 6.12 long-term-support (LTS) kernel (released 2024-11-17). Parent map: Linux Kernel Synchronization MOC.
Mental Model
Think of a completion as a one-bit (really one-counter) doorbell with memory. The worker rings the bell exactly once when it is done. The waiter either (a) arrives, sees the bell has already rung, and walks straight through without sleeping, or (b) arrives early, finds the bell silent, and sleeps on a wait queue until the bell rings. The “with memory” part is the whole point: an ordinary wake_up() on a wait queue is edge-triggered — if the wakeup fires before anyone is asleep, it is lost. A completion is level-triggered — the done counter records that the event happened, so a late waiter still observes it.
sequenceDiagram participant W as Waiter (consumer) participant C as struct completion<br/>(done counter + wait queue) participant P as Worker (producer) Note over C: init_completion() -> done = 0 W->>C: wait_for_completion() Note over C: done == 0, so sleep<br/>enqueue on x->wait, schedule() P->>C: complete() Note over C: done++ (now 1)<br/>swake_up_locked() wakes waiter C-->>W: wake; reacquire lock Note over C: done != 0 -> done-- (back to 0)<br/>return Note over W: proceeds past the barrier
Sequence of a one-shot completion. What it shows: the waiter blocks only while done == 0; complete() bumps the counter and wakes the waiter, which then decrements done back to zero and proceeds. The insight to take: the counter is what makes the order between wait_for_completion() and complete() irrelevant — if the worker had called complete() first, the waiter would have seen done == 1 on arrival and skipped the sleep entirely. There is no lost-wakeup window.
Mechanical Walk-through
The data structure
The object is deliberately minimal (per include/linux/completion.h v6.12):
struct completion {
unsigned int done;
struct swait_queue_head wait;
};done is an unsigned int counter, not a boolean. Two things ride on its value: zero means “event has not happened, waiters must sleep”; any non-zero value means “event has happened” and is consumed by a waiter decrementing it. The special value UINT_MAX is a latch meaning “permanently done” (set by complete_all()), which waiters must never decrement. wait is a simple wait queue (swait_queue_head) rather than the full-featured wait queue — the swait variant is leaner and PREEMPT_RT-friendly because it never runs arbitrary callbacks under its raw spinlock. (Contrast the general mechanism in Wait Queues and Task Blocking.)
The waiter side: do_wait_for_common()
All the blocking variants funnel into one core routine (verbatim from kernel/sched/completion.c v6.12):
static inline long __sched
do_wait_for_common(struct completion *x,
long (*action)(long), long timeout, int state)
{
if (!x->done) {
DECLARE_SWAITQUEUE(wait);
do {
if (signal_pending_state(state, current)) {
timeout = -ERESTARTSYS;
break;
}
__prepare_to_swait(&x->wait, &wait);
__set_current_state(state);
raw_spin_unlock_irq(&x->wait.lock);
timeout = action(timeout);
raw_spin_lock_irq(&x->wait.lock);
} while (!x->done && timeout);
__finish_swait(&x->wait, &wait);
if (!x->done)
return timeout;
}
if (x->done != UINT_MAX)
x->done--;
return timeout ?: 1;
}Walking it symbol by symbol. The whole function runs while the caller (__wait_for_common) holds x->wait.lock, the raw spinlock embedded in the wait queue. First, if (!x->done) — if the event already happened, the entire sleep block is skipped; this is the fast path that closes the race. Inside the loop, signal_pending_state(state, current) checks whether a signal should abort the wait (only meaningful for TASK_INTERRUPTIBLE/TASK_KILLABLE states; for TASK_UNINTERRUPTIBLE it is always false). __prepare_to_swait enqueues the current task on the wait queue; __set_current_state(state) marks it sleepable. The lock is then dropped (raw_spin_unlock_irq) before calling action(timeout) — action is the scheduler call (schedule_timeout or schedule) that actually yields the CPU. On wakeup the lock is retaken. The loop condition while (!x->done && timeout) re-checks under the lock: keep sleeping only if the event still has not fired and we have not run out of timeout. After the loop, __finish_swait dequeues. If done is still zero (we hit a timeout or signal), return the (zero or negative) timeout. Otherwise the consume step: if (x->done != UINT_MAX) x->done--; — decrement the counter, unless it is the UINT_MAX latch, which must stay latched. The final return timeout ?: 1 returns at least 1 on success so callers can distinguish “completed” (positive) from “timed out” (zero).
The signaling side: complete() and complete_all()
void complete(struct completion *x)
{
complete_with_flags(x, 0);
}complete() (verbatim doc comment from v6.12) “will wake up a single thread waiting on this completion. Threads will be awakened in the same order in which they were queued.” Internally complete_with_flags() takes x->wait.lock, increments done (unless already UINT_MAX), and calls swake_up_locked() to wake exactly one queued waiter. The doc comment further promises a memory-ordering guarantee: “If this function wakes up a task, it executes a full memory barrier before accessing the task state.” That barrier is what lets the woken waiter safely observe everything the worker stored before calling complete().
complete_all() is structurally different (verbatim from v6.12):
void complete_all(struct completion *x)
{
unsigned long flags;
lockdep_assert_RT_in_threaded_ctx();
raw_spin_lock_irqsave(&x->wait.lock, flags);
x->done = UINT_MAX;
swake_up_all_locked(&x->wait);
raw_spin_unlock_irqrestore(&x->wait.lock, flags);
}It assigns done = UINT_MAX (the permanent latch) rather than incrementing, then swake_up_all_locked() wakes every queued waiter. Its doc comment carries the critical caveat: “Since complete_all() sets the completion of @x permanently to done to allow multiple waiters to finish, a call to reinit_completion() must be used on @x if @x is to be used again. The code must make sure that all waiters have woken and finished before reinitializing @x. Also note that the function completion_done() can not be used to know if there are still waiters after complete_all() has been called.” Because done is now UINT_MAX, no waiter decrements it, so all current and future waiters pass straight through — exactly what you want for “this resource is now ready for everyone.”
Non-blocking and introspection helpers
try_wait_for_completion() attempts the consume without ever sleeping: it returns false if done == 0, otherwise decrements (unless latched) and returns true. completion_done() (verbatim doc) returns “0 if there are waiters (wait_for_completion() in progress), 1 if there are no waiters” and “will always return true if complete_all() was called.” Both take the lock briefly to read done consistently.
Code and API
Declaring and initializing
/* Static / file-scope: initialized to "not done" at compile time. */
static DECLARE_COMPLETION(setup_done);
/* On the stack of a function. MUST use the _ONSTACK form for lockdep. */
DECLARE_COMPLETION_ONSTACK(transfer_done);
/* Dynamically, e.g. embedded in a heap-allocated struct. */
struct my_ctx { struct completion done; /* ... */ };
init_completion(&ctx->done);
/* Reuse an existing, already-initialized completion. */
reinit_completion(&ctx->done);DECLARE_COMPLETION(work) expands to struct completion work = COMPLETION_INITIALIZER(work), where COMPLETION_INITIALIZER is { 0, __SWAIT_QUEUE_HEAD_INITIALIZER((work).wait) } — done = 0 and an initialized wait queue. DECLARE_COMPLETION_ONSTACK (verbatim macro: (*({ init_completion(&work); &work; })) under CONFIG_LOCKDEP) exists so lockdep registers the embedded lock with a stack lock-class key; using the plain DECLARE_COMPLETION on the stack confuses lockdep. init_completion() sets done = 0 and initializes the wait queue; reinit_completion() resets only done to 0 and deliberately does not re-touch the wait queue — you reinit, you do not re-init_completion(), an already-used completion.
The canonical kthread handshake
struct task_struct *t;
DECLARE_COMPLETION_ONSTACK(started);
static int worker(void *arg)
{
struct completion *started = arg;
/* ... do per-thread setup that the parent must wait to finish ... */
complete(started); /* tell the parent we are up */
/* ... main loop ... */
return 0;
}
t = kthread_run(worker, &started, "my-worker");
wait_for_completion(&started); /* parent blocks until worker is ready */This is the textbook use: the parent creates a kernel thread and must not proceed until the child has finished its setup. Note started is on the parent’s stack — and that is safe here precisely because the parent does not return from this frame until wait_for_completion() has returned, which only happens after complete(). That stack-lifetime reasoning is the crux of the on-stack hazard (see Failure Modes).
Waiting with a deadline and a kill escape
ret = wait_for_completion_timeout(&ctx->done, msecs_to_jiffies(500));
if (ret == 0) {
/* timed out: device never raised completion -> error recovery */
return -ETIMEDOUT;
}
/* ret >= 1: completed with (ret) jiffies to spare */Verbatim return semantics from v6.12: wait_for_completion_timeout() returns “0 if timed out, and positive (at least 1, or number of jiffies left till timeout) if completed.” wait_for_completion_interruptible() and _killable() return “-ERESTARTSYS if interrupted, 0 if completed.” There are also _io variants that account the wait as I/O wait for load-average/iowait accounting, and the combined _interruptible_timeout / _killable_timeout forms.
Failure Modes and Common Misunderstandings
The unkillable hung task. The plain wait_for_completion() is TASK_UNINTERRUPTIBLE — its doc comment states flatly: “It is NOT interruptible and there is no timeout.” If the event it waits for never fires (a wedged device, a worker that died before calling complete()), the waiting task becomes permanently unkillable and shows up as a hung_task warning (“blocked for more than N seconds”). The fix is almost always to use _killable or _timeout and handle the failure. Reach for the plain form only when completion is truly guaranteed.
Freeing an on-stack completion too early. The v6.12 documentation warns that for on-stack completions “the function must not return to a calling context until all activities (such as waiting threads) have ceased and the completion object is completely unused” — otherwise a still-running thread dereferences a freed stack frame, causing “subtle data corruption.” This bites when you use a timeout variant on a stack completion: the waiter can time out and return (freeing the frame) while the worker is still about to touch the completion. The remedy is to embed the completion in a longer-lived (heap) structure whose lifetime you control.
Reusing after complete_all() without reinit_completion(). Because complete_all() latches done to UINT_MAX, the completion is “stuck done” forever. The next wait_for_completion() returns instantly. You must reinit_completion() — and be certain every prior waiter has already woken and left — before reusing it. Calling complete_all() twice without an intervening reinit is a bug.
Confusing complete() semantics as a counting semaphore. complete() increments done, so N calls to complete() will release N sequential waiters. This is occasionally exploited (the “counting completion” hinted at in try_wait_for_completion’s comment), but it is a sharp edge: if you call complete() more times than there will be waiters, the surplus accumulates in done and a future wait_for_completion() passes without a corresponding signal. For a true counting resource, a semaphore is the clearer tool.
Alternatives and When to Choose Them
A completion is essentially a specialized, race-free wrapper around the “wait for a one-shot event” use of a wait queue or a semaphore. The honest comparison:
- Hand-rolled flag + wait queue. You can build the same thing with a
boolflag, await_queue_head_t, andwait_event()/wake_up(). But you must get the memory ordering and the check-then-sleep race right yourself, andwait_event()already needs a condition expression. The completion packages this correctly and names the intent. Prefer the completion. (See Wait Queues and Task Blocking for the underlying mechanism.) - Semaphore used as a one-shot. Historically the kernel used an on-stack semaphore initialized to 0, with the waiter calling
down()and the workerup(). This works but is exactly the pattern completions were invented to replace — it overloads a counting primitive, reads poorly, and the on-stack-free race is easy to get wrong. Use Kernel Semaphores when you genuinely need counting/resource semantics, not for event signaling. wait_event()on a condition. When the thing you wait on is naturally a predicate over shared state (“queue non-empty,” “buffer has space”) rather than a discrete one-shot event,wait_event()is the better fit — it re-evaluates the condition on each wakeup. A completion fits a single fire-once event better.- RCU / seqlock. Entirely different problem — those are for reading shared data cheaply, not for waiting on an event. Not substitutes.
Production Notes
Completions are pervasive in driver and subsystem code precisely because the “kick off hardware, sleep until the IRQ says done” pattern is everywhere. Direct memory access (DMA) and block/network I/O drivers commonly embed a struct completion in their per-request context, call wait_for_completion_timeout() after submitting, and have the interrupt handler call complete() from hardirq context (which is safe — complete() only takes a raw spinlock and never sleeps). Module initialization handshakes and the kthread start/stop dance (the worker signaling “I’m up” or the stopper waiting for “I’m gone”) are the other dominant uses. The lockdep_assert_RT_in_threaded_ctx() at the top of complete_all() reflects a PREEMPT_RT constraint: on the real-time kernel, complete_all() waking many tasks must run in threaded context, not from a hard-IRQ, to bound latency. The use of swait (simple wait queues) rather than full wait queues throughout the implementation is itself a PREEMPT_RT accommodation — simple wait queues hold a raw spinlock and run no arbitrary callbacks, so they are safe in the constrained contexts completions are signaled from.
Uncertain
Verify: that
swake_up_locked()(called bycomplete()) wakes waiters in strict FIFO order matching the doc comment’s “awakened in the same order in which they were queued.” Reason: the FIFO claim is in thecomplete()doc comment, but the exact ordering guarantee of the underlyingswaitenqueue/wake was not traced to theswaitimplementation source in this task. To resolve: readkernel/sched/swait.c__prepare_to_swait/swake_up_lockedin v6.12 and confirm tail-enqueue + head-wake ordering.
See Also
- Wait Queues and Task Blocking — the general sleep/wakeup mechanism a completion specializes;
swaitis the leaner variant used insidestruct completion - Kernel Semaphores — the counting primitive completions replaced for event signaling; use it for true resource counting
- Memory Barriers in the Linux Kernel — the full memory barrier
complete()issues before touching task state is what makes a waiter safely observe the worker’s prior stores - Sequence Locks and seqlock — sibling read-mostly primitive (different problem: cheap reads, not event waiting)
- Linux Kernel Synchronization MOC — parent map (section C, Sleeping Locks)