Skip to content

Completion Synchronization APIs

Overview

Completion provides a lightweight synchronization mechanism for one-shot event notification.

It is commonly used when one execution context must wait until another execution context finishes an operation.

Typical use cases include:

  • Hardware initialization
  • Firmware loading
  • DMA completion
  • Worker startup synchronization
  • Driver probe synchronization

init_completion()

Prototype

#include <linux/completion.h>

void init_completion(struct completion *x);

Parameters

Parameter Description
x Completion object

Description

Initialize a completion object.

The completion state becomes:

not completed

Example

struct completion done;

init_completion(&done);

reinit_completion()

Prototype

void reinit_completion(struct completion *x);

Parameters

Parameter Description
x Completion object

Description

Reset a completion object after it has already completed.

This allows the completion object to be reused.

Example

complete(&done);

reinit_completion(&done);

Notes

Completion state persists after completion.

Without reinitialization, future waiters return immediately.


wait_for_completion()

Prototype

void wait_for_completion(struct completion *x);

Parameters

Parameter Description
x Completion object

Description

Block until completion is signaled.

Example

wait_for_completion(&done);

Notes

The caller sleeps until:

complete()

or

complete_all()

is executed.


wait_for_completion_timeout()

Prototype

unsigned long wait_for_completion_timeout(
        struct completion *x,
        unsigned long timeout);

Parameters

Parameter Description
x Completion object
timeout Timeout in jiffies

Return Value

Return Meaning
0 Timeout
> 0 Completed

Example

ret = wait_for_completion_timeout(
        &done,
        msecs_to_jiffies(5000));

Notes

Timeout only indicates that completion did not occur.

The worker responsible for signaling completion may still be running.


complete()

Prototype

void complete(struct completion *x);

Parameters

Parameter Description
x Completion object

Description

Signal completion and wake a single waiter.

Example

complete(&done);

Notes

If multiple waiters are blocked:

complete()

wakes only one waiter.


complete_all()

Prototype

void complete_all(struct completion *x);

Parameters

Parameter Description
x Completion object

Description

Signal completion and wake all waiters.

Example

complete_all(&done);

Notes

All waiters blocked on the completion object are awakened.


Common Pitfalls

Forgetting Timeout Handling

Bad:

wait_for_completion(&done);

If the completion event never occurs, the caller blocks forever.

Consider:

wait_for_completion_timeout()

when waiting for hardware or firmware.


Assuming Timeout Means Worker Exit

Bad assumption:

timeout
    ==
worker exited

Timeout only means:

completion not signaled

Worker cleanup must be handled separately.


Forgetting reinit_completion()

After:

complete()

future waiters return immediately.

Use:

reinit_completion()

before reusing a completion object.


Related APIs

  • wait_event()
  • wait_event_timeout()
  • wake_up()
  • kthread_run()
  • kthread_stop()

Related Labs

  • Day68 - Kernel Threads and Wait Queues
  • Day69 - Completion Synchronization