On Tue, 10 Feb 2026 11:45:36 +0000 Alice Ryhl <[email protected]> wrote:
> On Tue, Feb 10, 2026 at 12:34:32PM +0100, Boris Brezillon wrote: > > On Tue, 10 Feb 2026 10:15:04 +0000 > > Alice Ryhl <[email protected]> wrote: > > > > > 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.
