Thread (103 messages) 103 messages, 9 authors, 2026-03-13

Re: [RFC PATCH 2/4] rust: sync: Add dma_fence abstractions

From: Boris Brezillon <boris.brezillon@collabora.com>
Date: 2026-02-10 12:21:54
Also in: dri-devel, lkml

On Tue, 10 Feb 2026 11:45:36 +0000
Alice Ryhl [off-list ref] wrote:
On Tue, Feb 10, 2026 at 12:34:32PM +0100, Boris Brezillon wrote:
quoted
On Tue, 10 Feb 2026 10:15:04 +0000
Alice Ryhl [off-list ref] wrote:
  
quoted
impl MustBeSignalled<'_> {
    /// Drivers generally should not use this one.
    fn i_promise_it_will_be_signalled(self) -> WillBeSignalled { ... }

    /// One way to ensure the fence has been signalled is to signal it.
    fn signal_fence(self) -> WillBeSignalled {
        self.fence.signal();
        self.i_promise_it_will_be_signalled()
    }

    /// Another way to ensure the fence will be signalled is to spawn a
    /// workqueue item that promises to signal it.
    fn transfer_to_wq(
        self,
        wq: &Workqueue,
        item: impl DmaFenceWorkItem,
    ) -> WillBeSignalled {
        // briefly obtain the lock class of the wq to indicate to
        // lockdep that the signalling path "blocks" on arbitrary jobs
        // from this wq completing
        bindings::lock_acquire(&wq->key);
        bindings::lock_release(&wq->key);  
Sorry, I'm still trying to connect the dots here. I get that the intent
is to ensure the pseudo-lock ordering is always:
  
   -> dma_fence_lockdep_map
      -> wq->lockdep_map  

but how can this order be the same in the WorkItem execution path? My
interpretation of process_one_work() makes me think we'll end up with
  
  -> wq->lockdep_map
    -> work->run()
       -> WorkItem::run()
          -> dma_fence_lockdep_map
             -> DmaFenceSignalingWorkItem::run()  
                ...

Am I missing something? Is there a way you can insert the
dma_fence_lockdep_map acquisition before the wq->lockdep_map one in the
execution path?  
Conceptually, the dma_fence_lockdep_map is already taken by the time you
get to WorkItem::run() because it was taken all the way back in the
ioctl, so WorkItem::run() does not need to reacquire it.

Now, of course that does not translate cleanly to how lockdep does
things, so in lockdep we do have to re-acquire it in WorkItem::run().
You can do that by setting the trylock bit when calling lock_acquire()
on dma_fence_lockdep_map. This has the correct semantics because trylock
does not create an edge from wq->lockdep_map to dma_fence_lockdep_map.
Ah, I never noticed dma_fence_begin_signalling() was recording a
try_lock not a regular lock. I guess it would do then.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help