Re: [PATCH v9 4/5] rust: Add dma_fence abstractions
Daniel Almeida <[email protected]> Wed, 5 Aug 2026 12:35:51 -0300
| Newsgroups | org.kernel.vger.linux-media,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.rcu,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <[email protected]> |
> On 5 Aug 2026, at 11:59, Philipp Stanner <[email protected]> wrote: > > C's dma_fence's are synchronisation primitives that will be needed by all > Rust GPU drivers. > > The dma_fence framework sets a number of rules, notably: > - fences must only be signaled once > - all fences must be signaled at some point > - fence error codes must only be set before signaling > - every pointer to a fence must be backed by a reference > > All those rules are being addressed by these abstractions. > > To cleanly decouple fence issuers and consumers, two types are provided: > - DriverFence: the only fence type that can be signaled and that > carries driver-specific data. > - Fence: the fence type to be shared with other drivers and / or > userspace. The only type callbacks can be registered on. > Cannot be signaled. > > Hereby, a Fence lives in the same chunk of memory as a DriverFence. Both > share the refcount of the underlying C dma_fence. Since this > implementation does not provide a custom dma_fence_backend_ops.release() > function, the memory is freed by the dma_fence backend once the refcount > drops to 0. > > To create a DriverFence, the user must first allocate a > DriverFenceAllocation, so that the creation of the DriverFence later on > can always succeed. Otherwise, deadlocks could occur if fences need to > be created in a GPU job submission path. > > Synchronization is ensured by the dma_fence backend. > > All DriverFence's created through this abstraction must be signaled by > the creator with an error code. In case a DriverFence drops without > being signaled beforehand, it is signaled with -ECANCELLED as its > error and a warning is printed. This allows the Rust abstraction to very > cleanly decouple fence issuer and consumer by relying on the decoupling > mechanisms in the C backend, which ensures through RCU and the > 'signaled' fence-flag that dma_fence_backend_ops functions cannot > access the potentially unloaded driver code anymore. > > Signalling fences on drop thus grants many advantages. Not signaling > fences on drop would risk deadlock and does not grant real advantages: > By definition only the drivers can ensure that a fence always represents > the hardware's state correctly. > > This implementation models a DmaFenceContext object on which fences are > to be created, thereby ensuring correct sequence numbering according to > the timeline. > > dma_fence supports a variety of callbacks. The mandatory callbacks > (get_timeline_name() and get_driver_name()) are implemented in this > patch. For convenience, they store those name parameters in the fence > context, saving the driver from implementing these two callbacks. > > Support for other callbacks (like for hardware signaling) is prepared > for through the fact that both DriverFence and Fence live in the same > allocation, allowing for usage of container_of from the callback to > access the driver-specific data. > > It is expected that other callbacks, added in the future, also mostly > operate on the generic data in the FenceContext. To make this safe, the > implementation ensures through a lifetime that a DriverFence cannot > outlive its FenceContext. > > Synchronization for dma_fence_ops callbacks is ensured by only running the > Rust deconstructor delayed with call_rcu(), which prevents UAF-bugs > should a DriverFence drop while a Fence callback is currently operating > on the associated driver data. Since they can also operate on the > FenceContext's data, its drop implementation also performs the necessary > delay with rcu_barrier(). > > An additional issue discovered during the review process of this code is > that there is (currently) no mechanism in Rust to prevent someone from > circumventing the DriverFence's FenceContext-reference's lifetime by > "forgetting" the fence, e.g. with core::mem::forget(). This would enable > UAF bugs on the FenceContext. Throw a panic if this happens and document > a path towards a more robust solution. > > Add abstractions for dma_fence in Rust. > > Signed-off-by: Philipp Stanner <[email protected]> > Tested-by: Daniel Almeida <[email protected]> > Owing to the ongoing discussion in v8, I still think we could propose some refinements in the future, like most source code out there :) But overall this is a solid base to build upon and it doesn’t make sense to delay seeking the “perfect” solution, if such a thing even exists.. Thanks for your hard work here! Reviewed-by: Daniel Almeida <[email protected]>