From: <gregkh@linuxfoundation.org>
To: chris@chris-wilson.co.uk, Jisheng.Zhang@synaptics.com,
gregkh@linuxfoundation.org, gustavo.padovan@collabora.com,
gustavo@padovan.org, seanpaul@chromium.org,
sumit.semwal@linaro.org
Cc: <stable@vger.kernel.org>, <stable-commits@vger.kernel.org>
Subject: Patch "dma-buf/sw-sync: Fix locking around sync_timeline lists" has been added to the 4.9-stable tree
Date: Thu, 07 Dec 2017 11:54:15 +0100 [thread overview]
Message-ID: <151264405516238@kroah.com> (raw)
This is a note to let you know that I've just added the patch titled
dma-buf/sw-sync: Fix locking around sync_timeline lists
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=summary
The filename of the patch is:
dma-buf-sw-sync-fix-locking-around-sync_timeline-lists.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@vger.kernel.org> know about it.
>From d3862e44daa7a0c94d2f6193502a8c49379acfce Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Thu, 29 Jun 2017 22:05:32 +0100
Subject: dma-buf/sw-sync: Fix locking around sync_timeline lists
From: Chris Wilson <chris@chris-wilson.co.uk>
commit d3862e44daa7a0c94d2f6193502a8c49379acfce upstream.
The sync_pt were not adding themselves atomically to the timeline lists,
corruption imminent. Only a single list is required to track the
unsignaled sync_pt, so reduce it and rename the lock more appropriately
along with using idiomatic names to distinguish a list from links along
it.
v2: Prevent spinlock recursion on free during create (next patch) and
fixup crossref in kerneldoc
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170629210532.5617-1-chris@chris-wilson.co.uk
[s/dma_fence/fence/g - gregkh]
Cc: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/dma-buf/sw_sync.c | 48 +++++++++++++++++--------------------------
drivers/dma-buf/sync_debug.c | 9 +++-----
drivers/dma-buf/sync_debug.h | 22 +++++++------------
3 files changed, 31 insertions(+), 48 deletions(-)
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -96,9 +96,8 @@ struct sync_timeline *sync_timeline_crea
obj->context = fence_context_alloc(1);
strlcpy(obj->name, name, sizeof(obj->name));
- INIT_LIST_HEAD(&obj->child_list_head);
- INIT_LIST_HEAD(&obj->active_list_head);
- spin_lock_init(&obj->child_list_lock);
+ INIT_LIST_HEAD(&obj->pt_list);
+ spin_lock_init(&obj->lock);
sync_timeline_debug_add(obj);
@@ -139,17 +138,15 @@ static void sync_timeline_signal(struct
trace_sync_timeline(obj);
- spin_lock_irq(&obj->child_list_lock);
+ spin_lock_irq(&obj->lock);
obj->value += inc;
- list_for_each_entry_safe(pt, next, &obj->active_list_head,
- active_list) {
+ list_for_each_entry_safe(pt, next, &obj->pt_list, link)
if (fence_is_signaled_locked(&pt->base))
- list_del_init(&pt->active_list);
- }
+ list_del_init(&pt->link);
- spin_unlock_irq(&obj->child_list_lock);
+ spin_unlock_irq(&obj->lock);
}
/**
@@ -171,15 +168,15 @@ static struct sync_pt *sync_pt_create(st
if (!pt)
return NULL;
- spin_lock_irq(&obj->child_list_lock);
-
sync_timeline_get(obj);
- fence_init(&pt->base, &timeline_fence_ops, &obj->child_list_lock,
+ fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
obj->context, value);
- list_add_tail(&pt->child_list, &obj->child_list_head);
- INIT_LIST_HEAD(&pt->active_list);
+ INIT_LIST_HEAD(&pt->link);
- spin_unlock_irq(&obj->child_list_lock);
+ spin_lock_irq(&obj->lock);
+ if (!fence_is_signaled_locked(&pt->base))
+ list_add_tail(&pt->link, &obj->pt_list);
+ spin_unlock_irq(&obj->lock);
return pt;
}
@@ -200,15 +197,15 @@ static void timeline_fence_release(struc
{
struct sync_pt *pt = fence_to_sync_pt(fence);
struct sync_timeline *parent = fence_parent(fence);
- unsigned long flags;
- spin_lock_irqsave(fence->lock, flags);
+ if (!list_empty(&pt->link)) {
+ unsigned long flags;
- list_del(&pt->child_list);
- if (!list_empty(&pt->active_list))
- list_del(&pt->active_list);
-
- spin_unlock_irqrestore(fence->lock, flags);
+ spin_lock_irqsave(fence->lock, flags);
+ if (!list_empty(&pt->link))
+ list_del(&pt->link);
+ spin_unlock_irqrestore(fence->lock, flags);
+ }
sync_timeline_put(parent);
fence_free(fence);
@@ -223,13 +220,6 @@ static bool timeline_fence_signaled(stru
static bool timeline_fence_enable_signaling(struct fence *fence)
{
- struct sync_pt *pt = fence_to_sync_pt(fence);
- struct sync_timeline *parent = fence_parent(fence);
-
- if (timeline_fence_signaled(fence))
- return false;
-
- list_add_tail(&pt->active_list, &parent->active_list_head);
return true;
}
--- a/drivers/dma-buf/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -119,13 +119,12 @@ static void sync_print_obj(struct seq_fi
seq_printf(s, "%s: %d\n", obj->name, obj->value);
- spin_lock_irq(&obj->child_list_lock);
- list_for_each(pos, &obj->child_list_head) {
- struct sync_pt *pt =
- container_of(pos, struct sync_pt, child_list);
+ spin_lock_irq(&obj->lock);
+ list_for_each(pos, &obj->pt_list) {
+ struct sync_pt *pt = container_of(pos, struct sync_pt, link);
sync_print_fence(s, &pt->base, false);
}
- spin_unlock_irq(&obj->child_list_lock);
+ spin_unlock_irq(&obj->lock);
}
static void sync_print_sync_file(struct seq_file *s,
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -24,43 +24,37 @@
* struct sync_timeline - sync object
* @kref: reference count on fence.
* @name: name of the sync_timeline. Useful for debugging
- * @child_list_head: list of children sync_pts for this sync_timeline
- * @child_list_lock: lock protecting @child_list_head and fence.status
- * @active_list_head: list of active (unsignaled/errored) sync_pts
+ * @lock: lock protecting @pt_list and @value
+ * @pt_list: list of active (unsignaled/errored) sync_pts
* @sync_timeline_list: membership in global sync_timeline_list
*/
struct sync_timeline {
struct kref kref;
char name[32];
- /* protected by child_list_lock */
+ /* protected by lock */
u64 context;
int value;
- struct list_head child_list_head;
- spinlock_t child_list_lock;
-
- struct list_head active_list_head;
+ struct list_head pt_list;
+ spinlock_t lock;
struct list_head sync_timeline_list;
};
static inline struct sync_timeline *fence_parent(struct fence *fence)
{
- return container_of(fence->lock, struct sync_timeline,
- child_list_lock);
+ return container_of(fence->lock, struct sync_timeline, lock);
}
/**
* struct sync_pt - sync_pt object
* @base: base fence object
- * @child_list: sync timeline child's list
- * @active_list: sync timeline active child's list
+ * @link: link on the sync timeline's list
*/
struct sync_pt {
struct fence base;
- struct list_head child_list;
- struct list_head active_list;
+ struct list_head link;
};
#ifdef CONFIG_SW_SYNC
Patches currently in stable-queue which might be from chris@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
reply other threads:[~2017-12-07 10:54 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=151264405516238@kroah.com \
--to=gregkh@linuxfoundation.org \
--cc=Jisheng.Zhang@synaptics.com \
--cc=chris@chris-wilson.co.uk \
--cc=gustavo.padovan@collabora.com \
--cc=gustavo@padovan.org \
--cc=seanpaul@chromium.org \
--cc=stable-commits@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=sumit.semwal@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.