FENCE SIGNALLING ANNOTATION(9)
π fence signalling annotation(9) π
okay so bestie, welcome to the Kernel API Manual page for fence signalling annotation(9) β this is the one about proving correctness of all the kernel code around dma_fence through code review and testing, and ngl it's tricky for a few reasons:
- It's a cross-driver contract π«Ά β and therefore all drivers must follow the same rules for lock nesting order, calling contexts for various functions, and anything else significant for in-kernel interfaces. But it is also impossible to test all drivers in a single machine, hence brute-force
N vs. Ntesting of all combinations is impossible. Even just limiting to the possible combinations is infeasible. - There is an enormous amount of driver code involved π. For render drivers there's the tail of command submission, after fences are published, scheduler code, interrupt and workers to process job completion, and timeout, gpu reset and gpu hang recovery code. Plus for integration with core mm with have
mmu_notifier, respectivelymmu_interval_notifier, and shrinker. For modesetting drivers there's the commit tail functions between when fences for an atomic modeset are published, and when the corresponding vblank completes, including any interrupt processing and related workers. Auditing all that code, across all drivers, is not feasible. - The wiggle-room is extremely thin π. Due to how many other subsystems are involved and the locking hierarchies this pulls in there is extremely thin wiggle-room for driver-specific differences.
dma_fenceinteracts with almost all of the core memory handling through page fault handlers viadma_resv,dma_resv_lockanddma_resv_unlock. On the other side it also interacts through all allocation sites throughmmu_notifierand shrinker.
Furthermore, lockdep does not handle cross-release dependencies, which means any deadlocks between dma_fence_wait and dma_fence_signal can't be caught at runtime with some quick testing. The simplest example is one thread waiting on a dma_fence while holding a lock:
lock(A);
dma_fence_wait(B);
unlock(A);
while the other thread is stuck trying to acquire the same lock, which prevents it from signalling the fence the previous thread is stuck waiting on:
lock(A);
unlock(A);
dma_fence_signal(B);
By manually annotating all code relevant to signalling a dma_fence we can teach lockdep about these dependencies, which also helps with the validation headache since now lockdep can check all the rules for us:
cookie = dma_fence_begin_signalling;
lock(A);
unlock(A);
dma_fence_signal(B);
dma_fence_end_signalling(cookie);
For using dma_fence_begin_signalling and dma_fence_end_signalling to annotate critical sections the following rules need to be observed:
- All code necessary to complete a
dma_fencemust be annotated β¨ β from the point where a fence is accessible to other threads, to the point wheredma_fence_signalis called. Un-annotated code can contain deadlock issues, and due to the very strict rules and many corner cases it is infeasible to catch these just with review or normal stress testing. struct dma_resvdeserves a special note π β since the readers are only protected byrcu. This means the signalling critical section starts as soon as the new fences are installed, even beforedma_resv_unlockis called.- The only exception are fast paths and opportunistic signalling code πββοΈ β which calls
dma_fence_signalpurely as an optimization, but is not required to guarantee completion of adma_fence. The usual example is a wait IOCTL which callsdma_fence_signal, while the mandatory completion path goes through a hardware interrupt and possible job completion worker. - To aid composability of code, the annotations can be freely nested π§ β as long as the overall locking hierarchy is consistent. The annotations also work both in interrupt and process context. Due to implementation details this requires that callers pass an opaque cookie from
dma_fence_begin_signallingtodma_fence_end_signalling. - Validation against the cross driver contract is implemented by priming
lockdepwith the relevant hierarchy at boot-up π β this means even just testing with a single device is enough to validate a driver, at least as far as deadlocks withdma_fence_waitagainstdma_fence_signalare concerned.
π SEE ALSO π
Kernel file ./drivers/dma-buf/dma-fence.c β then the whole reference squad: DMA fences overview(9), fence cross-driver contract(9), dma_fence_get_stub(9), dma_fence_allocate_private_stub(9), dma_fence_context_alloc(9), dma_fence_begin_signalling(9), dma_fence_end_signalling(9), dma_fence_signal_timestamp_locked(9), dma_fence_signal_timestamp(9), dma_fence_signal_locked(9), dma_fence_check_and_signal_locked(9), dma_fence_check_and_signal(9), dma_fence_signal(9), dma_fence_wait_timeout(9), dma_fence_release(9), dma_fence_free(9), dma_fence_enable_signaling(9), dma_fence_add_callback(9), dma_fence_get_status(9), dma_fence_remove_callback(9), dma_fence_default_wait(9), dma_fence_wait_any_timeout(9), deadline hints(9), dma_fence_set_deadline(9), dma_fence_describe(9), dma_fence_init(9), dma_fence_init64(9), dma_fence_driver_name(9), dma_fence_timeline_name(9).
mwah π β source/version path is ./drivers/dma-buf, date stamp is October 2026, and this page is literally fence signalling annotation(9). periodt. π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms