diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 5e96cb5f1f3b..8d88e84c8c58 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -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 diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index 19972f5d176f..0504afe52c2a 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -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,