[PATCH] dma-buf/dma-fence: Signal all callbacks from dma_fence_release()

Chris Wilson chris at chris-wilson.co.uk
Fri Aug 11 17:01:47 UTC 2017


This is an illegal scenario, to free the fence whilst there are pending
callbacks. Currently, we emit a WARN and then cast aside the callbacks
leaving them dangling. Alternatively, we could set an error on the fence
and then signal fence so that any dependency chains from the fence can
be tidied up, and if they care they can check for the error.

The question is whether or not the cure is worse than the disease
(premature fence signaling is never pretty).

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/dma-buf/dma-fence.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 9a302799040e..ed311edbeefa 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -172,7 +172,19 @@ void dma_fence_release(struct kref *kref)
 
 	trace_dma_fence_destroy(fence);
 
-	WARN_ON(!list_empty(&fence->cb_list));
+	if (WARN_ON(!list_empty(&fence->cb_list))) {
+		unsigned long flags;
+
+		/*
+		 * This should never happen, but if it does make sure that we
+		 * don't leave chains dangling. We set the error flag first
+		 * so that the callbacks know this signal is due to an error.
+		 */
+		spin_lock_irqsave(fence->lock, flags);
+		fence->error = -EDEADLK;
+		dma_fence_signal_locked(fence);
+		spin_unlock_irqrestore(fence->lock, flags);
+	}
 
 	if (fence->ops->release)
 		fence->ops->release(fence);
-- 
2.13.3



More information about the dri-devel mailing list