diff options
Diffstat (limited to 'drivers/dma-buf/dma-fence.c')
-rw-r--r-- | drivers/dma-buf/dma-fence.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 9bf06042619a..59ac96ec7ba8 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Fence mechanism for dma-buf and to allow for asynchronous dma access * @@ -7,15 +8,6 @@ * Authors: * Rob Clark <robdclark@gmail.com> * Maarten Lankhorst <maarten.lankhorst@canonical.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/slab.h> @@ -256,8 +248,25 @@ void dma_fence_release(struct kref *kref) trace_dma_fence_destroy(fence); - /* Failed to signal before release, could be a refcounting issue */ - WARN_ON(!list_empty(&fence->cb_list)); + if (WARN(!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) fence->ops->release(fence); |