]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dma-buf/dma-fence: Add dma_fence_check_and_signal()
authorPhilipp Stanner <phasta@kernel.org>
Mon, 1 Dec 2025 10:50:06 +0000 (11:50 +0100)
committerPhilipp Stanner <phasta@kernel.org>
Thu, 4 Dec 2025 14:03:40 +0000 (15:03 +0100)
The overwhelming majority of users of dma_fence signaling functions
don't care about whether the fence had already been signaled by someone
else. Therefore, the return code shall be removed from those functions.

For the few users who rely on the check, a new, specialized function
shall be provided.

Add dma_fence_check_and_signal(), which signals a fence if it had not
yet been signaled, and informs the user about that.

Add a counter part, dma_fence_check_and_signal_locked(), which doesn't
take the spinlock.

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://patch.msgid.link/20251201105011.19386-4-phasta@kernel.org
drivers/dma-buf/dma-fence.c
include/linux/dma-fence.h

index 5e96cb5f1f3b1f57f0e0210e7ca96f16f65c924a..8d88e84c8c58ba853b20989c4c6261bfe5a9070b 100644 (file)
@@ -443,6 +443,50 @@ int dma_fence_signal_locked(struct dma_fence *fence)
 }
 EXPORT_SYMBOL(dma_fence_signal_locked);
 
+/**
+ * dma_fence_check_and_signal_locked - signal the fence if it's not yet signaled
+ * @fence: the fence to check and signal
+ *
+ * Checks whether a fence was signaled and signals it if it was not yet signaled.
+ *
+ * Unlike dma_fence_check_and_signal(), this function must be called with
+ * &struct dma_fence.lock being held.
+ *
+ * Return: true if fence has been signaled already, false otherwise.
+ */
+bool dma_fence_check_and_signal_locked(struct dma_fence *fence)
+{
+       bool ret;
+
+       ret = dma_fence_test_signaled_flag(fence);
+       dma_fence_signal_locked(fence);
+
+       return ret;
+}
+EXPORT_SYMBOL(dma_fence_check_and_signal_locked);
+
+/**
+ * dma_fence_check_and_signal - signal the fence if it's not yet signaled
+ * @fence: the fence to check and signal
+ *
+ * Checks whether a fence was signaled and signals it if it was not yet signaled.
+ * All this is done in a race-free manner.
+ *
+ * Return: true if fence has been signaled already, false otherwise.
+ */
+bool dma_fence_check_and_signal(struct dma_fence *fence)
+{
+       unsigned long flags;
+       bool ret;
+
+       spin_lock_irqsave(fence->lock, flags);
+       ret = dma_fence_check_and_signal_locked(fence);
+       spin_unlock_irqrestore(fence->lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(dma_fence_check_and_signal);
+
 /**
  * dma_fence_signal - signal completion of a fence
  * @fence: the fence to signal
index 19972f5d176f30a9959f7406a9f686563bb293e4..0504afe52c2a7230cdbd674902711353bf60f4b0 100644 (file)
@@ -365,6 +365,8 @@ static inline void __dma_fence_might_wait(void) {}
 #endif
 
 int dma_fence_signal(struct dma_fence *fence);
+bool dma_fence_check_and_signal(struct dma_fence *fence);
+bool dma_fence_check_and_signal_locked(struct dma_fence *fence);
 int dma_fence_signal_locked(struct dma_fence *fence);
 int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp);
 int dma_fence_signal_timestamp_locked(struct dma_fence *fence,