On Mon, 29 Jun 2026 09:56:37 +0200 Philipp Stanner <[email protected]> wrote:
> The commit mentioned in the fixes tag below introduced a mechanism > through which fence producers can fully decouple from fence consumers. > This, desirable, mechanism is based on the fence's signaled-bit as the > "decoupling point". > > A sophisticated interaction between RCU and atomic instructions attempts > to ensure that fence consumers can still interact with fence producers > through the dma_fence_ops (callback pointers into the producer). > > This is the desired behavior: to check for decoupling, the signaled-bit > is first checked. If it's not yet signaled, RCU ensures that the ops > pointer cannot yet be NULL. > > Hereby, dma_fence_signal_timestamp_locked() first sets the signaled-bit, > and then sets the ops pointer to NULL. Readers first load the ops > pointer, and then check through the signaled-bit whether the pointer can > legally be accessed. > > These set and load operations could occur out of order on weakly ordered > platforms. This problem can be solved very elegantly by using the ops > pointer itself as the synchronization point. The pointer is either NULL, > or cannot become NULL while it is being used thanks to RCU. > > Replace the signaled-bit check in dma_fence_timeline_name() and > dma_fence_driver_name(). > > Cc: [email protected] > Fixes: f4cc3ab824d6 ("dma-buf: protected fence ops by RCU v8") > Signed-off-by: Philipp Stanner <[email protected]> Reviewed-by: Boris Brezillon <[email protected]> > --- > Changes since v1: > - Use ops pointer instead of memory barriers. (Christian) > - Rephrase commit message. > --- > drivers/dma-buf/dma-fence.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > index c7ea1e75d38a..0a025dfdf131 100644 > --- a/drivers/dma-buf/dma-fence.c > +++ b/drivers/dma-buf/dma-fence.c > @@ -1170,7 +1170,7 @@ const char __rcu *dma_fence_driver_name(struct > dma_fence *fence) > > /* RCU protection is required for safe access to returned string */ > ops = rcu_dereference(fence->ops); > - if (!dma_fence_test_signaled_flag(fence)) > + if (ops) > return (const char __rcu *)ops->get_driver_name(fence); > else > return (const char __rcu *)"detached-driver"; > @@ -1203,7 +1203,7 @@ const char __rcu *dma_fence_timeline_name(struct > dma_fence *fence) > > /* RCU protection is required for safe access to returned string */ > ops = rcu_dereference(fence->ops); > - if (!dma_fence_test_signaled_flag(fence)) > + if (ops) > return (const char __rcu *)ops->get_driver_name(fence); > else > return (const char __rcu *)"signaled-timeline"; > > base-commit: cdeb2ccd993ed8647adbbda2c3b103aa717fd6f7
