DragonFly BSD

Locking and Synchronization


Lockmgr locks used to be heavy-weight locks but have since been optimized and will run almost as fast as spinlocks and faster than mtx locks in the critical path. Lockmgr locks block formally and will not be as fast as spin-locks for very short highly-contending bits of code. Lockmgr locks are the go-to lock for DragonFly and should be used if you are not sure what to use.



Kernel spinlocks are optimized for fast inlining but should generally only be used if tokens, lockmgr, or mtx locks are not appropriate. The most common use case is when you are holding a token but do not want to break its atomicy by potentially blocking on a deeper lock. It is far more difficult to debug issues with spinlocks than it is for blockable locks.


LWKT serializing tokens

LWKT tokens are commonly used to loosely lock very broad, deep, or complex sections of code which might block at times. You can acquire tokens in any order without worrying about deadlocks, however any blocking condition (including blocking when acquiring additional tokens) will temporarily release ALL held tokens while the thread is blocked. Tokens have the property of serializing code execution for the token held while the thread is runnable.

Preemption by another thread (typically an interrupt thread) will not break the tokens you are holding. Preemption is still allowed... tokens do not enter a critical section. If the preempting thread tries to obtain the same token it will reschedule normally and return to the original thread.

The kernel thread scheduler will try to spin a bit on a token that cannot be acquired before giving up and blocking for real.



Mtx locks in DragonFly should not be confused with mtx locks in FreeBSD. Mtx locks in DragonFly are a very different beast. Generally these locks work similarly to lockmgr locks but provide two additional features which also make them heavier-weight in the face of contention.



The mplock has been deprecated and should no longer be used. It is still used in a few non-critical places in DragonFly but has been removed from nearly all major and minor kernel subsystems.


LWKT Messages

DragonFly implements a light weight message-and-port subsystem which is primarily used to shove packets around in bulk in the network subsystem and to cpu-localize network operations. The disk subsystem also uses LWKT messages to sequence disk probes and synchronize devfs.


Critical Sections

Critical sections are a form of cpu-localized locking that prevents a thread from being preempted by another thread or an IPI or clock interrupt.

Critical sections do not protect a thread from threads or interrupts which might run on other cpus and should generally not be used to protect the frontend of a chipset driver from the backend (since the frontend can run on any cpu). Critical sections are primarily used to protect against IPIs, allowing cpu localized code to run very efficiently.

A critical section can be used if you want to avoid code latency but is not recommended for this purpose any more. A critical section cannot prevent SMIs from occurring and also do not prevent the actual hard interrupt from interrupting the cpu, it simply causes the interrupt to immediately return and delay execution until the critical section is exited.



Condvars are only used when porting code from FreeBSD and should not generally be used for native DragonFly code.



DragonFly currently implements a LWKT serializer abstraction which should not be used generally. This abstraction is heavily integrated into the network interface device driver subsystem.