This is a note to let you know that I've just added the patch titled
dma-buf: Update kerneldoc for sync_file_create
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-update-kerneldoc-for-sync_file_create.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 24a367348a017555f982a9ee137070a7a821fa97 Mon Sep 17 00:00:00 2001
From: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Date: Fri, 9 Dec 2016 19:53:06 +0100
Subject: dma-buf: Update kerneldoc for sync_file_create
From: Daniel Vetter <daniel.vetter(a)ffwll.ch>
commit 24a367348a017555f982a9ee137070a7a821fa97 upstream.
This was missed when adding a dma_fence_get call. While at it also
remove the kerneldoc for the static inline helper - no point
documenting internals down to every detail.
Fixes: 30cd85dd6edc ("dma-buf/sync_file: hold reference to fence when creating sync_file")
Cc: Gustavo Padovan <gustavo.padovan(a)collabora.co.uk>
Cc: Sean Paul <seanpaul(a)chromium.org>
Cc: linux-doc(a)vger.kernel.org
Cc: Jonathan Corbet <corbet(a)lwn.net>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Signed-off-by: Daniel Vetter <daniel.vetter(a)intel.com>
Reviewed-by: Gustavo Padovan <gustavo.padovan(a)collabora.co.uk>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20161209185309.1682-3-daniel.v…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/sync_file.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -67,9 +67,10 @@ static void fence_check_cb_func(struct f
* sync_file_create() - creates a sync file
* @fence: fence to add to the sync_fence
*
- * Creates a sync_file containg @fence. Once this is called, the sync_file
- * takes ownership of @fence. The sync_file can be released with
- * fput(sync_file->file). Returns the sync_file or NULL in case of error.
+ * Creates a sync_file containg @fence. This function acquires and additional
+ * reference of @fence for the newly-created &sync_file, if it succeeds. The
+ * sync_file can be released with fput(sync_file->file). Returns the
+ * sync_file or NULL in case of error.
*/
struct sync_file *sync_file_create(struct fence *fence)
{
@@ -90,13 +91,6 @@ struct sync_file *sync_file_create(struc
}
EXPORT_SYMBOL(sync_file_create);
-/**
- * sync_file_fdget() - get a sync_file from an fd
- * @fd: fd referencing a fence
- *
- * Ensures @fd references a valid sync_file, increments the refcount of the
- * backing file. Returns the sync_file or NULL in case of error.
- */
static struct sync_file *sync_file_fdget(int fd)
{
struct file *file = fget(fd);
Patches currently in stable-queue which might be from daniel.vetter(a)ffwll.ch are
queue-4.9/dma-fence-clear-fence-status-during-dma_fence_init.patch
queue-4.9/dma-fence-wrap-querying-the-fence-status.patch
queue-4.9/dma-fence-introduce-drm_fence_set_error-helper.patch
queue-4.9/dma-buf-update-kerneldoc-for-sync_file_create.patch
This is a note to let you know that I've just added the patch titled
dma-buf/sync_file: hold reference to fence when creating sync_file
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-sync_file-hold-reference-to-fence-when-creating-sync_file.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 30cd85dd6edc86ea8d8589efb813f1fad41ef233 Mon Sep 17 00:00:00 2001
From: Gustavo Padovan <gustavo.padovan(a)collabora.co.uk>
Date: Wed, 19 Oct 2016 15:48:32 -0200
Subject: dma-buf/sync_file: hold reference to fence when creating sync_file
From: Gustavo Padovan <gustavo.padovan(a)collabora.co.uk>
commit 30cd85dd6edc86ea8d8589efb813f1fad41ef233 upstream.
fence referencing was out of balance. It was not taking any ref to the
fence at creating time, but it was putting a reference when freeing the
sync file.
This patch fixes the balancing issue by getting a reference for the fence
when creating the sync_file.
Signed-off-by: Gustavo Padovan <gustavo.padovan(a)collabora.co.uk>
Signed-off-by: Sean Paul <seanpaul(a)chromium.org>
Link: http://patchwork.freedesktop.org/patch/msgid/1476899313-22241-1-git-send-em…
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/sync_file.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -79,7 +79,7 @@ struct sync_file *sync_file_create(struc
if (!sync_file)
return NULL;
- sync_file->fence = fence;
+ sync_file->fence = fence_get(fence);
snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
fence->ops->get_driver_name(fence),
Patches currently in stable-queue which might be from gustavo.padovan(a)collabora.co.uk are
queue-4.9/dma-buf-sync_file-hold-reference-to-fence-when-creating-sync_file.patch
queue-4.9/dma-buf-update-kerneldoc-for-sync_file_create.patch
This is a note to let you know that I've just added the patch titled
dma-fence: Wrap querying the fence->status
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-fence-wrap-querying-the-fence-status.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From d6c99f4bf093a58d3ab47caaec74b81f18bc4e3f Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris(a)chris-wilson.co.uk>
Date: Wed, 4 Jan 2017 14:12:21 +0000
Subject: dma-fence: Wrap querying the fence->status
From: Chris Wilson <chris(a)chris-wilson.co.uk>
commit d6c99f4bf093a58d3ab47caaec74b81f18bc4e3f upstream.
The fence->status is an optional field that is only valid once the fence
has been signaled. (Driver may fill the fence->status with an error code
prior to calling dma_fence_signal().) Given the restriction upon its
validity, wrap querying of the fence->status into a helper
dma_fence_get_status().
Signed-off-by: Chris Wilson <chris(a)chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Reviewed-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-2-chris@ch…
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang(a)synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/fence.c | 25 +++++++++++++++++++++++++
drivers/dma-buf/sync_debug.c | 20 ++++++++++----------
drivers/dma-buf/sync_file.c | 6 ++----
include/linux/fence.h | 24 ++++++++++++++++++++++++
4 files changed, 61 insertions(+), 14 deletions(-)
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -281,6 +281,31 @@ int fence_add_callback(struct fence *fen
EXPORT_SYMBOL(fence_add_callback);
/**
+ * fence_get_status - returns the status upon completion
+ * @fence: [in] the fence to query
+ *
+ * This wraps fence_get_status_locked() to return the error status
+ * condition on a signaled fence. See fence_get_status_locked() for more
+ * details.
+ *
+ * Returns 0 if the fence has not yet been signaled, 1 if the fence has
+ * been signaled without an error condition, or a negative error code
+ * if the fence has been completed in err.
+ */
+int fence_get_status(struct fence *fence)
+{
+ unsigned long flags;
+ int status;
+
+ spin_lock_irqsave(fence->lock, flags);
+ status = fence_get_status_locked(fence);
+ spin_unlock_irqrestore(fence->lock, flags);
+
+ return status;
+}
+EXPORT_SYMBOL(fence_get_status);
+
+/**
* fence_remove_callback - remove a callback from the signaling list
* @fence: [in] the fence to wait on
* @cb: [in] the callback to remove
--- a/drivers/dma-buf/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -62,29 +62,29 @@ void sync_file_debug_remove(struct sync_
static const char *sync_status_str(int status)
{
- if (status == 0)
- return "signaled";
+ if (status < 0)
+ return "error";
if (status > 0)
- return "active";
+ return "signaled";
- return "error";
+ return "active";
}
-static void sync_print_fence(struct seq_file *s, struct fence *fence, bool show)
+static void sync_print_fence(struct seq_file *s,
+ struct fence *fence, bool show)
{
- int status = 1;
struct sync_timeline *parent = fence_parent(fence);
+ int status;
- if (fence_is_signaled_locked(fence))
- status = fence->status;
+ status = fence_get_status_locked(fence);
seq_printf(s, " %s%sfence %s",
show ? parent->name : "",
show ? "_" : "",
sync_status_str(status));
- if (status <= 0) {
+ if (status) {
struct timespec64 ts64 =
ktime_to_timespec64(fence->timestamp);
@@ -133,7 +133,7 @@ static void sync_print_sync_file(struct
int i;
seq_printf(s, "[%p] %s: %s\n", sync_file, sync_file->name,
- sync_status_str(!fence_is_signaled(sync_file->fence)));
+ sync_status_str(fence_get_status(sync_file->fence)));
if (fence_is_array(sync_file->fence)) {
struct fence_array *array = to_fence_array(sync_file->fence);
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -377,10 +377,8 @@ static void sync_fill_fence_info(struct
sizeof(info->obj_name));
strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
sizeof(info->driver_name));
- if (fence_is_signaled(fence))
- info->status = fence->status >= 0 ? 1 : fence->status;
- else
- info->status = 0;
+
+ info->status = fence_get_status(fence);
info->timestamp_ns = ktime_to_ns(fence->timestamp);
}
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -334,6 +334,30 @@ static inline struct fence *fence_later(
return fence_is_signaled(f2) ? NULL : f2;
}
+/**
+ * fence_get_status_locked - returns the status upon completion
+ * @fence: [in] the fence to query
+ *
+ * Drivers can supply an optional error status condition before they signal
+ * the fence (to indicate whether the fence was completed due to an error
+ * rather than success). The value of the status condition is only valid
+ * if the fence has been signaled, fence_get_status_locked() first checks
+ * the signal state before reporting the error status.
+ *
+ * Returns 0 if the fence has not yet been signaled, 1 if the fence has
+ * been signaled without an error condition, or a negative error code
+ * if the fence has been completed in err.
+ */
+static inline int fence_get_status_locked(struct fence *fence)
+{
+ if (fence_is_signaled_locked(fence))
+ return fence->status < 0 ? fence->status : 1;
+ else
+ return 0;
+}
+
+int fence_get_status(struct fence *fence);
+
signed long fence_wait_timeout(struct fence *, bool intr, signed long timeout);
signed long fence_wait_any_timeout(struct fence **fences, uint32_t count,
bool intr, signed long timeout);
Patches currently in stable-queue which might be from chris(a)chris-wilson.co.uk are
queue-4.9/dma-buf-sw-sync-fix-the-is-signaled-test-to-handle-u32-wraparound.patch
queue-4.9/dma-fence-clear-fence-status-during-dma_fence_init.patch
queue-4.9/dma-buf-sw-sync-fix-locking-around-sync_timeline-lists.patch
queue-4.9/dma-fence-wrap-querying-the-fence-status.patch
queue-4.9/dma-buf-sw_sync-clean-up-list-before-signaling-the-fence.patch
queue-4.9/dma-buf-sw-sync-reduce-irqsave-irqrestore-from-known-context.patch
queue-4.9/dma-buf-sw_sync-move-timeline_fence_ops-around.patch
queue-4.9/dma-buf-sw-sync-prevent-user-overflow-on-timeline-advance.patch
queue-4.9/dma-fence-introduce-drm_fence_set_error-helper.patch
queue-4.9/dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
queue-4.9/dma-buf-sw-sync-use-an-rbtree-to-sort-fences-in-the-timeline.patch
queue-4.9/dma-buf-sw-sync-sync_pt-is-private-and-of-fixed-size.patch
queue-4.9/dma-buf-dma-fence-extract-__dma_fence_is_later.patch
This is a note to let you know that I've just added the patch titled
dma-fence: Introduce drm_fence_set_error() helper
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-fence-introduce-drm_fence_set_error-helper.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From a009e975da5c7d42a7f5eaadc54946eb5f76c9af Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris(a)chris-wilson.co.uk>
Date: Wed, 4 Jan 2017 14:12:22 +0000
Subject: dma-fence: Introduce drm_fence_set_error() helper
From: Chris Wilson <chris(a)chris-wilson.co.uk>
commit a009e975da5c7d42a7f5eaadc54946eb5f76c9af upstream.
The dma_fence.error field (formerly known as dma_fence.status) is an
optional field that may be set by drivers before calling
dma_fence_signal(). The field can be used to indicate that the fence was
completed in err rather than with success, and is visible to other
consumers of the fence and to userspace via sync_file.
This patch renames the field from status to error so that its meaning is
hopefully more clear (and distinct from dma_fence_get_status() which is
a composite between the error state and signal state) and adds a helper
that validates the preconditions of when it is suitable to adjust the
error field.
Signed-off-by: Chris Wilson <chris(a)chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Reviewed-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-3-chris@ch…
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang(a)synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/fence.c | 2 +-
include/linux/fence.h | 30 +++++++++++++++++++++++++-----
2 files changed, 26 insertions(+), 6 deletions(-)
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -551,7 +551,7 @@ fence_init(struct fence *fence, const st
fence->context = context;
fence->seqno = seqno;
fence->flags = 0UL;
- fence->status = 0;
+ fence->error = 0;
trace_fence_init(fence);
}
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -47,7 +47,7 @@ struct fence_cb;
* can be compared to decide which fence would be signaled later.
* @flags: A mask of FENCE_FLAG_* defined below
* @timestamp: Timestamp when the fence was signaled.
- * @status: Optional, only valid if < 0, must be set before calling
+ * @error: Optional, only valid if < 0, must be set before calling
* fence_signal, indicates that the fence has completed with an error.
*
* the flags member must be manipulated and read using the appropriate
@@ -79,7 +79,7 @@ struct fence {
unsigned seqno;
unsigned long flags;
ktime_t timestamp;
- int status;
+ int error;
};
enum fence_flag_bits {
@@ -132,7 +132,7 @@ struct fence_cb {
* or some failure occurred that made it impossible to enable
* signaling. True indicates successful enabling.
*
- * fence->status may be set in enable_signaling, but only when false is
+ * fence->error may be set in enable_signaling, but only when false is
* returned.
*
* Calling fence_signal before enable_signaling is called allows
@@ -144,7 +144,7 @@ struct fence_cb {
* the second time will be a noop since it was already signaled.
*
* Notes on signaled:
- * May set fence->status if returning true.
+ * May set fence->error if returning true.
*
* Notes on wait:
* Must not be NULL, set to fence_default_wait for default implementation.
@@ -351,13 +351,33 @@ static inline struct fence *fence_later(
static inline int fence_get_status_locked(struct fence *fence)
{
if (fence_is_signaled_locked(fence))
- return fence->status < 0 ? fence->status : 1;
+ return fence->error ?: 1;
else
return 0;
}
int fence_get_status(struct fence *fence);
+/**
+ * fence_set_error - flag an error condition on the fence
+ * @fence: [in] the fence
+ * @error: [in] the error to store
+ *
+ * Drivers can supply an optional error status condition before they signal
+ * the fence, to indicate that the fence was completed due to an error
+ * rather than success. This must be set before signaling (so that the value
+ * is visible before any waiters on the signal callback are woken). This
+ * helper exists to help catching erroneous setting of #fence.error.
+ */
+static inline void fence_set_error(struct fence *fence,
+ int error)
+{
+ BUG_ON(test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags));
+ BUG_ON(error >= 0 || error < -MAX_ERRNO);
+
+ fence->error = error;
+}
+
signed long fence_wait_timeout(struct fence *, bool intr, signed long timeout);
signed long fence_wait_any_timeout(struct fence **fences, uint32_t count,
bool intr, signed long timeout);
Patches currently in stable-queue which might be from chris(a)chris-wilson.co.uk are
queue-4.9/dma-buf-sw-sync-fix-the-is-signaled-test-to-handle-u32-wraparound.patch
queue-4.9/dma-fence-clear-fence-status-during-dma_fence_init.patch
queue-4.9/dma-buf-sw-sync-fix-locking-around-sync_timeline-lists.patch
queue-4.9/dma-fence-wrap-querying-the-fence-status.patch
queue-4.9/dma-buf-sw_sync-clean-up-list-before-signaling-the-fence.patch
queue-4.9/dma-buf-sw-sync-reduce-irqsave-irqrestore-from-known-context.patch
queue-4.9/dma-buf-sw_sync-move-timeline_fence_ops-around.patch
queue-4.9/dma-buf-sw-sync-prevent-user-overflow-on-timeline-advance.patch
queue-4.9/dma-fence-introduce-drm_fence_set_error-helper.patch
queue-4.9/dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
queue-4.9/dma-buf-sw-sync-use-an-rbtree-to-sort-fences-in-the-timeline.patch
queue-4.9/dma-buf-sw-sync-sync_pt-is-private-and-of-fixed-size.patch
queue-4.9/dma-buf-dma-fence-extract-__dma_fence_is_later.patch
This is a note to let you know that I've just added the patch titled
dma-fence: Clear fence->status during dma_fence_init()
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-fence-clear-fence-status-during-dma_fence_init.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 83dd1376fd92f33bdeca9e83d479534a4e7f870b Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris(a)chris-wilson.co.uk>
Date: Wed, 4 Jan 2017 14:12:20 +0000
Subject: dma-fence: Clear fence->status during dma_fence_init()
From: Chris Wilson <chris(a)chris-wilson.co.uk>
commit 83dd1376fd92f33bdeca9e83d479534a4e7f870b upstream.
As the fence->status is an optional field that may be set before
dma_fence_signal() is called to convey that the fence completed with an
error, we have to ensure that it is always set to zero on initialisation
so that the typical use (i.e. unset) always flags a successful completion.
Signed-off-by: Chris Wilson <chris(a)chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin(a)intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter(a)ffwll.ch>
Reviewed-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Signed-off-by: Sumit Semwal <sumit.semwal(a)linaro.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20170104141222.6992-1-chris@ch…
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang(a)synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/fence.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -526,6 +526,7 @@ fence_init(struct fence *fence, const st
fence->context = context;
fence->seqno = seqno;
fence->flags = 0UL;
+ fence->status = 0;
trace_fence_init(fence);
}
Patches currently in stable-queue which might be from chris(a)chris-wilson.co.uk are
queue-4.9/dma-buf-sw-sync-fix-the-is-signaled-test-to-handle-u32-wraparound.patch
queue-4.9/dma-fence-clear-fence-status-during-dma_fence_init.patch
queue-4.9/dma-buf-sw-sync-fix-locking-around-sync_timeline-lists.patch
queue-4.9/dma-fence-wrap-querying-the-fence-status.patch
queue-4.9/dma-buf-sw_sync-clean-up-list-before-signaling-the-fence.patch
queue-4.9/dma-buf-sw-sync-reduce-irqsave-irqrestore-from-known-context.patch
queue-4.9/dma-buf-sw_sync-move-timeline_fence_ops-around.patch
queue-4.9/dma-buf-sw-sync-prevent-user-overflow-on-timeline-advance.patch
queue-4.9/dma-fence-introduce-drm_fence_set_error-helper.patch
queue-4.9/dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
queue-4.9/dma-buf-sw-sync-use-an-rbtree-to-sort-fences-in-the-timeline.patch
queue-4.9/dma-buf-sw-sync-sync_pt-is-private-and-of-fixed-size.patch
queue-4.9/dma-buf-dma-fence-extract-__dma_fence_is_later.patch
This is a note to let you know that I've just added the patch titled
dma-buf/sw_sync: force signal all unsignaled fences on dying timeline
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From ea4d5a270b57fa8d4871f372ca9b97b7697fdfda Mon Sep 17 00:00:00 2001
From: Dominik Behr <dbehr(a)chromium.org>
Date: Thu, 7 Sep 2017 16:02:46 -0300
Subject: dma-buf/sw_sync: force signal all unsignaled fences on dying timeline
From: Dominik Behr <dbehr(a)chromium.org>
commit ea4d5a270b57fa8d4871f372ca9b97b7697fdfda upstream.
To avoid hanging userspace components that might have been waiting on the
active fences of the destroyed timeline we need to signal with error all
remaining fences on such timeline.
This restore the default behaviour of the Android sw_sync framework, which
Android still relies on. It was broken on the dma fence conversion a few
years ago and never fixed.
v2: Do not bother with cleanup do the list (Chris Wilson)
Reviewed-by: Chris Wilson <chris(a)chris-wilson.co.uk>
Signed-off-by: Dominik Behr <dbehr(a)chromium.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan(a)collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170907190246.16425-2-gustav…
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang(a)synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/sw_sync.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -321,8 +321,16 @@ static int sw_sync_debugfs_open(struct i
static int sw_sync_debugfs_release(struct inode *inode, struct file *file)
{
struct sync_timeline *obj = file->private_data;
+ struct sync_pt *pt, *next;
- smp_wmb();
+ spin_lock_irq(&obj->lock);
+
+ list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
+ fence_set_error(&pt->base, -ENOENT);
+ fence_signal_locked(&pt->base);
+ }
+
+ spin_unlock_irq(&obj->lock);
sync_timeline_put(obj);
return 0;
Patches currently in stable-queue which might be from dbehr(a)chromium.org are
queue-4.9/dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
This is a note to let you know that I've just added the patch titled
dma-buf/sw_sync: clean up list before signaling the fence
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-sw_sync-clean-up-list-before-signaling-the-fence.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 3792b7c1a70815fe4e954221c096f9278638fd21 Mon Sep 17 00:00:00 2001
From: Gustavo Padovan <gustavo.padovan(a)collabora.com>
Date: Sat, 29 Jul 2017 12:22:16 -0300
Subject: dma-buf/sw_sync: clean up list before signaling the fence
From: Gustavo Padovan <gustavo.padovan(a)collabora.com>
commit 3792b7c1a70815fe4e954221c096f9278638fd21 upstream.
If userspace already dropped its own reference by closing the sw_sync
fence fd we might end up in a deadlock where
dma_fence_is_signaled_locked() will trigger the release of the fence and
thus try to hold the lock to remove the fence from the list.
dma_fence_is_signaled_locked() tries to release/free the fence and hold
the lock in the process.
We fix that by changing the order operation and clean up the list and
rb-tree first.
v2: Drop fence get/put dance and manipulate the list first (Chris Wilson)
Cc: Chris Wilson <chris(a)chris-wilson.co.uk>
Signed-off-by: Gustavo Padovan <gustavo.padovan(a)collabora.com>
Reviewed-by: Chris Wilson <chris(a)chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20170729152217.8362-2-gustavo…
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang(a)synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/sw_sync.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -213,11 +213,21 @@ static void sync_timeline_signal(struct
obj->value += inc;
list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
- if (!fence_is_signaled_locked(&pt->base))
+ if (!timeline_fence_signaled(&pt->base))
break;
list_del_init(&pt->link);
rb_erase(&pt->node, &obj->pt_tree);
+
+ /*
+ * A signal callback may release the last reference to this
+ * fence, causing it to be freed. That operation has to be
+ * last to avoid a use after free inside this loop, and must
+ * be after we remove the fence from the timeline in order to
+ * prevent deadlocking on timeline->lock inside
+ * timeline_fence_release().
+ */
+ fence_signal_locked(&pt->base);
}
spin_unlock_irq(&obj->lock);
Patches currently in stable-queue which might be from gustavo.padovan(a)collabora.com are
queue-4.9/dma-buf-sw-sync-fix-the-is-signaled-test-to-handle-u32-wraparound.patch
queue-4.9/dma-buf-sw-sync-fix-locking-around-sync_timeline-lists.patch
queue-4.9/dma-buf-sw_sync-clean-up-list-before-signaling-the-fence.patch
queue-4.9/dma-buf-sw-sync-reduce-irqsave-irqrestore-from-known-context.patch
queue-4.9/dma-buf-sw_sync-move-timeline_fence_ops-around.patch
queue-4.9/dma-buf-sw-sync-prevent-user-overflow-on-timeline-advance.patch
queue-4.9/dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
queue-4.9/dma-buf-sw-sync-use-an-rbtree-to-sort-fences-in-the-timeline.patch
queue-4.9/dma-buf-sw-sync-sync_pt-is-private-and-of-fixed-size.patch
queue-4.9/dma-buf-dma-fence-extract-__dma_fence_is_later.patch
This is a note to let you know that I've just added the patch titled
dma-buf/sw-sync: sync_pt is private and of fixed size
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
dma-buf-sw-sync-sync_pt-is-private-and-of-fixed-size.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 3b52ce44e720c240afc4c4b03140d7b7811b23bd Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris(a)chris-wilson.co.uk>
Date: Thu, 29 Jun 2017 13:59:28 +0100
Subject: dma-buf/sw-sync: sync_pt is private and of fixed size
From: Chris Wilson <chris(a)chris-wilson.co.uk>
commit 3b52ce44e720c240afc4c4b03140d7b7811b23bd upstream.
Since sync_pt is only allocated from a single location and is no longer
the base class for fences (that is struct dma_fence) it no longer needs
a generic unsized allocator.
Signed-off-by: Chris Wilson <chris(a)chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal(a)linaro.org>
Cc: Sean Paul <seanpaul(a)chromium.org>
Cc: Gustavo Padovan <gustavo(a)padovan.org>
Reviewed-by: Sean Paul <seanpaul(a)chromium.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan(a)collabora.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170629125930.821-5-chris@chr…
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang(a)synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/dma-buf/sw_sync.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -155,7 +155,6 @@ static void sync_timeline_signal(struct
/**
* sync_pt_create() - creates a sync pt
* @parent: fence's parent sync_timeline
- * @size: size to allocate for this pt
* @inc: value of the fence
*
* Creates a new sync_pt as a child of @parent. @size bytes will be
@@ -163,15 +162,12 @@ static void sync_timeline_signal(struct
* the generic sync_timeline struct. Returns the sync_pt object or
* NULL in case of error.
*/
-static struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size,
- unsigned int value)
+static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
+ unsigned int value)
{
struct sync_pt *pt;
- if (size < sizeof(*pt))
- return NULL;
-
- pt = kzalloc(size, GFP_KERNEL);
+ pt = kzalloc(sizeof(*pt), GFP_KERNEL);
if (!pt)
return NULL;
@@ -312,7 +308,7 @@ static long sw_sync_ioctl_create_fence(s
goto err;
}
- pt = sync_pt_create(obj, sizeof(*pt), data.value);
+ pt = sync_pt_create(obj, data.value);
if (!pt) {
err = -ENOMEM;
goto err;
Patches currently in stable-queue which might be from chris(a)chris-wilson.co.uk are
queue-4.9/dma-buf-sw-sync-fix-the-is-signaled-test-to-handle-u32-wraparound.patch
queue-4.9/dma-fence-clear-fence-status-during-dma_fence_init.patch
queue-4.9/dma-buf-sw-sync-fix-locking-around-sync_timeline-lists.patch
queue-4.9/dma-fence-wrap-querying-the-fence-status.patch
queue-4.9/dma-buf-sw_sync-clean-up-list-before-signaling-the-fence.patch
queue-4.9/dma-buf-sw-sync-reduce-irqsave-irqrestore-from-known-context.patch
queue-4.9/dma-buf-sw_sync-move-timeline_fence_ops-around.patch
queue-4.9/dma-buf-sw-sync-prevent-user-overflow-on-timeline-advance.patch
queue-4.9/dma-fence-introduce-drm_fence_set_error-helper.patch
queue-4.9/dma-buf-sw_sync-force-signal-all-unsignaled-fences-on-dying-timeline.patch
queue-4.9/dma-buf-sw-sync-use-an-rbtree-to-sort-fences-in-the-timeline.patch
queue-4.9/dma-buf-sw-sync-sync_pt-is-private-and-of-fixed-size.patch
queue-4.9/dma-buf-dma-fence-extract-__dma_fence_is_later.patch