All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org, Chris Wilson <chris@chris-wilson.co.uk>
Subject: [PATCH v2] dma-buf/sw_sync: Separate signal/timeline locks
Date: Tue, 14 Jul 2020 21:14:07 +0100	[thread overview]
Message-ID: <20200714201407.28968-1-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20200714200646.14041-2-chris@chris-wilson.co.uk>

Since we decouple the sync_pt from the timeline tree upon release, in
order to allow releasing the sync_pt from a signal callback we need to
separate the sync_pt signaling lock from the timeline tree lock.

v2: Mark up the unlocked read of the current timeline value.

Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 drivers/dma-buf/sw_sync.c    | 33 ++++++++++++++++++++-------------
 drivers/dma-buf/sync_debug.h |  2 ++
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 807c82148062..5851bf7076d0 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -132,24 +132,32 @@ static void timeline_fence_release(struct dma_fence *fence)
 {
 	struct sync_pt *pt = dma_fence_to_sync_pt(fence);
 	struct sync_timeline *parent = dma_fence_parent(fence);
-	unsigned long flags;
 
-	spin_lock_irqsave(fence->lock, flags);
 	if (!list_empty(&pt->link)) {
-		list_del(&pt->link);
-		rb_erase(&pt->node, &parent->pt_tree);
+		unsigned long flags;
+
+		spin_lock_irqsave(&parent->lock, flags);
+		if (!list_empty(&pt->link)) {
+			list_del(&pt->link);
+			rb_erase(&pt->node, &parent->pt_tree);
+		}
+		spin_unlock_irqrestore(&parent->lock, flags);
 	}
-	spin_unlock_irqrestore(fence->lock, flags);
 
 	sync_timeline_put(parent);
 	dma_fence_free(fence);
 }
 
-static bool timeline_fence_signaled(struct dma_fence *fence)
+static int timeline_value(struct dma_fence *fence)
 {
-	struct sync_timeline *parent = dma_fence_parent(fence);
+	return READ_ONCE(dma_fence_parent(fence)->value);
+}
 
-	return !__dma_fence_is_later(fence->seqno, parent->value, fence->ops);
+static bool timeline_fence_signaled(struct dma_fence *fence)
+{
+	return !__dma_fence_is_later(fence->seqno,
+				     timeline_value(fence),
+				     fence->ops);
 }
 
 static bool timeline_fence_enable_signaling(struct dma_fence *fence)
@@ -166,9 +174,7 @@ static void timeline_fence_value_str(struct dma_fence *fence,
 static void timeline_fence_timeline_value_str(struct dma_fence *fence,
 					     char *str, int size)
 {
-	struct sync_timeline *parent = dma_fence_parent(fence);
-
-	snprintf(str, size, "%d", parent->value);
+	snprintf(str, size, "%d", timeline_value(fence));
 }
 
 static const struct dma_fence_ops timeline_fence_ops = {
@@ -252,12 +258,13 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
 		return NULL;
 
 	sync_timeline_get(obj);
-	dma_fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
+	spin_lock_init(&pt->lock);
+	dma_fence_init(&pt->base, &timeline_fence_ops, &pt->lock,
 		       obj->context, value);
 	INIT_LIST_HEAD(&pt->link);
 
 	spin_lock_irq(&obj->lock);
-	if (!dma_fence_is_signaled_locked(&pt->base)) {
+	if (!dma_fence_is_signaled(&pt->base)) {
 		struct rb_node **p = &obj->pt_tree.rb_node;
 		struct rb_node *parent = NULL;
 
diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
index 6176e52ba2d7..fd073fc32329 100644
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -55,11 +55,13 @@ static inline struct sync_timeline *dma_fence_parent(struct dma_fence *fence)
  * @base: base fence object
  * @link: link on the sync timeline's list
  * @node: node in the sync timeline's tree
+ * @lock: fence signaling lock
  */
 struct sync_pt {
 	struct dma_fence base;
 	struct list_head link;
 	struct rb_node node;
+	spinlock_t lock;
 };
 
 extern const struct file_operations sw_sync_debugfs_fops;
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: Chris Wilson <chris@chris-wilson.co.uk>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org,
	Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>,
	Chris Wilson <chris@chris-wilson.co.uk>
Subject: [Intel-gfx] [PATCH v2] dma-buf/sw_sync: Separate signal/timeline locks
Date: Tue, 14 Jul 2020 21:14:07 +0100	[thread overview]
Message-ID: <20200714201407.28968-1-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20200714200646.14041-2-chris@chris-wilson.co.uk>

Since we decouple the sync_pt from the timeline tree upon release, in
order to allow releasing the sync_pt from a signal callback we need to
separate the sync_pt signaling lock from the timeline tree lock.

v2: Mark up the unlocked read of the current timeline value.

Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 drivers/dma-buf/sw_sync.c    | 33 ++++++++++++++++++++-------------
 drivers/dma-buf/sync_debug.h |  2 ++
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 807c82148062..5851bf7076d0 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -132,24 +132,32 @@ static void timeline_fence_release(struct dma_fence *fence)
 {
 	struct sync_pt *pt = dma_fence_to_sync_pt(fence);
 	struct sync_timeline *parent = dma_fence_parent(fence);
-	unsigned long flags;
 
-	spin_lock_irqsave(fence->lock, flags);
 	if (!list_empty(&pt->link)) {
-		list_del(&pt->link);
-		rb_erase(&pt->node, &parent->pt_tree);
+		unsigned long flags;
+
+		spin_lock_irqsave(&parent->lock, flags);
+		if (!list_empty(&pt->link)) {
+			list_del(&pt->link);
+			rb_erase(&pt->node, &parent->pt_tree);
+		}
+		spin_unlock_irqrestore(&parent->lock, flags);
 	}
-	spin_unlock_irqrestore(fence->lock, flags);
 
 	sync_timeline_put(parent);
 	dma_fence_free(fence);
 }
 
-static bool timeline_fence_signaled(struct dma_fence *fence)
+static int timeline_value(struct dma_fence *fence)
 {
-	struct sync_timeline *parent = dma_fence_parent(fence);
+	return READ_ONCE(dma_fence_parent(fence)->value);
+}
 
-	return !__dma_fence_is_later(fence->seqno, parent->value, fence->ops);
+static bool timeline_fence_signaled(struct dma_fence *fence)
+{
+	return !__dma_fence_is_later(fence->seqno,
+				     timeline_value(fence),
+				     fence->ops);
 }
 
 static bool timeline_fence_enable_signaling(struct dma_fence *fence)
@@ -166,9 +174,7 @@ static void timeline_fence_value_str(struct dma_fence *fence,
 static void timeline_fence_timeline_value_str(struct dma_fence *fence,
 					     char *str, int size)
 {
-	struct sync_timeline *parent = dma_fence_parent(fence);
-
-	snprintf(str, size, "%d", parent->value);
+	snprintf(str, size, "%d", timeline_value(fence));
 }
 
 static const struct dma_fence_ops timeline_fence_ops = {
@@ -252,12 +258,13 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj,
 		return NULL;
 
 	sync_timeline_get(obj);
-	dma_fence_init(&pt->base, &timeline_fence_ops, &obj->lock,
+	spin_lock_init(&pt->lock);
+	dma_fence_init(&pt->base, &timeline_fence_ops, &pt->lock,
 		       obj->context, value);
 	INIT_LIST_HEAD(&pt->link);
 
 	spin_lock_irq(&obj->lock);
-	if (!dma_fence_is_signaled_locked(&pt->base)) {
+	if (!dma_fence_is_signaled(&pt->base)) {
 		struct rb_node **p = &obj->pt_tree.rb_node;
 		struct rb_node *parent = NULL;
 
diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h
index 6176e52ba2d7..fd073fc32329 100644
--- a/drivers/dma-buf/sync_debug.h
+++ b/drivers/dma-buf/sync_debug.h
@@ -55,11 +55,13 @@ static inline struct sync_timeline *dma_fence_parent(struct dma_fence *fence)
  * @base: base fence object
  * @link: link on the sync timeline's list
  * @node: node in the sync timeline's tree
+ * @lock: fence signaling lock
  */
 struct sync_pt {
 	struct dma_fence base;
 	struct list_head link;
 	struct rb_node node;
+	spinlock_t lock;
 };
 
 extern const struct file_operations sw_sync_debugfs_fops;
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2020-07-14 20:14 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-14 20:06 [PATCH 1/3] dma-buf/sw_sync: Avoid recursive lock during fence signal Chris Wilson
2020-07-14 20:06 ` [Intel-gfx] " Chris Wilson
2020-07-14 20:06 ` Chris Wilson
2020-07-14 20:06 ` [PATCH 2/3] dma-buf/sw_sync: Separate signal/timeline locks Chris Wilson
2020-07-14 20:06   ` [Intel-gfx] " Chris Wilson
2020-07-14 20:14   ` Chris Wilson [this message]
2020-07-14 20:14     ` [Intel-gfx] [PATCH v2] " Chris Wilson
2020-07-14 20:06 ` [PATCH 3/3] dma-buf/selftests: Add locking selftests for sw_sync Chris Wilson
2020-07-14 20:06   ` [Intel-gfx] " Chris Wilson
2020-07-14 20:29   ` Bas Nieuwenhuizen
2020-07-14 20:29     ` [Intel-gfx] " Bas Nieuwenhuizen
2020-07-14 20:14 ` [PATCH 1/3] dma-buf/sw_sync: Avoid recursive lock during fence signal Bas Nieuwenhuizen
2020-07-14 20:14   ` [Intel-gfx] " Bas Nieuwenhuizen
2020-07-14 20:14   ` Bas Nieuwenhuizen
2020-07-14 20:27 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/3] dma-buf/sw_sync: Avoid recursive lock during fence signal. (rev2) Patchwork
2020-07-14 20:49 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2020-07-15  8:57 ` [PATCH 1/3] dma-buf/sw_sync: Avoid recursive lock during fence signal Christian König
2020-07-15  8:57   ` [Intel-gfx] " Christian König
2020-07-15  8:57   ` Christian König

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=20200714201407.28968-1-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.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.