On Tue, Feb 10, 2026 at 09:16:34AM +0100, Christian König wrote: > On 2/9/26 15:58, Boris Brezillon wrote: > > On Mon, 09 Feb 2026 09:19:46 +0100 > > Philipp Stanner <[email protected]> wrote: > > > >> On Fri, 2026-02-06 at 11:23 +0100, Danilo Krummrich wrote: > >>> On Thu Feb 5, 2026 at 9:57 AM CET, Boris Brezillon wrote: > >>>> On Tue, 3 Feb 2026 09:14:01 +0100 > >>>> Philipp Stanner <[email protected]> wrote: > >>>> Unfortunately, I don't know how to translate that in rust, but we > >>>> need a way to check if any path code path does a DmaFence.signal(), > >>>> go back to the entry point (for a WorkItem, that would be > >>>> WorkItem::run() for instance), and make it a DmaFenceSignallingPath. > >>>> Not only that, but we need to know all the deps that make it so > >>>> this path can be called (if I take the WorkItem example, that would > >>>> be the path that leads to the WorkItem being scheduled). > >>> > >>> I think we need a guard object for this that is not Send, just like for > >>> any > >>> other lock. > >>> > >>> Internally, those markers rely on lockdep, i.e. they just acquire and > >>> release a > >>> "fake" lock. > >> > >> The guard object would be created through fence.begin_signalling(), > >> wouldn't it? > > > > It shouldn't be a (&self)-method, because at the start of a DMA > > signaling path, you don't necessarily know which fence you're going to > > signal (you might actually signal several of them). > > > >> And when it drops you call dma_fence_end_signalling()? > > > > Yep, dma_fence_end_signalling() should be called when the guard is > > dropped. > > > >> > >> How would that ensure that the driver actually marks the signalling region > >> correctly? > > > > Nothing, and that's a problem we have in C: you have no way of telling > > which code section is going to be a DMA-signaling path. I can't think > > of any way to make that safer in rust, unfortunately. The best I can > > think of would be to > > > > - Have a special DmaFenceSignalWorkItem (wrapper a WorkItem with extra > > constraints) that's designed for DMA-fence signaling, and that takes > > the DmaSignaling guard around the ::run() call. > > - We would then need to ensure that any code path scheduling this work > > item is also in a DMA-signaling path by taking a ref to the > > DmaSignalingGuard. This of course doesn't guarantee that the section > > is wide enough to prevent any non-authorized operations in any path > > leading to this WorkItem scheduling, but it would at least force the > > caller to consider the problem. > > On the C side I have a patch set which does something very similar. > > It's basically a WARN_ON_ONCE() which triggers as soon as you try to > signal a DMA fence from an IOCTL, or more specific process context. > > Signaling a DMA fence from interrupt context, a work item or kernel > thread is still allowed, there is just the hole that you can schedule > a work item from process context as well. > > The major problem with that patch set is that we have tons of very > hacky signaling paths in drivers already because we initially didn't > knew how much trouble getting this wrong causes. > > I'm strongly in favor of getting this right for the rust side from the > beginning and enforcing strict rules for every code trying to > implement a DMA fence.
Hmm. Could you say a bit more about what the rules are? I just re-read the comments in dma-fence.c, but I have some questions. First, how does the signalling annotation work when the signalling path crosses thread boundaries? For example, let's say I call an ioctl to perform an async VM_BIND, then the dma fence signalling critical path starts in the ioctl, but then it moves into a workqueue and finishes there, right? Second, it looks like we have the same challenge as with irq locks where you must properly nest dma_fence_begin_signalling() regions, and can't e.g. do this: c1 = dma_fence_begin_signalling() c2 = dma_fence_begin_signalling() dma_fence_end_signalling(c1) dma_fence_end_signalling(c2) Alice
