aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma-buf
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-06-09 07:00:02 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2019-06-09 08:01:44 -0400
commit427231bc6d585befe09ea793776f0ba4d032c3f8 (patch)
tree9c3d2de4d74d84434d8589003dc1312f5e680b76 /drivers/dma-buf
parentaec3925f093d3ac880c53ec03ea28ef8608b0a52 (diff)
dma-fence: Signal all callbacks from dma_fence_release()
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. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190609110002.31915-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r--drivers/dma-buf/dma-fence.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 9bf06042619a..3eddfa0ad206 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -256,8 +256,25 @@ void dma_fence_release(struct kref *kref)
256 256
257 trace_dma_fence_destroy(fence); 257 trace_dma_fence_destroy(fence);
258 258
259 /* Failed to signal before release, could be a refcounting issue */ 259 if (WARN(!list_empty(&fence->cb_list),
260 WARN_ON(!list_empty(&fence->cb_list)); 260 "Fence %s:%s:%llx:%llx released with pending signals!\n",
261 fence->ops->get_driver_name(fence),
262 fence->ops->get_timeline_name(fence),
263 fence->context, fence->seqno)) {
264 unsigned long flags;
265
266 /*
267 * Failed to signal before release, likely a refcounting issue.
268 *
269 * This should never happen, but if it does make sure that we
270 * don't leave chains dangling. We set the error flag first
271 * so that the callbacks know this signal is due to an error.
272 */
273 spin_lock_irqsave(fence->lock, flags);
274 fence->error = -EDEADLK;
275 dma_fence_signal_locked(fence);
276 spin_unlock_irqrestore(fence->lock, flags);
277 }
261 278
262 if (fence->ops->release) 279 if (fence->ops->release)
263 fence->ops->release(fence); 280 fence->ops->release(fence);