Skip to content

Day69 - Completion Synchronization

Overview

This lab explores Linux kernel completion synchronization primitives.

Topics covered:

  • Basic completion usage
  • Completion timeout handling
  • complete() vs complete_all()
  • reinit_completion()

Lab 1 - Basic Completion

Objective

Learn the basic completion workflow.

wait_for_completion()
        |
    complete()

Implementation

Main thread:

init_completion()
wait_for_completion()

Worker thread:

complete()

Expected Behavior

MAIN wait
WORKER complete
MAIN resume

Result

Example log:

[MAIN] wait completion...
[WORKER] start
[WORKER] complete
[MAIN] done

Lab 2 - Completion Timeout

Objective

Learn timeout handling and worker cleanup.


Implementation

Main thread:

wait_for_completion_timeout()

Timeout path:

kthread_stop()

Worker thread:

msleep_interruptible()
kthread_should_stop()

Observation

Timeout does not imply worker termination.

The worker must still be stopped and synchronized before resources are released.


Result

Example log:

[MAIN] timeout
[WORKER] interrupted
[WORKER] stop request
[WORKER] exit
[MAIN] exit due to error

Lab 3 - complete() vs complete_all()

Objective

Compare wake-up behavior with multiple waiters.


Test Topology

WAITER-1
WAITER-2
WAITER-3


    SIGNALER

Test A - complete()

Signaler:

complete(&done);

Result

[SIGNALER] complete
[WAITER-1] done

Only one waiter wakes up.


Test B - complete_all()

Signaler:

complete_all(&done);

Result

[SIGNALER] complete
[WAITER-1] done
[WAITER-2] done
[WAITER-3] done

All waiters wake up.


Lab 4 - reinit_completion()

Objective

Verify completion state persistence and reuse.


Test Flow

complete_all()

WAITER-2 start
immediately done

reinit_completion()

WAITER-3 start
blocks again

complete_all()

WAITER-3 done

Result

[SIGNALER] complete_all
[WAITER-2] done

[SIGNALER] reinit_completion

[WAITER-3] start
[WAITER-3] timeout

[SIGNALER] complete_all

[WAITER-3] done

Observation

Completion state remains completed after:

complete()
complete_all()

New waiters immediately return.

To reuse a completion object:

reinit_completion()

must be called.


Summary

Completion is a one-shot synchronization primitive.

Key behaviors verified:

  • wait_for_completion()
  • wait_for_completion_timeout()
  • complete()
  • complete_all()
  • reinit_completion()

Completion is ideal for:

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

Completion is not intended for state machines or repeated event processing.

Those use cases are better served by wait queues.