Commit 427231bc authored by Chris Wilson's avatar Chris Wilson

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarGustavo Padovan <gustavo.padovan@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190609110002.31915-1-chris@chris-wilson.co.uk
parent aec3925f
...@@ -256,8 +256,25 @@ void dma_fence_release(struct kref *kref) ...@@ -256,8 +256,25 @@ void dma_fence_release(struct kref *kref)
trace_dma_fence_destroy(fence); trace_dma_fence_destroy(fence);
/* Failed to signal before release, could be a refcounting issue */ if (WARN(!list_empty(&fence->cb_list),
WARN_ON(!list_empty(&fence->cb_list)); "Fence %s:%s:%llx:%llx released with pending signals!\n",
fence->ops->get_driver_name(fence),
fence->ops->get_timeline_name(fence),
fence->context, fence->seqno)) {
unsigned long flags;
/*
* Failed to signal before release, likely a refcounting issue.
*
* 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) if (fence->ops->release)
fence->ops->release(fence); fence->ops->release(fence);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment