All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/10] dma-buf: add new dma_fence_chain container v4
@ 2018-12-11 10:34 Chunming Zhou
  2018-12-11 10:34 ` [PATCH 02/10] drm/syncobj: remove drm_syncobj_cb and cleanup Chunming Zhou
                   ` (12 more replies)
  0 siblings, 13 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx
  Cc: Christian König, Christian König

From: Christian König <ckoenig.leichtzumerken@gmail.com>

Lockless container implementation similar to a dma_fence_array, but with
only two elements per node and automatic garbage collection.

v2: properly document dma_fence_chain_for_each, add dma_fence_chain_find_seqno,
    drop prev reference during garbage collection if it's not a chain fence.
v3: use head and iterator for dma_fence_chain_for_each
v4: fix reference count in dma_fence_chain_enable_signaling

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/dma-buf/Makefile          |   3 +-
 drivers/dma-buf/dma-fence-chain.c | 241 ++++++++++++++++++++++++++++++
 include/linux/dma-fence-chain.h   |  81 ++++++++++
 3 files changed, 324 insertions(+), 1 deletion(-)
 create mode 100644 drivers/dma-buf/dma-fence-chain.c
 create mode 100644 include/linux/dma-fence-chain.h

diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 0913a6ccab5a..1f006e083eb9 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,4 +1,5 @@
-obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o
+obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
+	 reservation.o seqno-fence.o
 obj-$(CONFIG_SYNC_FILE)		+= sync_file.o
 obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o
 obj-$(CONFIG_UDMABUF)		+= udmabuf.o
diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
new file mode 100644
index 000000000000..0c5e3c902fa0
--- /dev/null
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -0,0 +1,241 @@
+/*
+ * fence-chain: chain fences together in a timeline
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ * Authors:
+ *	Christian König <christian.koenig@amd.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/dma-fence-chain.h>
+
+static bool dma_fence_chain_enable_signaling(struct dma_fence *fence);
+
+/**
+ * dma_fence_chain_get_prev - use RCU to get a reference to the previous fence
+ * @chain: chain node to get the previous node from
+ *
+ * Use dma_fence_get_rcu_safe to get a reference to the previous fence of the
+ * chain node.
+ */
+static struct dma_fence *dma_fence_chain_get_prev(struct dma_fence_chain *chain)
+{
+	struct dma_fence *prev;
+
+	rcu_read_lock();
+	prev = dma_fence_get_rcu_safe(&chain->prev);
+	rcu_read_unlock();
+	return prev;
+}
+
+/**
+ * dma_fence_chain_walk - chain walking function
+ * @fence: current chain node
+ *
+ * Walk the chain to the next node. Returns the next fence or NULL if we are at
+ * the end of the chain. Garbage collects chain nodes which are already
+ * signaled.
+ */
+struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
+{
+	struct dma_fence_chain *chain, *prev_chain;
+	struct dma_fence *prev, *replacement, *tmp;
+
+	chain = to_dma_fence_chain(fence);
+	if (!chain) {
+		dma_fence_put(fence);
+		return NULL;
+	}
+
+	while ((prev = dma_fence_chain_get_prev(chain))) {
+
+		prev_chain = to_dma_fence_chain(prev);
+		if (prev_chain) {
+			if (!dma_fence_is_signaled(prev_chain->fence))
+				break;
+
+			replacement = dma_fence_chain_get_prev(prev_chain);
+		} else {
+			if (!dma_fence_is_signaled(prev))
+				break;
+
+			replacement = NULL;
+		}
+
+		tmp = cmpxchg(&chain->prev, prev, replacement);
+		if (tmp == prev)
+			dma_fence_put(tmp);
+		else
+			dma_fence_put(replacement);
+		dma_fence_put(prev);
+	}
+
+	dma_fence_put(fence);
+	return prev;
+}
+EXPORT_SYMBOL(dma_fence_chain_walk);
+
+/**
+ * dma_fence_chain_find_seqno - find fence chain node by seqno
+ * @pfence: pointer to the chain node where to start
+ * @seqno: the sequence number to search for
+ *
+ * Advance the fence pointer to the chain node which will signal this sequence
+ * number. If no sequence number is provided then this is a no-op.
+ *
+ * Returns EINVAL if the fence is not a chain node or the sequence number has
+ * not yet advanced far enough.
+ */
+int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)
+{
+	struct dma_fence_chain *chain;
+
+	if (!seqno)
+		return 0;
+
+	chain = to_dma_fence_chain(*pfence);
+	if (!chain || chain->base.seqno < seqno)
+		return -EINVAL;
+
+	dma_fence_chain_for_each(*pfence, &chain->base) {
+		if ((*pfence)->context != chain->base.context ||
+		    to_dma_fence_chain(*pfence)->prev_seqno < seqno)
+			break;
+	}
+	dma_fence_put(&chain->base);
+
+	return 0;
+}
+EXPORT_SYMBOL(dma_fence_chain_find_seqno);
+
+static const char *dma_fence_chain_get_driver_name(struct dma_fence *fence)
+{
+        return "dma_fence_chain";
+}
+
+static const char *dma_fence_chain_get_timeline_name(struct dma_fence *fence)
+{
+        return "unbound";
+}
+
+static void dma_fence_chain_irq_work(struct irq_work *work)
+{
+	struct dma_fence_chain *chain;
+
+	chain = container_of(work, typeof(*chain), work);
+
+	/* Try to rearm the callback */
+	if (!dma_fence_chain_enable_signaling(&chain->base))
+		/* Ok, we are done. No more unsignaled fences left */
+		dma_fence_signal(&chain->base);
+	dma_fence_put(&chain->base);
+}
+
+static void dma_fence_chain_cb(struct dma_fence *f, struct dma_fence_cb *cb)
+{
+	struct dma_fence_chain *chain;
+
+	chain = container_of(cb, typeof(*chain), cb);
+	irq_work_queue(&chain->work);
+	dma_fence_put(f);
+}
+
+static bool dma_fence_chain_enable_signaling(struct dma_fence *fence)
+{
+	struct dma_fence_chain *head = to_dma_fence_chain(fence);
+
+	dma_fence_get(&head->base);
+	dma_fence_chain_for_each(fence, &head->base) {
+		struct dma_fence_chain *chain = to_dma_fence_chain(fence);
+		struct dma_fence *f = chain ? chain->fence : fence;
+
+		dma_fence_get(f);
+		if (!dma_fence_add_callback(f, &head->cb, dma_fence_chain_cb)) {
+			dma_fence_put(fence);
+			return true;
+		}
+		dma_fence_put(f);
+	}
+	dma_fence_put(&head->base);
+	return false;
+}
+
+static bool dma_fence_chain_signaled(struct dma_fence *fence)
+{
+	dma_fence_chain_for_each(fence, fence) {
+		struct dma_fence_chain *chain = to_dma_fence_chain(fence);
+		struct dma_fence *f = chain ? chain->fence : fence;
+
+		if (!dma_fence_is_signaled(f)) {
+			dma_fence_put(fence);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static void dma_fence_chain_release(struct dma_fence *fence)
+{
+	struct dma_fence_chain *chain = to_dma_fence_chain(fence);
+
+	dma_fence_put(chain->prev);
+	dma_fence_put(chain->fence);
+	dma_fence_free(fence);
+}
+
+const struct dma_fence_ops dma_fence_chain_ops = {
+	.get_driver_name = dma_fence_chain_get_driver_name,
+	.get_timeline_name = dma_fence_chain_get_timeline_name,
+	.enable_signaling = dma_fence_chain_enable_signaling,
+	.signaled = dma_fence_chain_signaled,
+	.release = dma_fence_chain_release,
+};
+EXPORT_SYMBOL(dma_fence_chain_ops);
+
+/**
+ * dma_fence_chain_init - initialize a fence chain
+ * @chain: the chain node to initialize
+ * @prev: the previous fence
+ * @fence: the current fence
+ *
+ * Initialize a new chain node and either start a new chain or add the node to
+ * the existing chain of the previous fence.
+ */
+void dma_fence_chain_init(struct dma_fence_chain *chain,
+			  struct dma_fence *prev,
+			  struct dma_fence *fence,
+			  uint64_t seqno)
+{
+	struct dma_fence_chain *prev_chain = to_dma_fence_chain(prev);
+	uint64_t context;
+
+	spin_lock_init(&chain->lock);
+	chain->prev = prev;
+	chain->fence = fence;
+	chain->prev_seqno = 0;
+	init_irq_work(&chain->work, dma_fence_chain_irq_work);
+
+	/* Try to reuse the context of the previous chain node. */
+	if (prev_chain && __dma_fence_is_later(seqno, prev->seqno)) {
+		context = prev->context;
+		chain->prev_seqno = prev->seqno;
+	} else {
+		context = dma_fence_context_alloc(1);
+		/* Make sure that we always have a valid sequence number. */
+		if (prev_chain)
+			seqno = max(prev->seqno, seqno);
+	}
+
+	dma_fence_init(&chain->base, &dma_fence_chain_ops,
+		       &chain->lock, context, seqno);
+}
+EXPORT_SYMBOL(dma_fence_chain_init);
diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h
new file mode 100644
index 000000000000..a5c2e8c6915c
--- /dev/null
+++ b/include/linux/dma-fence-chain.h
@@ -0,0 +1,81 @@
+/*
+ * fence-chain: chain fences together in a timeline
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ * Authors:
+ *	Christian König <christian.koenig@amd.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.
+ */
+
+#ifndef __LINUX_DMA_FENCE_CHAIN_H
+#define __LINUX_DMA_FENCE_CHAIN_H
+
+#include <linux/dma-fence.h>
+#include <linux/irq_work.h>
+
+/**
+ * struct dma_fence_chain - fence to represent an node of a fence chain
+ * @base: fence base class
+ * @lock: spinlock for fence handling
+ * @prev: previous fence of the chain
+ * @prev_seqno: original previous seqno before garbage collection
+ * @fence: encapsulated fence
+ * @cb: callback structure for signaling
+ * @work: irq work item for signaling
+ */
+struct dma_fence_chain {
+	struct dma_fence base;
+	spinlock_t lock;
+	struct dma_fence *prev;
+	u64 prev_seqno;
+	struct dma_fence *fence;
+	struct dma_fence_cb cb;
+	struct irq_work work;
+};
+
+extern const struct dma_fence_ops dma_fence_chain_ops;
+
+/**
+ * to_dma_fence_chain - cast a fence to a dma_fence_chain
+ * @fence: fence to cast to a dma_fence_array
+ *
+ * Returns NULL if the fence is not a dma_fence_chain,
+ * or the dma_fence_chain otherwise.
+ */
+static inline struct dma_fence_chain *
+to_dma_fence_chain(struct dma_fence *fence)
+{
+	if (!fence || fence->ops != &dma_fence_chain_ops)
+		return NULL;
+
+	return container_of(fence, struct dma_fence_chain, base);
+}
+
+/**
+ * dma_fence_chain_for_each - iterate over all fences in chain
+ * @iter: current fence
+ * @head: starting point
+ *
+ * Iterate over all fences in the chain. We keep a reference to the current
+ * fence while inside the loop which must be dropped when breaking out.
+ */
+#define dma_fence_chain_for_each(iter, head)	\
+	for (iter = dma_fence_get(head); iter; \
+	     iter = dma_fence_chain_walk(head))
+
+struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence);
+int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno);
+void dma_fence_chain_init(struct dma_fence_chain *chain,
+			  struct dma_fence *prev,
+			  struct dma_fence *fence,
+			  uint64_t seqno);
+
+#endif /* __LINUX_DMA_FENCE_CHAIN_H */
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/10] drm/syncobj: remove drm_syncobj_cb and cleanup
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-11 10:34 ` [PATCH 03/10] drm/syncobj: add new drm_syncobj_add_point interface v3 Chunming Zhou
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx
  Cc: Christian König, Christian König

From: Christian König <ckoenig.leichtzumerken@gmail.com>

This completes "drm/syncobj: Drop add/remove_callback from driver
interface" and cleans up the implementation a bit.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/drm_syncobj.c | 91 ++++++++++++-----------------------
 include/drm/drm_syncobj.h     | 21 --------
 2 files changed, 30 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index db30a0e89db8..e19525af0cce 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -56,6 +56,16 @@
 #include "drm_internal.h"
 #include <drm/drm_syncobj.h>
 
+struct syncobj_wait_entry {
+	struct list_head node;
+	struct task_struct *task;
+	struct dma_fence *fence;
+	struct dma_fence_cb fence_cb;
+};
+
+static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
+				      struct syncobj_wait_entry *wait);
+
 /**
  * drm_syncobj_find - lookup and reference a sync object.
  * @file_private: drm file private pointer
@@ -82,58 +92,33 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 }
 EXPORT_SYMBOL(drm_syncobj_find);
 
-static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj,
-					    struct drm_syncobj_cb *cb,
-					    drm_syncobj_func_t func)
+static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
+				       struct syncobj_wait_entry *wait)
 {
-	cb->func = func;
-	list_add_tail(&cb->node, &syncobj->cb_list);
-}
-
-static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
-						 struct dma_fence **fence,
-						 struct drm_syncobj_cb *cb,
-						 drm_syncobj_func_t func)
-{
-	int ret;
-
-	*fence = drm_syncobj_fence_get(syncobj);
-	if (*fence)
-		return 1;
+	if (wait->fence)
+		return;
 
 	spin_lock(&syncobj->lock);
 	/* We've already tried once to get a fence and failed.  Now that we
 	 * have the lock, try one more time just to be sure we don't add a
 	 * callback when a fence has already been set.
 	 */
-	if (syncobj->fence) {
-		*fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
-								 lockdep_is_held(&syncobj->lock)));
-		ret = 1;
-	} else {
-		*fence = NULL;
-		drm_syncobj_add_callback_locked(syncobj, cb, func);
-		ret = 0;
-	}
+	if (syncobj->fence)
+		wait->fence = dma_fence_get(
+			rcu_dereference_protected(syncobj->fence, 1));
+	else
+		list_add_tail(&wait->node, &syncobj->cb_list);
 	spin_unlock(&syncobj->lock);
-
-	return ret;
 }
 
-void drm_syncobj_add_callback(struct drm_syncobj *syncobj,
-			      struct drm_syncobj_cb *cb,
-			      drm_syncobj_func_t func)
+static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
+				    struct syncobj_wait_entry *wait)
 {
-	spin_lock(&syncobj->lock);
-	drm_syncobj_add_callback_locked(syncobj, cb, func);
-	spin_unlock(&syncobj->lock);
-}
+	if (!wait->node.next)
+		return;
 
-void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
-				 struct drm_syncobj_cb *cb)
-{
 	spin_lock(&syncobj->lock);
-	list_del_init(&cb->node);
+	list_del_init(&wait->node);
 	spin_unlock(&syncobj->lock);
 }
 
@@ -148,7 +133,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
 			       struct dma_fence *fence)
 {
 	struct dma_fence *old_fence;
-	struct drm_syncobj_cb *cur, *tmp;
+	struct syncobj_wait_entry *cur, *tmp;
 
 	if (fence)
 		dma_fence_get(fence);
@@ -162,7 +147,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
 	if (fence != old_fence) {
 		list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
 			list_del_init(&cur->node);
-			cur->func(syncobj, cur);
+			syncobj_wait_syncobj_func(syncobj, cur);
 		}
 	}
 
@@ -608,13 +593,6 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
 					&args->handle);
 }
 
-struct syncobj_wait_entry {
-	struct task_struct *task;
-	struct dma_fence *fence;
-	struct dma_fence_cb fence_cb;
-	struct drm_syncobj_cb syncobj_cb;
-};
-
 static void syncobj_wait_fence_func(struct dma_fence *fence,
 				    struct dma_fence_cb *cb)
 {
@@ -625,11 +603,8 @@ static void syncobj_wait_fence_func(struct dma_fence *fence,
 }
 
 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
-				      struct drm_syncobj_cb *cb)
+				      struct syncobj_wait_entry *wait)
 {
-	struct syncobj_wait_entry *wait =
-		container_of(cb, struct syncobj_wait_entry, syncobj_cb);
-
 	/* This happens inside the syncobj lock */
 	wait->fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
 							      lockdep_is_held(&syncobj->lock)));
@@ -688,12 +663,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 	 */
 
 	if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
-		for (i = 0; i < count; ++i) {
-			drm_syncobj_fence_get_or_add_callback(syncobjs[i],
-							      &entries[i].fence,
-							      &entries[i].syncobj_cb,
-							      syncobj_wait_syncobj_func);
-		}
+		for (i = 0; i < count; ++i)
+			drm_syncobj_fence_add_wait(syncobjs[i], &entries[i]);
 	}
 
 	do {
@@ -742,9 +713,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 
 cleanup_entries:
 	for (i = 0; i < count; ++i) {
-		if (entries[i].syncobj_cb.func)
-			drm_syncobj_remove_callback(syncobjs[i],
-						    &entries[i].syncobj_cb);
+		drm_syncobj_remove_wait(syncobjs[i], &entries[i]);
 		if (entries[i].fence_cb.func)
 			dma_fence_remove_callback(entries[i].fence,
 						  &entries[i].fence_cb);
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index b1fe921f8e8f..7c6ed845c70d 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -28,8 +28,6 @@
 
 #include "linux/dma-fence.h"
 
-struct drm_syncobj_cb;
-
 /**
  * struct drm_syncobj - sync object.
  *
@@ -62,25 +60,6 @@ struct drm_syncobj {
 	struct file *file;
 };
 
-typedef void (*drm_syncobj_func_t)(struct drm_syncobj *syncobj,
-				   struct drm_syncobj_cb *cb);
-
-/**
- * struct drm_syncobj_cb - callback for drm_syncobj_add_callback
- * @node: used by drm_syncob_add_callback to append this struct to
- *	  &drm_syncobj.cb_list
- * @func: drm_syncobj_func_t to call
- *
- * This struct will be initialized by drm_syncobj_add_callback, additional
- * data can be passed along by embedding drm_syncobj_cb in another struct.
- * The callback will get called the next time drm_syncobj_replace_fence is
- * called.
- */
-struct drm_syncobj_cb {
-	struct list_head node;
-	drm_syncobj_func_t func;
-};
-
 void drm_syncobj_free(struct kref *kref);
 
 /**
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/10] drm/syncobj: add new drm_syncobj_add_point interface v3
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
  2018-12-11 10:34 ` [PATCH 02/10] drm/syncobj: remove drm_syncobj_cb and cleanup Chunming Zhou
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-11 10:34 ` [PATCH 04/10] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx
  Cc: Christian König, Christian König

From: Christian König <ckoenig.leichtzumerken@gmail.com>

Use the dma_fence_chain object to create a timeline of fence objects
instead of just replacing the existing fence.

v2: rebase and cleanup
v3: fix garbage collection parameters

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/drm_syncobj.c | 37 +++++++++++++++++++++++++++++++++++
 include/drm/drm_syncobj.h     |  5 +++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index e19525af0cce..2b8a744fbbb6 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -122,6 +122,43 @@ static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
 	spin_unlock(&syncobj->lock);
 }
 
+/**
+ * drm_syncobj_add_point - add new timeline point to the syncobj
+ * @syncobj: sync object to add timeline point do
+ * @chain: chain node to use to add the point
+ * @fence: fence to encapsulate in the chain node
+ * @point: sequence number to use for the point
+ *
+ * Add the chain node as new timeline point to the syncobj.
+ */
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+			   struct dma_fence_chain *chain,
+			   struct dma_fence *fence,
+			   uint64_t point)
+{
+	struct syncobj_wait_entry *cur, *tmp;
+	struct dma_fence *prev;
+
+	dma_fence_get(fence);
+
+	spin_lock(&syncobj->lock);
+
+	prev = drm_syncobj_fence_get(syncobj);
+	dma_fence_chain_init(chain, prev, fence, point);
+	rcu_assign_pointer(syncobj->fence, &chain->base);
+
+	list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
+		list_del_init(&cur->node);
+		syncobj_wait_syncobj_func(syncobj, cur);
+	}
+	spin_unlock(&syncobj->lock);
+
+	/* Walk the chain once to trigger garbage collection */
+	dma_fence_chain_for_each(fence, prev);
+	dma_fence_put(prev);
+}
+EXPORT_SYMBOL(drm_syncobj_add_point);
+
 /**
  * drm_syncobj_replace_fence - replace fence in a sync object.
  * @syncobj: Sync object to replace fence in
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index 7c6ed845c70d..8acb4ae4f311 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -27,6 +27,7 @@
 #define __DRM_SYNCOBJ_H__
 
 #include "linux/dma-fence.h"
+#include "linux/dma-fence-chain.h"
 
 /**
  * struct drm_syncobj - sync object.
@@ -110,6 +111,10 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 				     u32 handle);
+void drm_syncobj_add_point(struct drm_syncobj *syncobj,
+			   struct dma_fence_chain *chain,
+			   struct dma_fence *fence,
+			   uint64_t point);
 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
 			       struct dma_fence *fence);
 int drm_syncobj_find_fence(struct drm_file *file_private,
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/10] drm/syncobj: add support for timeline point wait v8
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
  2018-12-11 10:34 ` [PATCH 02/10] drm/syncobj: remove drm_syncobj_cb and cleanup Chunming Zhou
  2018-12-11 10:34 ` [PATCH 03/10] drm/syncobj: add new drm_syncobj_add_point interface v3 Chunming Zhou
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-11 10:34 ` [PATCH 05/10] drm/syncobj: add timeline payload query ioctl v4 Chunming Zhou
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx
  Cc: Chunming Zhou, Daniel Rakos, Bas Nieuwenhuizen, Dave Airlie,
	Christian König

points array is one-to-one match with syncobjs array.
v2:
add seperate ioctl for timeline point wait, otherwise break uapi.
v3:
userspace can specify two kinds waits::
a. Wait for time point to be completed.
b. and wait for time point to become available
v4:
rebase
v5:
add comment for xxx_WAIT_AVAILABLE
v6: rebase and rework on new container
v7: drop _WAIT_COMPLETED, it is the default anyway
v8: correctly handle garbage collected fences

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Cc: Daniel Rakos <Daniel.Rakos@amd.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/drm_internal.h |   2 +
 drivers/gpu/drm/drm_ioctl.c    |   2 +
 drivers/gpu/drm/drm_syncobj.c  | 153 ++++++++++++++++++++++++++-------
 include/uapi/drm/drm.h         |  15 ++++
 4 files changed, 143 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index c7a7d7ce5d1c..18b41e10195c 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -178,6 +178,8 @@ int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
 				   struct drm_file *file_private);
 int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_private);
+int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
+				    struct drm_file *file_private);
 int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
 			    struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 94bd872d56c4..a9a17ed35cc4 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -675,6 +675,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl,
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 2b8a744fbbb6..532d7d3c98cd 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -61,6 +61,7 @@ struct syncobj_wait_entry {
 	struct task_struct *task;
 	struct dma_fence *fence;
 	struct dma_fence_cb fence_cb;
+	u64    point;
 };
 
 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
@@ -95,6 +96,8 @@ EXPORT_SYMBOL(drm_syncobj_find);
 static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
 				       struct syncobj_wait_entry *wait)
 {
+	struct dma_fence *fence;
+
 	if (wait->fence)
 		return;
 
@@ -103,11 +106,15 @@ static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
 	 * have the lock, try one more time just to be sure we don't add a
 	 * callback when a fence has already been set.
 	 */
-	if (syncobj->fence)
-		wait->fence = dma_fence_get(
-			rcu_dereference_protected(syncobj->fence, 1));
-	else
+	fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
+	if (!fence || dma_fence_chain_find_seqno(&fence, wait->point)) {
+		dma_fence_put(fence);
 		list_add_tail(&wait->node, &syncobj->cb_list);
+	} else if (!fence) {
+		wait->fence = dma_fence_get_stub();
+	} else {
+		wait->fence = fence;
+	}
 	spin_unlock(&syncobj->lock);
 }
 
@@ -147,10 +154,8 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj,
 	dma_fence_chain_init(chain, prev, fence, point);
 	rcu_assign_pointer(syncobj->fence, &chain->base);
 
-	list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
-		list_del_init(&cur->node);
+	list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
 		syncobj_wait_syncobj_func(syncobj, cur);
-	}
 	spin_unlock(&syncobj->lock);
 
 	/* Walk the chain once to trigger garbage collection */
@@ -182,10 +187,8 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
 	rcu_assign_pointer(syncobj->fence, fence);
 
 	if (fence != old_fence) {
-		list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) {
-			list_del_init(&cur->node);
+		list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
 			syncobj_wait_syncobj_func(syncobj, cur);
-		}
 	}
 
 	spin_unlock(&syncobj->lock);
@@ -642,13 +645,27 @@ static void syncobj_wait_fence_func(struct dma_fence *fence,
 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
 				      struct syncobj_wait_entry *wait)
 {
+	struct dma_fence *fence;
+
 	/* This happens inside the syncobj lock */
-	wait->fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
-							      lockdep_is_held(&syncobj->lock)));
+	fence = rcu_dereference_protected(syncobj->fence,
+					  lockdep_is_held(&syncobj->lock));
+	dma_fence_get(fence);
+	if (!fence || dma_fence_chain_find_seqno(&fence, wait->point)) {
+		dma_fence_put(fence);
+		return;
+	} else if (!fence) {
+		wait->fence = dma_fence_get_stub();
+	} else {
+		wait->fence = fence;
+	}
+
 	wake_up_process(wait->task);
+	list_del_init(&wait->node);
 }
 
 static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
+						  void __user *user_points,
 						  uint32_t count,
 						  uint32_t flags,
 						  signed long timeout,
@@ -656,12 +673,27 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 {
 	struct syncobj_wait_entry *entries;
 	struct dma_fence *fence;
+	uint64_t *points;
 	uint32_t signaled_count, i;
 
-	entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
-	if (!entries)
+	points = kmalloc_array(count, sizeof(*points), GFP_KERNEL);
+	if (points == NULL)
 		return -ENOMEM;
 
+	if (!user_points) {
+		memset(points, 0, count * sizeof(uint64_t));
+
+	} else if (copy_from_user(points, user_points,
+				  sizeof(uint64_t) * count)) {
+		timeout = -EFAULT;
+		goto err_free_points;
+	}
+
+	entries = kcalloc(count, sizeof(*entries), GFP_KERNEL);
+	if (!entries) {
+		timeout = -ENOMEM;
+		goto err_free_points;
+	}
 	/* Walk the list of sync objects and initialize entries.  We do
 	 * this up-front so that we can properly return -EINVAL if there is
 	 * a syncobj with a missing fence and then never have the chance of
@@ -669,9 +701,13 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 	 */
 	signaled_count = 0;
 	for (i = 0; i < count; ++i) {
+		struct dma_fence *fence;
+
 		entries[i].task = current;
-		entries[i].fence = drm_syncobj_fence_get(syncobjs[i]);
-		if (!entries[i].fence) {
+		entries[i].point = points[i];
+		fence = drm_syncobj_fence_get(syncobjs[i]);
+		if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) {
+			dma_fence_put(fence);
 			if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
 				continue;
 			} else {
@@ -680,7 +716,13 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 			}
 		}
 
-		if (dma_fence_is_signaled(entries[i].fence)) {
+		if (fence)
+			entries[i].fence = fence;
+		else
+			entries[i].fence = dma_fence_get_stub();
+
+		if ((flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) ||
+		    dma_fence_is_signaled(entries[i].fence)) {
 			if (signaled_count == 0 && idx)
 				*idx = i;
 			signaled_count++;
@@ -713,7 +755,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 			if (!fence)
 				continue;
 
-			if (dma_fence_is_signaled(fence) ||
+			if ((flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) ||
+			    dma_fence_is_signaled(fence) ||
 			    (!entries[i].fence_cb.func &&
 			     dma_fence_add_callback(fence,
 						    &entries[i].fence_cb,
@@ -758,6 +801,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 	}
 	kfree(entries);
 
+err_free_points:
+	kfree(points);
+
 	return timeout;
 }
 
@@ -796,19 +842,33 @@ static signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec)
 static int drm_syncobj_array_wait(struct drm_device *dev,
 				  struct drm_file *file_private,
 				  struct drm_syncobj_wait *wait,
-				  struct drm_syncobj **syncobjs)
+				  struct drm_syncobj_timeline_wait *timeline_wait,
+				  struct drm_syncobj **syncobjs, bool timeline)
 {
-	signed long timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec);
+	signed long timeout = 0;
 	uint32_t first = ~0;
 
-	timeout = drm_syncobj_array_wait_timeout(syncobjs,
-						 wait->count_handles,
-						 wait->flags,
-						 timeout, &first);
-	if (timeout < 0)
-		return timeout;
-
-	wait->first_signaled = first;
+	if (!timeline) {
+		timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec);
+		timeout = drm_syncobj_array_wait_timeout(syncobjs,
+							 NULL,
+							 wait->count_handles,
+							 wait->flags,
+							 timeout, &first);
+		if (timeout < 0)
+			return timeout;
+		wait->first_signaled = first;
+	} else {
+		timeout = drm_timeout_abs_to_jiffies(timeline_wait->timeout_nsec);
+		timeout = drm_syncobj_array_wait_timeout(syncobjs,
+							 u64_to_user_ptr(timeline_wait->points),
+							 timeline_wait->count_handles,
+							 timeline_wait->flags,
+							 timeout, &first);
+		if (timeout < 0)
+			return timeout;
+		timeline_wait->first_signaled = first;
+	}
 	return 0;
 }
 
@@ -894,13 +954,48 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
 		return ret;
 
 	ret = drm_syncobj_array_wait(dev, file_private,
-				     args, syncobjs);
+				     args, NULL, syncobjs, false);
 
 	drm_syncobj_array_free(syncobjs, args->count_handles);
 
 	return ret;
 }
 
+int
+drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
+				struct drm_file *file_private)
+{
+	struct drm_syncobj_timeline_wait *args = data;
+	struct drm_syncobj **syncobjs;
+	int ret = 0;
+
+	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+		return -ENODEV;
+
+	if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL |
+			    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT |
+			    DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE))
+		return -EINVAL;
+
+	if (args->count_handles == 0)
+		return -EINVAL;
+
+	ret = drm_syncobj_array_find(file_private,
+				     u64_to_user_ptr(args->handles),
+				     args->count_handles,
+				     &syncobjs);
+	if (ret < 0)
+		return ret;
+
+	ret = drm_syncobj_array_wait(dev, file_private,
+				     NULL, args, syncobjs, true);
+
+	drm_syncobj_array_free(syncobjs, args->count_handles);
+
+	return ret;
+}
+
+
 int
 drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_private)
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 300f336633f2..0092111d002c 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -737,6 +737,7 @@ struct drm_syncobj_handle {
 
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2)
 struct drm_syncobj_wait {
 	__u64 handles;
 	/* absolute timeout */
@@ -747,6 +748,19 @@ struct drm_syncobj_wait {
 	__u32 pad;
 };
 
+struct drm_syncobj_timeline_wait {
+	__u64 handles;
+	/* wait on specific timeline point for every handles*/
+	__u64 points;
+	/* absolute timeout */
+	__s64 timeout_nsec;
+	__u32 count_handles;
+	__u32 flags;
+	__u32 first_signaled; /* only valid when not waiting all */
+	__u32 pad;
+};
+
+
 struct drm_syncobj_array {
 	__u64 handles;
 	__u32 count_handles;
@@ -909,6 +923,7 @@ extern "C" {
 #define DRM_IOCTL_MODE_GET_LEASE	DRM_IOWR(0xC8, struct drm_mode_get_lease)
 #define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
 
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/10] drm/syncobj: add timeline payload query ioctl v4
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (2 preceding siblings ...)
  2018-12-11 10:34 ` [PATCH 04/10] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-11 10:34 ` [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Chunming Zhou
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx
  Cc: Chunming Zhou, Daniel Rakos, Bas Nieuwenhuizen, Dave Airlie,
	Christian König

user mode can query timeline payload.
v2: check return value of copy_to_user
v3: handle querying entry by entry
v4: rebase on new chain container, simplify interface

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Cc: Daniel Rakos <Daniel.Rakos@amd.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/drm_internal.h |  2 ++
 drivers/gpu/drm/drm_ioctl.c    |  2 ++
 drivers/gpu/drm/drm_syncobj.c  | 43 ++++++++++++++++++++++++++++++++++
 include/uapi/drm/drm.h         | 10 ++++++++
 4 files changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 18b41e10195c..dab4d5936441 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -184,6 +184,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
 			    struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 			     struct drm_file *file_private);
+int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
+			    struct drm_file *file_private);
 
 /* drm_framebuffer.c */
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index a9a17ed35cc4..7578ef6dc1d1 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -681,6 +681,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 532d7d3c98cd..76ce13dafc4d 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1061,3 +1061,46 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 
 	return ret;
 }
+
+int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
+			    struct drm_file *file_private)
+{
+	struct drm_syncobj_timeline_array *args = data;
+	struct drm_syncobj **syncobjs;
+	uint64_t __user *points = u64_to_user_ptr(args->points);
+	uint32_t i;
+	int ret;
+
+	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+		return -ENODEV;
+
+	if (args->pad != 0)
+		return -EINVAL;
+
+	if (args->count_handles == 0)
+		return -EINVAL;
+
+	ret = drm_syncobj_array_find(file_private,
+				     u64_to_user_ptr(args->handles),
+				     args->count_handles,
+				     &syncobjs);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < args->count_handles; i++) {
+		struct dma_fence_chain *chain;
+		struct dma_fence *fence;
+		uint64_t point;
+
+		fence = drm_syncobj_fence_get(syncobjs[i]);
+		chain = to_dma_fence_chain(fence);
+		point = chain ? fence->seqno : 0;
+		ret = copy_to_user(&points[i], &point, sizeof(uint64_t));
+		ret = ret ? -EFAULT : 0;
+		if (ret)
+			break;
+	}
+	drm_syncobj_array_free(syncobjs, args->count_handles);
+
+	return ret;
+}
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 0092111d002c..b2c36f2b2599 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -767,6 +767,14 @@ struct drm_syncobj_array {
 	__u32 pad;
 };
 
+struct drm_syncobj_timeline_array {
+	__u64 handles;
+	__u64 points;
+	__u32 count_handles;
+	__u32 pad;
+};
+
+
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
 	__u32 crtc_id;		/* requested crtc_id */
@@ -924,6 +932,8 @@ extern "C" {
 #define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
 
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
+#define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (3 preceding siblings ...)
  2018-12-11 10:34 ` [PATCH 05/10] drm/syncobj: add timeline payload query ioctl v4 Chunming Zhou
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-13 11:37   ` Chris Wilson
       [not found] ` <20181211103449.25899-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx
  Cc: Christian König, Christian König

From: Christian König <ckoenig.leichtzumerken@gmail.com>

Implement finding the right timeline point in drm_syncobj_find_fence.

v2: return -EINVAL when the point is not submitted yet.
v3: fix reference counting bug, add flags handling as well

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 76ce13dafc4d..d964b348ecba 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
 			   struct dma_fence **fence)
 {
 	struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
-	int ret = 0;
+	struct syncobj_wait_entry wait;
+	int ret;
 
 	if (!syncobj)
 		return -ENOENT;
 
 	*fence = drm_syncobj_fence_get(syncobj);
-	if (!*fence) {
+	drm_syncobj_put(syncobj);
+
+	if (*fence) {
+		ret = dma_fence_chain_find_seqno(fence, point);
+		if (!ret)
+			return 0;
+		dma_fence_put(*fence);
+	} else {
 		ret = -EINVAL;
 	}
-	drm_syncobj_put(syncobj);
+
+	if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
+		return ret;
+
+	memset(&wait, 0, sizeof(wait));
+	wait.task = current;
+	wait.point = point;
+	drm_syncobj_fence_add_wait(syncobj, &wait);
+
+	do {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (wait.fence) {
+			ret = 0;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+
+		schedule();
+	} while (1);
+
+	__set_current_state(TASK_RUNNING);
+	*fence = wait.fence;
+
+	if (wait.node.next)
+		drm_syncobj_remove_wait(syncobj, &wait);
+
 	return ret;
 }
 EXPORT_SYMBOL(drm_syncobj_find_fence);
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/10] drm/amdgpu: add timeline support in amdgpu CS v2
       [not found] ` <20181211103449.25899-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
@ 2018-12-11 10:34   ` Chunming Zhou
  2018-12-11 10:34   ` [PATCH 08/10] drm/syncobj: add transition iotcls between binary and timeline v2 Chunming Zhou
  2018-12-13 11:29   ` [Intel-gfx] [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chris Wilson
  2 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig-5C7GfCeVMHo,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Chunming Zhou, Chris Wilson, Daniel Rakos, Jason Ekstrand,
	Bas Nieuwenhuizen, Dave Airlie, Christian König

syncobj wait/signal operation is appending in command submission.
v2: separate to two kinds in/out_deps functions

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Cc: Daniel Rakos <Daniel.Rakos@amd.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h    |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 147 +++++++++++++++++++++----
 include/uapi/drm/amdgpu_drm.h          |   8 ++
 3 files changed, 140 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 42f882c633ee..f9160ea1396a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -545,6 +545,12 @@ struct amdgpu_cs_chunk {
 	void			*kdata;
 };
 
+struct amdgpu_cs_post_dep {
+	struct drm_syncobj *syncobj;
+	struct dma_fence_chain *chain;
+	u64 point;
+};
+
 struct amdgpu_cs_parser {
 	struct amdgpu_device	*adev;
 	struct drm_file		*filp;
@@ -574,8 +580,8 @@ struct amdgpu_cs_parser {
 	/* user fence */
 	struct amdgpu_bo_list_entry	uf_entry;
 
-	unsigned num_post_dep_syncobjs;
-	struct drm_syncobj **post_dep_syncobjs;
+	unsigned			num_post_deps;
+	struct amdgpu_cs_post_dep	*post_deps;
 };
 
 static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index dc54e9efd910..580f1ea27157 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -213,6 +213,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
 		case AMDGPU_CHUNK_ID_DEPENDENCIES:
 		case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
 		case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
+		case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
+		case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
 			break;
 
 		default:
@@ -792,9 +794,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
 		ttm_eu_backoff_reservation(&parser->ticket,
 					   &parser->validated);
 
-	for (i = 0; i < parser->num_post_dep_syncobjs; i++)
-		drm_syncobj_put(parser->post_dep_syncobjs[i]);
-	kfree(parser->post_dep_syncobjs);
+	for (i = 0; i < parser->num_post_deps; i++) {
+		drm_syncobj_put(parser->post_deps[i].syncobj);
+		kfree(parser->post_deps[i].chain);
+	}
+	kfree(parser->post_deps);
 
 	dma_fence_put(parser->fence);
 
@@ -1100,13 +1104,18 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
 }
 
 static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
-						 uint32_t handle)
+						 uint32_t handle, u64 point,
+						 u64 flags)
 {
-	int r;
 	struct dma_fence *fence;
-	r = drm_syncobj_find_fence(p->filp, handle, 0, 0, &fence);
-	if (r)
+	int r;
+
+	r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence);
+	if (r) {
+		DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n",
+			  handle, point, r);
 		return r;
+	}
 
 	r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true);
 	dma_fence_put(fence);
@@ -1117,46 +1126,115 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
 static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
 					    struct amdgpu_cs_chunk *chunk)
 {
+	struct drm_amdgpu_cs_chunk_sem *deps;
 	unsigned num_deps;
 	int i, r;
-	struct drm_amdgpu_cs_chunk_sem *deps;
 
 	deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
 	num_deps = chunk->length_dw * 4 /
 		sizeof(struct drm_amdgpu_cs_chunk_sem);
+	for (i = 0; i < num_deps; ++i) {
+		r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle,
+							  0, 0);
+		if (r)
+			return r;
+	}
+
+	return 0;
+}
 
+
+static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser *p,
+						     struct amdgpu_cs_chunk *chunk)
+{
+	struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
+	unsigned num_deps;
+	int i, r;
+
+	syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
+	num_deps = chunk->length_dw * 4 /
+		sizeof(struct drm_amdgpu_cs_chunk_syncobj);
 	for (i = 0; i < num_deps; ++i) {
-		r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle);
+		r = amdgpu_syncobj_lookup_and_add_to_sync(p,
+							  syncobj_deps[i].handle,
+							  syncobj_deps[i].point,
+							  syncobj_deps[i].flags);
 		if (r)
 			return r;
 	}
+
 	return 0;
 }
 
 static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
 					     struct amdgpu_cs_chunk *chunk)
 {
+	struct drm_amdgpu_cs_chunk_sem *deps;
 	unsigned num_deps;
 	int i;
-	struct drm_amdgpu_cs_chunk_sem *deps;
+
 	deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
 	num_deps = chunk->length_dw * 4 /
 		sizeof(struct drm_amdgpu_cs_chunk_sem);
 
-	p->post_dep_syncobjs = kmalloc_array(num_deps,
-					     sizeof(struct drm_syncobj *),
-					     GFP_KERNEL);
-	p->num_post_dep_syncobjs = 0;
+	p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
+				     GFP_KERNEL);
+	p->num_post_deps = 0;
+
+	if (!p->post_deps)
+		return -ENOMEM;
+
+
+	for (i = 0; i < num_deps; ++i) {
+		p->post_deps[i].syncobj =
+			drm_syncobj_find(p->filp, deps[i].handle);
+		if (!p->post_deps[i].syncobj)
+			return -EINVAL;
+		p->post_deps[i].chain = NULL;
+		p->post_deps[i].point = 0;
+		p->num_post_deps++;
+	}
+
+	return 0;
+}
+
+
+static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p,
+						      struct amdgpu_cs_chunk
+						      *chunk)
+{
+	struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
+	unsigned num_deps;
+	int i;
+
+	syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
+	num_deps = chunk->length_dw * 4 /
+		sizeof(struct drm_amdgpu_cs_chunk_syncobj);
+
+	p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
+				     GFP_KERNEL);
+	p->num_post_deps = 0;
 
-	if (!p->post_dep_syncobjs)
+	if (!p->post_deps)
 		return -ENOMEM;
 
 	for (i = 0; i < num_deps; ++i) {
-		p->post_dep_syncobjs[i] = drm_syncobj_find(p->filp, deps[i].handle);
-		if (!p->post_dep_syncobjs[i])
+		struct amdgpu_cs_post_dep *dep = &p->post_deps[i];
+
+		dep->chain = kmalloc(sizeof(*dep->chain), GFP_KERNEL);
+		if (!dep->chain)
+			return -ENOMEM;
+
+		dep->syncobj = drm_syncobj_find(p->filp,
+						syncobj_deps[i].handle);
+		if (!dep->syncobj) {
+			kfree(dep->chain);
 			return -EINVAL;
-		p->num_post_dep_syncobjs++;
+		}
+		dep->point = syncobj_deps[i].point;
+		p->num_post_deps++;
 	}
+
 	return 0;
 }
 
@@ -1170,18 +1248,32 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
 
 		chunk = &p->chunks[i];
 
-		if (chunk->chunk_id == AMDGPU_CHUNK_ID_DEPENDENCIES) {
+		switch (chunk->chunk_id) {
+		case AMDGPU_CHUNK_ID_DEPENDENCIES:
 			r = amdgpu_cs_process_fence_dep(p, chunk);
 			if (r)
 				return r;
-		} else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) {
+			break;
+		case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
 			r = amdgpu_cs_process_syncobj_in_dep(p, chunk);
 			if (r)
 				return r;
-		} else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) {
+			break;
+		case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
 			r = amdgpu_cs_process_syncobj_out_dep(p, chunk);
 			if (r)
 				return r;
+			break;
+		case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
+			r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);
+			if (r)
+				return r;
+			break;
+		case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
+			r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);
+			if (r)
+				return r;
+			break;
 		}
 	}
 
@@ -1192,8 +1284,17 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
 {
 	int i;
 
-	for (i = 0; i < p->num_post_dep_syncobjs; ++i)
-		drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence);
+	for (i = 0; i < p->num_post_deps; ++i) {
+		if (p->post_deps[i].chain) {
+			drm_syncobj_add_point(p->post_deps[i].syncobj,
+					      p->post_deps[i].chain,
+					      p->fence, p->post_deps[i].point);
+			p->post_deps[i].chain = NULL;
+		} else {
+			drm_syncobj_replace_fence(p->post_deps[i].syncobj,
+						  p->fence);
+		}
+	}
 }
 
 static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index be84e43c1e19..997222bc1afe 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -523,6 +523,8 @@ struct drm_amdgpu_gem_va {
 #define AMDGPU_CHUNK_ID_SYNCOBJ_IN      0x04
 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT     0x05
 #define AMDGPU_CHUNK_ID_BO_HANDLES      0x06
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT    0x07
+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL  0x08
 
 struct drm_amdgpu_cs_chunk {
 	__u32		chunk_id;
@@ -598,6 +600,12 @@ struct drm_amdgpu_cs_chunk_sem {
 	__u32 handle;
 };
 
+struct drm_amdgpu_cs_chunk_syncobj {
+       __u32 handle;
+       __u32 flags;
+       __u64 point;
+};
+
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ	0
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD	1
 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD	2
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/10] drm/syncobj: add transition iotcls between binary and timeline v2
       [not found] ` <20181211103449.25899-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
  2018-12-11 10:34   ` [PATCH 07/10] drm/amdgpu: add timeline support in amdgpu CS v2 Chunming Zhou
@ 2018-12-11 10:34   ` Chunming Zhou
  2018-12-13 11:29   ` [Intel-gfx] [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chris Wilson
  2 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig-5C7GfCeVMHo,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Chunming Zhou

we need to import/export timeline point.

v2: unify to one transfer ioctl

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
---
 drivers/gpu/drm/drm_internal.h |  2 +
 drivers/gpu/drm/drm_ioctl.c    |  2 +
 drivers/gpu/drm/drm_syncobj.c  | 74 ++++++++++++++++++++++++++++++++++
 include/uapi/drm/drm.h         | 10 +++++
 4 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index dab4d5936441..06c2adc4950e 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -176,6 +176,8 @@ int drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void *data,
 				   struct drm_file *file_private);
 int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
 				   struct drm_file *file_private);
+int drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data,
+			       struct drm_file *file_private);
 int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_private);
 int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7578ef6dc1d1..e9d4bed12783 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -673,6 +673,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TRANSFER, drm_syncobj_transfer_ioctl,
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl,
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index d964b348ecba..3bba86c8160d 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -670,6 +670,80 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data,
 					&args->handle);
 }
 
+static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
+					    struct drm_syncobj_transfer *args)
+{
+	struct drm_syncobj *timeline_syncobj = NULL;
+	struct dma_fence *fence;
+	struct dma_fence_chain *chain;
+	int ret;
+
+	timeline_syncobj = drm_syncobj_find(file_private, args->dst_handle);
+	if (!timeline_syncobj) {
+		return -ENOENT;
+	}
+	ret = drm_syncobj_find_fence(file_private, args->src_handle,
+				     args->src_point, args->flags,
+				     &fence);
+	if (ret)
+		goto err;
+	chain = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+	if (!chain) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+	drm_syncobj_add_point(timeline_syncobj, chain, fence, args->dst_point);
+err1:
+	dma_fence_put(fence);
+err:
+	drm_syncobj_put(timeline_syncobj);
+
+	return ret;
+}
+
+static int
+drm_syncobj_transfer_to_binary(struct drm_file *file_private,
+			       struct drm_syncobj_transfer *args)
+{
+	struct drm_syncobj *binary_syncobj = NULL;
+	struct dma_fence *fence;
+	int ret;
+
+	binary_syncobj = drm_syncobj_find(file_private, args->dst_handle);
+	if (!binary_syncobj)
+		return -ENOENT;
+	ret = drm_syncobj_find_fence(file_private, args->src_handle,
+				     args->src_point, args->flags, &fence);
+	if (ret)
+		goto err;
+	drm_syncobj_replace_fence(binary_syncobj, fence);
+	dma_fence_put(fence);
+err:
+	drm_syncobj_put(binary_syncobj);
+
+	return ret;
+}
+int
+drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_private)
+{
+	struct drm_syncobj_transfer *args = data;
+	int ret;
+
+	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+		return -ENODEV;
+
+	if (args->pad)
+		return -EINVAL;
+
+	if (args->dst_point)
+		ret = drm_syncobj_transfer_to_timeline(file_private, args);
+	else
+		ret = drm_syncobj_transfer_to_binary(file_private, args);
+
+	return ret;
+}
+
 static void syncobj_wait_fence_func(struct dma_fence *fence,
 				    struct dma_fence_cb *cb)
 {
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index b2c36f2b2599..4c1e2e6579fa 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -735,6 +735,15 @@ struct drm_syncobj_handle {
 	__u32 pad;
 };
 
+struct drm_syncobj_transfer {
+	__u32 src_handle;
+	__u32 dst_handle;
+	__u64 src_point;
+	__u64 dst_point;
+	__u32 flags;
+	__u32 pad;
+};
+
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2)
@@ -933,6 +942,7 @@ extern "C" {
 
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
 #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
 
 /**
  * Device specific ioctls should only be in their respective headers
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/10] drm/syncobj: add timeline signal ioctl for syncobj v2
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (5 preceding siblings ...)
       [not found] ` <20181211103449.25899-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-11 10:34 ` [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu Chunming Zhou
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx; +Cc: Chunming Zhou

v2: individually allocate chain array, since chain node is free independently.

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
---
 drivers/gpu/drm/drm_internal.h |  2 +
 drivers/gpu/drm/drm_ioctl.c    |  2 +
 drivers/gpu/drm/drm_syncobj.c  | 81 ++++++++++++++++++++++++++++++++++
 include/uapi/drm/drm.h         |  1 +
 4 files changed, 86 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 06c2adc4950e..d7a19bd89cb2 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -186,6 +186,8 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
 			    struct drm_file *file_private);
 int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 			     struct drm_file *file_private);
+int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
+				      struct drm_file *file_private);
 int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
 			    struct drm_file *file_private);
 
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index e9d4bed12783..a50dc62dc87b 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -683,6 +683,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, drm_syncobj_timeline_signal_ioctl,
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 3bba86c8160d..961f6d343564 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1173,6 +1173,87 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
 	return ret;
 }
 
+int
+drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
+				  struct drm_file *file_private)
+{
+	struct drm_syncobj_timeline_array *args = data;
+	struct drm_syncobj **syncobjs;
+	struct dma_fence_chain **chains;
+	uint64_t *points;
+	uint32_t i, j, timeline_count = 0;
+	int ret;
+
+	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+		return -EOPNOTSUPP;
+
+	if (args->pad != 0)
+		return -EINVAL;
+
+	if (args->count_handles == 0)
+		return -EINVAL;
+
+	ret = drm_syncobj_array_find(file_private,
+				     u64_to_user_ptr(args->handles),
+				     args->count_handles,
+				     &syncobjs);
+	if (ret < 0)
+		return ret;
+
+	points = kmalloc_array(args->count_handles, sizeof(*points),
+			       GFP_KERNEL);
+	if (!points) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	if (!u64_to_user_ptr(args->points)) {
+		memset(points, 0, args->count_handles * sizeof(uint64_t));
+	} else if (copy_from_user(points, u64_to_user_ptr(args->points),
+				  sizeof(uint64_t) * args->count_handles)) {
+		ret = -EFAULT;
+		goto err_points;
+	}
+
+
+	for (i = 0; i < args->count_handles; i++) {
+		if (points[i])
+			timeline_count++;
+	}
+	chains = kmalloc_array(timeline_count, sizeof(void *), GFP_KERNEL);
+	if (!chains) {
+		ret = -ENOMEM;
+		goto err_points;
+	}
+	for (i = 0; i < timeline_count; i++) {
+		chains[i] = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);
+		if (!chains[i]) {
+			for (j = 0; j < i; j++)
+				kfree(chains[j]);
+			ret = -ENOMEM;
+			goto err_chains;
+		}
+	}
+
+	for (i = 0, j = 0; i < args->count_handles; i++) {
+		if (points[i]) {
+			struct dma_fence *fence = dma_fence_get_stub();
+
+			drm_syncobj_add_point(syncobjs[i], chains[j++],
+					      fence, points[i]);
+			dma_fence_put(fence);
+		} else
+			drm_syncobj_assign_null_handle(syncobjs[i]);
+	}
+err_chains:
+	kfree(chains);
+err_points:
+	kfree(points);
+out:
+	drm_syncobj_array_free(syncobjs, args->count_handles);
+
+	return ret;
+}
+
 int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
 			    struct drm_file *file_private)
 {
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 4c1e2e6579fa..fe00b74268eb 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -943,6 +943,7 @@ extern "C" {
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT	DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait)
 #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
 #define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
 
 /**
  * Device specific ioctls should only be in their respective headers
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (6 preceding siblings ...)
  2018-12-11 10:34 ` [PATCH 09/10] drm/syncobj: add timeline signal ioctl for syncobj v2 Chunming Zhou
@ 2018-12-11 10:34 ` Chunming Zhou
  2018-12-11 11:18 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/10] dma-buf: add new dma_fence_chain container v4 Patchwork
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Chunming Zhou @ 2018-12-11 10:34 UTC (permalink / raw)
  To: Christian.Koenig, dri-devel, amd-gfx, intel-gfx; +Cc: Chunming Zhou

Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 8de55f7f1a3a..cafafdb1d03f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -71,9 +71,10 @@
  * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk).
  * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE.
  * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation.
+ * - 3.28.0 - Add syncobj timeline support to AMDGPU_CS.
  */
 #define KMS_DRIVER_MAJOR	3
-#define KMS_DRIVER_MINOR	27
+#define KMS_DRIVER_MINOR	28
 #define KMS_DRIVER_PATCHLEVEL	0
 
 int amdgpu_vram_limit = 0;
-- 
2.17.1

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

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/10] dma-buf: add new dma_fence_chain container v4
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (7 preceding siblings ...)
  2018-12-11 10:34 ` [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu Chunming Zhou
@ 2018-12-11 11:18 ` Patchwork
  2018-12-11 11:24 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2018-12-11 11:18 UTC (permalink / raw)
  To: Chunming Zhou; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/10] dma-buf: add new dma_fence_chain container v4
URL   : https://patchwork.freedesktop.org/series/53879/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
840d7cb7e1cc dma-buf: add new dma_fence_chain container v4
-:12: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#12: 
v2: properly document dma_fence_chain_for_each, add dma_fence_chain_find_seqno,

-:31: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#31: 
new file mode 100644

-:36: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#36: FILE: drivers/dma-buf/dma-fence-chain.c:1:
+/*

-:94: CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#94: FILE: drivers/dma-buf/dma-fence-chain.c:59:
+	while ((prev = dma_fence_chain_get_prev(chain))) {
+

-:156: ERROR:CODE_INDENT: code indent should use tabs where possible
#156: FILE: drivers/dma-buf/dma-fence-chain.c:121:
+        return "dma_fence_chain";$

-:156: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#156: FILE: drivers/dma-buf/dma-fence-chain.c:121:
+        return "dma_fence_chain";$

-:161: ERROR:CODE_INDENT: code indent should use tabs where possible
#161: FILE: drivers/dma-buf/dma-fence-chain.c:126:
+        return "unbound";$

-:161: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#161: FILE: drivers/dma-buf/dma-fence-chain.c:126:
+        return "unbound";$

-:283: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#283: FILE: include/linux/dma-fence-chain.h:1:
+/*

-:318: CHECK:UNCOMMENTED_DEFINITION: spinlock_t definition without comment
#318: FILE: include/linux/dma-fence-chain.h:36:
+	spinlock_t lock;

-:352: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'iter' - possible side-effects?
#352: FILE: include/linux/dma-fence-chain.h:70:
+#define dma_fence_chain_for_each(iter, head)	\
+	for (iter = dma_fence_get(head); iter; \
+	     iter = dma_fence_chain_walk(head))

-:352: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'head' - possible side-effects?
#352: FILE: include/linux/dma-fence-chain.h:70:
+#define dma_fence_chain_for_each(iter, head)	\
+	for (iter = dma_fence_get(head); iter; \
+	     iter = dma_fence_chain_walk(head))

-:363: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Christian König <ckoenig.leichtzumerken@gmail.com>'

total: 2 errors, 7 warnings, 4 checks, 328 lines checked
87065bf020ee drm/syncobj: remove drm_syncobj_cb and cleanup
-:77: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#77: FILE: drivers/gpu/drm/drm_syncobj.c:107:
+		wait->fence = dma_fence_get(

-:217: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Christian König <ckoenig.leichtzumerken@gmail.com>'

total: 0 errors, 1 warnings, 1 checks, 186 lines checked
59a66b97c017 drm/syncobj: add new drm_syncobj_add_point interface v3
-:87: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Christian König <ckoenig.leichtzumerken@gmail.com>'

total: 0 errors, 1 warnings, 0 checks, 60 lines checked
2b8a180d5fb2 drm/syncobj: add support for timeline point wait v8
-:11: WARNING:TYPO_SPELLING: 'seperate' may be misspelled - perhaps 'separate'?
#11: 
add seperate ioctl for timeline point wait, otherwise break uapi.

-:54: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#54: FILE: drivers/gpu/drm/drm_ioctl.c:679:
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 		                  ^

-:163: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "!points"
#163: FILE: drivers/gpu/drm/drm_syncobj.c:680:
+	if (points == NULL)

-:324: CHECK:LINE_SPACING: Please don't use multiple blank lines
#324: FILE: drivers/gpu/drm/drm_syncobj.c:998:
+
+

-:356: CHECK:LINE_SPACING: Please don't use multiple blank lines
#356: FILE: include/uapi/drm/drm.h:763:
+
+

total: 0 errors, 1 warnings, 4 checks, 302 lines checked
baf631df82a6 drm/syncobj: add timeline payload query ioctl v4
-:44: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#44: FILE: drivers/gpu/drm/drm_ioctl.c:685:
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 		                  ^

-:114: CHECK:LINE_SPACING: Please don't use multiple blank lines
#114: FILE: include/uapi/drm/drm.h:777:
+
+

total: 0 errors, 0 warnings, 2 checks, 84 lines checked
910c349cf9d7 drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
-:77: WARNING:NO_AUTHOR_SIGN_OFF: Missing Signed-off-by: line by nominal patch author 'Christian König <ckoenig.leichtzumerken@gmail.com>'

total: 0 errors, 1 warnings, 0 checks, 56 lines checked
0311d860d79e drm/amdgpu: add timeline support in amdgpu CS v2
-:43: WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#43: FILE: drivers/gpu/drm/amd/amdgpu/amdgpu.h:467:
+	unsigned			num_post_deps;

-:121: CHECK:LINE_SPACING: Please don't use multiple blank lines
#121: FILE: drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1146:
 
+

-:126: WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#126: FILE: drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1151:
+	unsigned num_deps;

-:168: CHECK:LINE_SPACING: Please don't use multiple blank lines
#168: FILE: drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1187:
+
+

-:182: CHECK:LINE_SPACING: Please don't use multiple blank lines
#182: FILE: drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1201:
+
+

-:188: WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#188: FILE: drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1207:
+	unsigned num_deps;

-:300: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#300: FILE: include/uapi/drm/amdgpu_drm.h:604:
+       __u32 handle;$

-:301: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#301: FILE: include/uapi/drm/amdgpu_drm.h:605:
+       __u32 flags;$

-:302: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#302: FILE: include/uapi/drm/amdgpu_drm.h:606:
+       __u64 point;$

total: 0 errors, 6 warnings, 3 checks, 266 lines checked
2dd3be4e6245 drm/syncobj: add transition iotcls between binary and timeline v2
-:35: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#35: FILE: drivers/gpu/drm/drm_ioctl.c:677:
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 		                  ^

-:56: WARNING:BRACES: braces {} are not necessary for single statement blocks
#56: FILE: drivers/gpu/drm/drm_syncobj.c:682:
+	if (!timeline_syncobj) {
+		return -ENOENT;
+	}

-:64: CHECK:ALLOC_SIZEOF_STRUCT: Prefer kzalloc(sizeof(*chain)...) over kzalloc(sizeof(struct dma_fence_chain)...)
#64: FILE: drivers/gpu/drm/drm_syncobj.c:690:
+	chain = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);

-:100: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#100: FILE: drivers/gpu/drm/drm_syncobj.c:726:
+}
+int

total: 0 errors, 1 warnings, 3 checks, 118 lines checked
0c1208ed2010 drm/syncobj: add timeline signal ioctl for syncobj v2
-:6: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#6: 
v2: individually allocate chain array, since chain node is free independently.

-:32: CHECK:SPACING: spaces preferred around that '|' (ctx:VxV)
#32: FILE: drivers/gpu/drm/drm_ioctl.c:687:
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 		                  ^

-:85: CHECK:LINE_SPACING: Please don't use multiple blank lines
#85: FILE: drivers/gpu/drm/drm_syncobj.c:1217:
+
+

-:96: CHECK:ALLOC_SIZEOF_STRUCT: Prefer kzalloc(sizeof(*chains[i])...) over kzalloc(sizeof(struct dma_fence_chain)...)
#96: FILE: drivers/gpu/drm/drm_syncobj.c:1228:
+		chains[i] = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL);

-:106: CHECK:BRACES: braces {} should be used on all arms of this statement
#106: FILE: drivers/gpu/drm/drm_syncobj.c:1238:
+		if (points[i]) {
[...]
+		} else
[...]

-:112: CHECK:BRACES: Unbalanced braces around else statement
#112: FILE: drivers/gpu/drm/drm_syncobj.c:1244:
+		} else

total: 0 errors, 1 warnings, 5 checks, 110 lines checked
b2b237d605c5 drm/amdgpu: update version for timeline syncobj support in amdgpu
-:8: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

total: 0 errors, 1 warnings, 0 checks, 11 lines checked

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* ✗ Fi.CI.SPARSE: warning for series starting with [01/10] dma-buf: add new dma_fence_chain container v4
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (8 preceding siblings ...)
  2018-12-11 11:18 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/10] dma-buf: add new dma_fence_chain container v4 Patchwork
@ 2018-12-11 11:24 ` Patchwork
  2018-12-11 11:38 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2018-12-11 11:24 UTC (permalink / raw)
  To: Chunming Zhou; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/10] dma-buf: add new dma_fence_chain container v4
URL   : https://patchwork.freedesktop.org/series/53879/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: dma-buf: add new dma_fence_chain container v4
Okay!

Commit: drm/syncobj: remove drm_syncobj_cb and cleanup
-O:drivers/gpu/drm/drm_syncobj.c:123:6: warning: symbol 'drm_syncobj_add_callback' was not declared. Should it be static?
-O:drivers/gpu/drm/drm_syncobj.c:132:6: warning: symbol 'drm_syncobj_remove_callback' was not declared. Should it be static?

Commit: drm/syncobj: add new drm_syncobj_add_point interface v3
Okay!

Commit: drm/syncobj: add support for timeline point wait v8
+./include/linux/slab.h:665:13: error: not a function <noident>

Commit: drm/syncobj: add timeline payload query ioctl v4
Okay!

Commit: drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
Okay!

Commit: drm/amdgpu: add timeline support in amdgpu CS v2
+./include/linux/slab.h:665:13: error: not a function <noident>

Commit: drm/syncobj: add transition iotcls between binary and timeline v2
+./include/linux/slab.h:332:43: warning: dubious: x & !y

Commit: drm/syncobj: add timeline signal ioctl for syncobj v2
+./include/linux/slab.h:665:13: error: not a function <noident>
+./include/linux/slab.h:665:13: error: not a function <noident>

Commit: drm/amdgpu: update version for timeline syncobj support in amdgpu
Okay!

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* ✓ Fi.CI.BAT: success for series starting with [01/10] dma-buf: add new dma_fence_chain container v4
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (9 preceding siblings ...)
  2018-12-11 11:24 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-12-11 11:38 ` Patchwork
  2018-12-11 13:39 ` ✓ Fi.CI.IGT: " Patchwork
  2018-12-12  5:31 ` [PATCH 01/10] " Zhou, David(ChunMing)
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2018-12-11 11:38 UTC (permalink / raw)
  To: Chunming Zhou; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/10] dma-buf: add new dma_fence_chain container v4
URL   : https://patchwork.freedesktop.org/series/53879/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5295 -> Patchwork_11064
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/53879/revisions/1/mbox/

Known issues
------------

  Here are the changes found in Patchwork_11064 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_chamelium@dp-crc-fast:
    - {fi-kbl-7500u}:     PASS -> DMESG-FAIL [fdo#103841]

  * igt@kms_frontbuffer_tracking@basic:
    - fi-hsw-peppy:       PASS -> DMESG-WARN [fdo#102614]

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
    - fi-byt-clapper:     PASS -> FAIL [fdo#103191] / [fdo#107362]

  * {igt@runner@aborted}:
    - {fi-kbl-7500u}:     NOTRUN -> FAIL [fdo#103841]

  
#### Possible fixes ####

  * igt@i915_selftest@live_coherency:
    - fi-gdg-551:         DMESG-FAIL [fdo#107164] -> PASS

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - fi-byt-clapper:     FAIL [fdo#103191] / [fdo#107362] -> PASS

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
    - fi-cfl-8109u:       INCOMPLETE [fdo#106070] / [fdo#108126] -> PASS

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
  [fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191
  [fdo#103841]: https://bugs.freedesktop.org/show_bug.cgi?id=103841
  [fdo#106070]: https://bugs.freedesktop.org/show_bug.cgi?id=106070
  [fdo#107164]: https://bugs.freedesktop.org/show_bug.cgi?id=107164
  [fdo#107362]: https://bugs.freedesktop.org/show_bug.cgi?id=107362
  [fdo#108126]: https://bugs.freedesktop.org/show_bug.cgi?id=108126


Participating hosts (49 -> 43)
------------------------------

  Missing    (6): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-ctg-p8600 fi-pnv-d510 fi-bdw-samus 


Build changes
-------------

    * Linux: CI_DRM_5295 -> Patchwork_11064

  CI_DRM_5295: b94537deaa09d831c7e191da57aed98cc11fd49b @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4745: 3b52e8a5809a4e860350c59476a456745cd9fee0 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_11064: b2b237d605c56ee4e2c27ccd9c779655e2b849a7 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

b2b237d605c5 drm/amdgpu: update version for timeline syncobj support in amdgpu
0c1208ed2010 drm/syncobj: add timeline signal ioctl for syncobj v2
2dd3be4e6245 drm/syncobj: add transition iotcls between binary and timeline v2
0311d860d79e drm/amdgpu: add timeline support in amdgpu CS v2
910c349cf9d7 drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
baf631df82a6 drm/syncobj: add timeline payload query ioctl v4
2b8a180d5fb2 drm/syncobj: add support for timeline point wait v8
59a66b97c017 drm/syncobj: add new drm_syncobj_add_point interface v3
87065bf020ee drm/syncobj: remove drm_syncobj_cb and cleanup
840d7cb7e1cc dma-buf: add new dma_fence_chain container v4

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_11064/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 24+ messages in thread

* ✓ Fi.CI.IGT: success for series starting with [01/10] dma-buf: add new dma_fence_chain container v4
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (10 preceding siblings ...)
  2018-12-11 11:38 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2018-12-11 13:39 ` Patchwork
  2018-12-12  5:31 ` [PATCH 01/10] " Zhou, David(ChunMing)
  12 siblings, 0 replies; 24+ messages in thread
From: Patchwork @ 2018-12-11 13:39 UTC (permalink / raw)
  To: Chunming Zhou; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/10] dma-buf: add new dma_fence_chain container v4
URL   : https://patchwork.freedesktop.org/series/53879/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5295_full -> Patchwork_11064_full
====================================================

Summary
-------

  **WARNING**

  Minor unknown changes coming with Patchwork_11064_full need to be verified
  manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_11064_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_11064_full:

### IGT changes ###

#### Warnings ####

  * igt@pm_rc6_residency@rc6-accuracy:
    - shard-snb:          SKIP -> PASS

  
Known issues
------------

  Here are the changes found in Patchwork_11064_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_busy@extended-modeset-hang-newfb-render-b:
    - {shard-iclb}:       NOTRUN -> DMESG-WARN [fdo#107956]

  * igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-a:
    - shard-skl:          NOTRUN -> DMESG-WARN [fdo#107956]
    - shard-apl:          PASS -> DMESG-WARN [fdo#107956]

  * igt@kms_ccs@pipe-a-crc-sprite-planes-basic:
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#107725]

  * igt@kms_cursor_crc@cursor-64x21-sliding:
    - shard-apl:          PASS -> FAIL [fdo#103232] +4

  * igt@kms_cursor_crc@cursor-64x64-random:
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#103232] +1

  * igt@kms_draw_crc@draw-method-xrgb2101010-blt-untiled:
    - {shard-iclb}:       PASS -> WARN [fdo#108336]

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-glk:          PASS -> FAIL [fdo#103833] / [fdo#105681]
    - shard-kbl:          PASS -> FAIL [fdo#103833] / [fdo#105681]

  * igt@kms_fbcon_fbt@psr-suspend:
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#107882]

  * igt@kms_flip@flip-vs-expired-vblank:
    - shard-skl:          PASS -> FAIL [fdo#105363]

  * igt@kms_flip_tiling@flip-changes-tiling:
    - {shard-iclb}:       PASS -> DMESG-WARN [fdo#107724] / [fdo#108336] +3

  * igt@kms_flip_tiling@flip-changes-tiling-y:
    - shard-skl:          NOTRUN -> FAIL [fdo#107931] / [fdo#108303]

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-onoff:
    - shard-apl:          PASS -> FAIL [fdo#103167] +4

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-move:
    - {shard-iclb}:       PASS -> FAIL [fdo#103167] +3

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-pwrite:
    - shard-glk:          PASS -> FAIL [fdo#103167] +1

  * igt@kms_frontbuffer_tracking@fbcpsr-suspend:
    - {shard-iclb}:       PASS -> DMESG-FAIL [fdo#107724]

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-spr-indfb-draw-blt:
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#103167] +1

  * igt@kms_plane@pixel-format-pipe-c-planes:
    - shard-apl:          PASS -> FAIL [fdo#103166] +1
    - shard-skl:          NOTRUN -> DMESG-WARN [fdo#106885]

  * {igt@kms_plane@pixel-format-pipe-c-planes-source-clamping}:
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#108948]

  * igt@kms_plane@plane-position-covered-pipe-a-planes:
    - shard-glk:          PASS -> FAIL [fdo#103166]
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#103166]

  * igt@kms_plane_alpha_blend@pipe-b-alpha-opaque-fb:
    - shard-glk:          PASS -> FAIL [fdo#108145]

  * igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min:
    - shard-skl:          NOTRUN -> FAIL [fdo#108145]

  * igt@kms_plane_multiple@atomic-pipe-c-tiling-x:
    - {shard-iclb}:       PASS -> FAIL [fdo#103166]

  * {igt@kms_rotation_crc@multiplane-rotation-cropping-top}:
    - shard-kbl:          PASS -> DMESG-WARN [fdo#105604]
    - shard-glk:          PASS -> DMESG-WARN [fdo#105763] / [fdo#106538]

  * igt@kms_setmode@basic:
    - shard-kbl:          PASS -> FAIL [fdo#99912]

  * igt@pm_rpm@cursor-dpms:
    - {shard-iclb}:       PASS -> DMESG-WARN [fdo#107724] +7

  * igt@pm_rps@min-max-config-loaded:
    - {shard-iclb}:       NOTRUN -> FAIL [fdo#102250]

  
#### Possible fixes ####

  * igt@kms_color@pipe-b-ctm-negative:
    - shard-skl:          FAIL [fdo#107361] -> PASS

  * igt@kms_cursor_legacy@basic-flip-before-cursor-legacy:
    - shard-apl:          DMESG-WARN [fdo#103558] / [fdo#105602] -> PASS +16

  * igt@kms_draw_crc@draw-method-rgb565-pwrite-ytiled:
    - shard-glk:          FAIL [fdo#103184] -> PASS

  * igt@kms_flip@dpms-vs-vblank-race:
    - shard-skl:          FAIL [fdo#103060] -> PASS

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-mmap-gtt:
    - shard-apl:          FAIL [fdo#103167] -> PASS

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-mmap-wc:
    - shard-glk:          FAIL [fdo#103167] -> PASS +5

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-pwrite:
    - {shard-iclb}:       FAIL [fdo#103167] -> PASS +4

  * igt@kms_frontbuffer_tracking@fbcpsr-stridechange:
    - {shard-iclb}:       FAIL [fdo#105683] -> PASS

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes:
    - {shard-iclb}:       INCOMPLETE [fdo#107713] -> PASS +2

  * igt@kms_plane@plane-position-covered-pipe-a-planes:
    - shard-apl:          FAIL [fdo#103166] -> PASS

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max:
    - shard-glk:          FAIL [fdo#108145] -> PASS

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
    - shard-skl:          FAIL [fdo#107815] / [fdo#108145] -> PASS

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          FAIL [fdo#107815] -> PASS

  * igt@kms_plane_alpha_blend@pipe-c-alpha-opaque-fb:
    - shard-apl:          FAIL [fdo#108145] -> PASS

  * igt@kms_plane_multiple@atomic-pipe-a-tiling-x:
    - {shard-iclb}:       FAIL [fdo#103166] -> PASS

  * igt@kms_plane_multiple@atomic-pipe-c-tiling-x:
    - shard-glk:          FAIL [fdo#103166] -> PASS +1

  * igt@kms_universal_plane@universal-plane-gen9-features-pipe-a:
    - shard-kbl:          DMESG-WARN [fdo#103558] / [fdo#105602] -> PASS +17

  * igt@kms_vblank@pipe-c-ts-continuation-dpms-suspend:
    - shard-skl:          INCOMPLETE [fdo#104108] -> PASS

  * igt@perf@blocking:
    - shard-hsw:          FAIL [fdo#102252] -> PASS

  * igt@pm_rpm@gem-mmap-gtt:
    - shard-skl:          INCOMPLETE [fdo#107807] -> PASS

  * igt@pm_rpm@universal-planes-dpms:
    - {shard-iclb}:       INCOMPLETE [fdo#107713] / [fdo#108840] -> PASS

  
#### Warnings ####

  * igt@i915_selftest@live_contexts:
    - {shard-iclb}:       INCOMPLETE [fdo#108315] -> DMESG-FAIL [fdo#108569]

  * igt@kms_cursor_crc@cursor-128x128-random:
    - {shard-iclb}:       FAIL [fdo#103232] -> DMESG-WARN [fdo#107724] / [fdo#108336]

  * igt@kms_cursor_crc@cursor-64x64-sliding:
    - shard-apl:          DMESG-FAIL [fdo#103232] / [fdo#103558] / [fdo#105602] -> FAIL [fdo#103232]
    - shard-kbl:          DMESG-FAIL [fdo#103232] / [fdo#103558] / [fdo#105602] -> FAIL [fdo#103232]

  * igt@kms_frontbuffer_tracking@fbc-1p-rte:
    - shard-kbl:          DMESG-FAIL [fdo#103167] / [fdo#103558] / [fdo#105602] -> FAIL [fdo#103167] / [fdo#105682]

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-draw-mmap-wc:
    - {shard-iclb}:       FAIL [fdo#103167] -> DMESG-FAIL [fdo#107724]

  * {igt@kms_plane@pixel-format-pipe-a-planes-source-clamping}:
    - {shard-iclb}:       FAIL [fdo#108948] -> DMESG-WARN [fdo#107724] / [fdo#108336]

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#102250]: https://bugs.freedesktop.org/show_bug.cgi?id=102250
  [fdo#102252]: https://bugs.freedesktop.org/show_bug.cgi?id=102252
  [fdo#103060]: https://bugs.freedesktop.org/show_bug.cgi?id=103060
  [fdo#103166]: https://bugs.freedesktop.org/show_bug.cgi?id=103166
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103184]: https://bugs.freedesktop.org/show_bug.cgi?id=103184
  [fdo#103232]: https://bugs.freedesktop.org/show_bug.cgi?id=103232
  [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
  [fdo#103833]: https://bugs.freedesktop.org/show_bug.cgi?id=103833
  [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
  [fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
  [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
  [fdo#105604]: https://bugs.freedesktop.org/show_bug.cgi?id=105604
  [fdo#105681]: https://bugs.freedesktop.org/show_bug.cgi?id=105681
  [fdo#105682]: https://bugs.freedesktop.org/show_bug.cgi?id=105682
  [fdo#105683]: https://bugs.freedesktop.org/show_bug.cgi?id=105683
  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#106538]: https://bugs.freedesktop.org/show_bug.cgi?id=106538
  [fdo#106885]: https://bugs.freedesktop.org/show_bug.cgi?id=106885
  [fdo#107361]: https://bugs.freedesktop.org/show_bug.cgi?id=107361
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#107725]: https://bugs.freedesktop.org/show_bug.cgi?id=107725
  [fdo#107807]: https://bugs.freedesktop.org/show_bug.cgi?id=107807
  [fdo#107815]: https://bugs.freedesktop.org/show_bug.cgi?id=107815
  [fdo#107882]: https://bugs.freedesktop.org/show_bug.cgi?id=107882
  [fdo#107931]: https://bugs.freedesktop.org/show_bug.cgi?id=107931
  [fdo#107956]: https://bugs.freedesktop.org/show_bug.cgi?id=107956
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108303]: https://bugs.freedesktop.org/show_bug.cgi?id=108303
  [fdo#108315]: https://bugs.freedesktop.org/show_bug.cgi?id=108315
  [fdo#108336]: https://bugs.freedesktop.org/show_bug.cgi?id=108336
  [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569
  [fdo#108840]: https://bugs.freedesktop.org/show_bug.cgi?id=108840
  [fdo#108948]: https://bugs.freedesktop.org/show_bug.cgi?id=108948
  [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912


Participating hosts (7 -> 7)
------------------------------

  No changes in participating hosts


Build changes
-------------

    * Linux: CI_DRM_5295 -> Patchwork_11064

  CI_DRM_5295: b94537deaa09d831c7e191da57aed98cc11fd49b @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4745: 3b52e8a5809a4e860350c59476a456745cd9fee0 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_11064: b2b237d605c56ee4e2c27ccd9c779655e2b849a7 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_11064/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 01/10] dma-buf: add new dma_fence_chain container v4
  2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
                   ` (11 preceding siblings ...)
  2018-12-11 13:39 ` ✓ Fi.CI.IGT: " Patchwork
@ 2018-12-12  5:31 ` Zhou, David(ChunMing)
  12 siblings, 0 replies; 24+ messages in thread
From: Zhou, David(ChunMing) @ 2018-12-12  5:31 UTC (permalink / raw)
  To: Zhou, David(ChunMing),
	dri-devel, amd-gfx, intel-gfx, daniel.vetter, chris, eric
  Cc: Christian König, Koenig, Christian

Hi Daniel and Chris,

Could you take a look on all the patches? Can we get your RB or AB on all patches including igt patch before we submit to drm-misc? 

We already fix all existing issues, and also add  test case in IGT as your required.

Btw, the patch set is tested by below tests:
a. vulkan cts  " ./deqp-vk -n dEQP-VK. *semaphore*" 
b. internal vulkan timeline test
c. libdrm test "sudo ./amdgpu_test -s 9"
d. IGT test, "sudo ./syncobj_basic"
e. IGT test, "sudo ./syncobj_wait"
f. IGT test, "sudo ./syncobj_timeline"

Any other suggestion or requirement is welcome.

-David

> -----Original Message-----
> From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of
> Chunming Zhou
> Sent: Tuesday, December 11, 2018 6:35 PM
> To: Koenig, Christian <Christian.Koenig@amd.com>; dri-
> devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org; intel-
> gfx@lists.freedesktop.org
> Cc: Christian König <ckoenig.leichtzumerken@gmail.com>; Koenig, Christian
> <Christian.Koenig@amd.com>
> Subject: [PATCH 01/10] dma-buf: add new dma_fence_chain container v4
> 
> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> 
> Lockless container implementation similar to a dma_fence_array, but with
> only two elements per node and automatic garbage collection.
> 
> v2: properly document dma_fence_chain_for_each, add
> dma_fence_chain_find_seqno,
>     drop prev reference during garbage collection if it's not a chain fence.
> v3: use head and iterator for dma_fence_chain_for_each
> v4: fix reference count in dma_fence_chain_enable_signaling
> 
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/dma-buf/Makefile          |   3 +-
>  drivers/dma-buf/dma-fence-chain.c | 241
> ++++++++++++++++++++++++++++++
>  include/linux/dma-fence-chain.h   |  81 ++++++++++
>  3 files changed, 324 insertions(+), 1 deletion(-)  create mode 100644
> drivers/dma-buf/dma-fence-chain.c  create mode 100644 include/linux/dma-
> fence-chain.h
> 
> diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index
> 0913a6ccab5a..1f006e083eb9 100644
> --- a/drivers/dma-buf/Makefile
> +++ b/drivers/dma-buf/Makefile
> @@ -1,4 +1,5 @@
> -obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-
> fence.o
> +obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
> +	 reservation.o seqno-fence.o
>  obj-$(CONFIG_SYNC_FILE)		+= sync_file.o
>  obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o
>  obj-$(CONFIG_UDMABUF)		+= udmabuf.o
> diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-
> fence-chain.c
> new file mode 100644
> index 000000000000..0c5e3c902fa0
> --- /dev/null
> +++ b/drivers/dma-buf/dma-fence-chain.c
> @@ -0,0 +1,241 @@
> +/*
> + * fence-chain: chain fences together in a timeline
> + *
> + * Copyright (C) 2018 Advanced Micro Devices, Inc.
> + * Authors:
> + *	Christian König <christian.koenig@amd.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/dma-fence-chain.h>
> +
> +static bool dma_fence_chain_enable_signaling(struct dma_fence *fence);
> +
> +/**
> + * dma_fence_chain_get_prev - use RCU to get a reference to the
> +previous fence
> + * @chain: chain node to get the previous node from
> + *
> + * Use dma_fence_get_rcu_safe to get a reference to the previous fence
> +of the
> + * chain node.
> + */
> +static struct dma_fence *dma_fence_chain_get_prev(struct
> +dma_fence_chain *chain) {
> +	struct dma_fence *prev;
> +
> +	rcu_read_lock();
> +	prev = dma_fence_get_rcu_safe(&chain->prev);
> +	rcu_read_unlock();
> +	return prev;
> +}
> +
> +/**
> + * dma_fence_chain_walk - chain walking function
> + * @fence: current chain node
> + *
> + * Walk the chain to the next node. Returns the next fence or NULL if
> +we are at
> + * the end of the chain. Garbage collects chain nodes which are already
> + * signaled.
> + */
> +struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence) {
> +	struct dma_fence_chain *chain, *prev_chain;
> +	struct dma_fence *prev, *replacement, *tmp;
> +
> +	chain = to_dma_fence_chain(fence);
> +	if (!chain) {
> +		dma_fence_put(fence);
> +		return NULL;
> +	}
> +
> +	while ((prev = dma_fence_chain_get_prev(chain))) {
> +
> +		prev_chain = to_dma_fence_chain(prev);
> +		if (prev_chain) {
> +			if (!dma_fence_is_signaled(prev_chain->fence))
> +				break;
> +
> +			replacement =
> dma_fence_chain_get_prev(prev_chain);
> +		} else {
> +			if (!dma_fence_is_signaled(prev))
> +				break;
> +
> +			replacement = NULL;
> +		}
> +
> +		tmp = cmpxchg(&chain->prev, prev, replacement);
> +		if (tmp == prev)
> +			dma_fence_put(tmp);
> +		else
> +			dma_fence_put(replacement);
> +		dma_fence_put(prev);
> +	}
> +
> +	dma_fence_put(fence);
> +	return prev;
> +}
> +EXPORT_SYMBOL(dma_fence_chain_walk);
> +
> +/**
> + * dma_fence_chain_find_seqno - find fence chain node by seqno
> + * @pfence: pointer to the chain node where to start
> + * @seqno: the sequence number to search for
> + *
> + * Advance the fence pointer to the chain node which will signal this
> +sequence
> + * number. If no sequence number is provided then this is a no-op.
> + *
> + * Returns EINVAL if the fence is not a chain node or the sequence
> +number has
> + * not yet advanced far enough.
> + */
> +int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t
> +seqno) {
> +	struct dma_fence_chain *chain;
> +
> +	if (!seqno)
> +		return 0;
> +
> +	chain = to_dma_fence_chain(*pfence);
> +	if (!chain || chain->base.seqno < seqno)
> +		return -EINVAL;
> +
> +	dma_fence_chain_for_each(*pfence, &chain->base) {
> +		if ((*pfence)->context != chain->base.context ||
> +		    to_dma_fence_chain(*pfence)->prev_seqno < seqno)
> +			break;
> +	}
> +	dma_fence_put(&chain->base);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(dma_fence_chain_find_seqno);
> +
> +static const char *dma_fence_chain_get_driver_name(struct dma_fence
> +*fence) {
> +        return "dma_fence_chain";
> +}
> +
> +static const char *dma_fence_chain_get_timeline_name(struct dma_fence
> +*fence) {
> +        return "unbound";
> +}
> +
> +static void dma_fence_chain_irq_work(struct irq_work *work) {
> +	struct dma_fence_chain *chain;
> +
> +	chain = container_of(work, typeof(*chain), work);
> +
> +	/* Try to rearm the callback */
> +	if (!dma_fence_chain_enable_signaling(&chain->base))
> +		/* Ok, we are done. No more unsignaled fences left */
> +		dma_fence_signal(&chain->base);
> +	dma_fence_put(&chain->base);
> +}
> +
> +static void dma_fence_chain_cb(struct dma_fence *f, struct dma_fence_cb
> +*cb) {
> +	struct dma_fence_chain *chain;
> +
> +	chain = container_of(cb, typeof(*chain), cb);
> +	irq_work_queue(&chain->work);
> +	dma_fence_put(f);
> +}
> +
> +static bool dma_fence_chain_enable_signaling(struct dma_fence *fence) {
> +	struct dma_fence_chain *head = to_dma_fence_chain(fence);
> +
> +	dma_fence_get(&head->base);
> +	dma_fence_chain_for_each(fence, &head->base) {
> +		struct dma_fence_chain *chain =
> to_dma_fence_chain(fence);
> +		struct dma_fence *f = chain ? chain->fence : fence;
> +
> +		dma_fence_get(f);
> +		if (!dma_fence_add_callback(f, &head->cb,
> dma_fence_chain_cb)) {
> +			dma_fence_put(fence);
> +			return true;
> +		}
> +		dma_fence_put(f);
> +	}
> +	dma_fence_put(&head->base);
> +	return false;
> +}
> +
> +static bool dma_fence_chain_signaled(struct dma_fence *fence) {
> +	dma_fence_chain_for_each(fence, fence) {
> +		struct dma_fence_chain *chain =
> to_dma_fence_chain(fence);
> +		struct dma_fence *f = chain ? chain->fence : fence;
> +
> +		if (!dma_fence_is_signaled(f)) {
> +			dma_fence_put(fence);
> +			return false;
> +		}
> +	}
> +
> +	return true;
> +}
> +
> +static void dma_fence_chain_release(struct dma_fence *fence) {
> +	struct dma_fence_chain *chain = to_dma_fence_chain(fence);
> +
> +	dma_fence_put(chain->prev);
> +	dma_fence_put(chain->fence);
> +	dma_fence_free(fence);
> +}
> +
> +const struct dma_fence_ops dma_fence_chain_ops = {
> +	.get_driver_name = dma_fence_chain_get_driver_name,
> +	.get_timeline_name = dma_fence_chain_get_timeline_name,
> +	.enable_signaling = dma_fence_chain_enable_signaling,
> +	.signaled = dma_fence_chain_signaled,
> +	.release = dma_fence_chain_release,
> +};
> +EXPORT_SYMBOL(dma_fence_chain_ops);
> +
> +/**
> + * dma_fence_chain_init - initialize a fence chain
> + * @chain: the chain node to initialize
> + * @prev: the previous fence
> + * @fence: the current fence
> + *
> + * Initialize a new chain node and either start a new chain or add the
> +node to
> + * the existing chain of the previous fence.
> + */
> +void dma_fence_chain_init(struct dma_fence_chain *chain,
> +			  struct dma_fence *prev,
> +			  struct dma_fence *fence,
> +			  uint64_t seqno)
> +{
> +	struct dma_fence_chain *prev_chain = to_dma_fence_chain(prev);
> +	uint64_t context;
> +
> +	spin_lock_init(&chain->lock);
> +	chain->prev = prev;
> +	chain->fence = fence;
> +	chain->prev_seqno = 0;
> +	init_irq_work(&chain->work, dma_fence_chain_irq_work);
> +
> +	/* Try to reuse the context of the previous chain node. */
> +	if (prev_chain && __dma_fence_is_later(seqno, prev->seqno)) {
> +		context = prev->context;
> +		chain->prev_seqno = prev->seqno;
> +	} else {
> +		context = dma_fence_context_alloc(1);
> +		/* Make sure that we always have a valid sequence number.
> */
> +		if (prev_chain)
> +			seqno = max(prev->seqno, seqno);
> +	}
> +
> +	dma_fence_init(&chain->base, &dma_fence_chain_ops,
> +		       &chain->lock, context, seqno); }
> +EXPORT_SYMBOL(dma_fence_chain_init);
> diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-
> chain.h new file mode 100644 index 000000000000..a5c2e8c6915c
> --- /dev/null
> +++ b/include/linux/dma-fence-chain.h
> @@ -0,0 +1,81 @@
> +/*
> + * fence-chain: chain fences together in a timeline
> + *
> + * Copyright (C) 2018 Advanced Micro Devices, Inc.
> + * Authors:
> + *	Christian König <christian.koenig@amd.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.
> + */
> +
> +#ifndef __LINUX_DMA_FENCE_CHAIN_H
> +#define __LINUX_DMA_FENCE_CHAIN_H
> +
> +#include <linux/dma-fence.h>
> +#include <linux/irq_work.h>
> +
> +/**
> + * struct dma_fence_chain - fence to represent an node of a fence chain
> + * @base: fence base class
> + * @lock: spinlock for fence handling
> + * @prev: previous fence of the chain
> + * @prev_seqno: original previous seqno before garbage collection
> + * @fence: encapsulated fence
> + * @cb: callback structure for signaling
> + * @work: irq work item for signaling
> + */
> +struct dma_fence_chain {
> +	struct dma_fence base;
> +	spinlock_t lock;
> +	struct dma_fence *prev;
> +	u64 prev_seqno;
> +	struct dma_fence *fence;
> +	struct dma_fence_cb cb;
> +	struct irq_work work;
> +};
> +
> +extern const struct dma_fence_ops dma_fence_chain_ops;
> +
> +/**
> + * to_dma_fence_chain - cast a fence to a dma_fence_chain
> + * @fence: fence to cast to a dma_fence_array
> + *
> + * Returns NULL if the fence is not a dma_fence_chain,
> + * or the dma_fence_chain otherwise.
> + */
> +static inline struct dma_fence_chain *
> +to_dma_fence_chain(struct dma_fence *fence) {
> +	if (!fence || fence->ops != &dma_fence_chain_ops)
> +		return NULL;
> +
> +	return container_of(fence, struct dma_fence_chain, base); }
> +
> +/**
> + * dma_fence_chain_for_each - iterate over all fences in chain
> + * @iter: current fence
> + * @head: starting point
> + *
> + * Iterate over all fences in the chain. We keep a reference to the
> +current
> + * fence while inside the loop which must be dropped when breaking out.
> + */
> +#define dma_fence_chain_for_each(iter, head)	\
> +	for (iter = dma_fence_get(head); iter; \
> +	     iter = dma_fence_chain_walk(head))
> +
> +struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence); int
> +dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t
> seqno);
> +void dma_fence_chain_init(struct dma_fence_chain *chain,
> +			  struct dma_fence *prev,
> +			  struct dma_fence *fence,
> +			  uint64_t seqno);
> +
> +#endif /* __LINUX_DMA_FENCE_CHAIN_H */
> --
> 2.17.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 01/10] dma-buf: add new dma_fence_chain container v4
       [not found] ` <20181211103449.25899-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
  2018-12-11 10:34   ` [PATCH 07/10] drm/amdgpu: add timeline support in amdgpu CS v2 Chunming Zhou
  2018-12-11 10:34   ` [PATCH 08/10] drm/syncobj: add transition iotcls between binary and timeline v2 Chunming Zhou
@ 2018-12-13 11:29   ` Chris Wilson
  2 siblings, 0 replies; 24+ messages in thread
From: Chris Wilson @ 2018-12-13 11:29 UTC (permalink / raw)
  To: Christian.Koenig-5C7GfCeVMHo, Chunming Zhou,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Christian König, Christian König

Quoting Chunming Zhou (2018-12-11 10:34:40)
> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> 
> Lockless container implementation similar to a dma_fence_array, but with
> only two elements per node and automatic garbage collection.
> 
> v2: properly document dma_fence_chain_for_each, add dma_fence_chain_find_seqno,
>     drop prev reference during garbage collection if it's not a chain fence.
> v3: use head and iterator for dma_fence_chain_for_each
> v4: fix reference count in dma_fence_chain_enable_signaling
> 
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/dma-buf/Makefile          |   3 +-
>  drivers/dma-buf/dma-fence-chain.c | 241 ++++++++++++++++++++++++++++++
>  include/linux/dma-fence-chain.h   |  81 ++++++++++
>  3 files changed, 324 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/dma-buf/dma-fence-chain.c
>  create mode 100644 include/linux/dma-fence-chain.h
> 
> diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
> index 0913a6ccab5a..1f006e083eb9 100644
> --- a/drivers/dma-buf/Makefile
> +++ b/drivers/dma-buf/Makefile
> @@ -1,4 +1,5 @@
> -obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o
> +obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
> +        reservation.o seqno-fence.o
>  obj-$(CONFIG_SYNC_FILE)                += sync_file.o
>  obj-$(CONFIG_SW_SYNC)          += sw_sync.o sync_debug.o
>  obj-$(CONFIG_UDMABUF)          += udmabuf.o
> diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
> new file mode 100644
> index 000000000000..0c5e3c902fa0
> --- /dev/null
> +++ b/drivers/dma-buf/dma-fence-chain.c
> @@ -0,0 +1,241 @@
> +/*

SPDX-License-Identifier: GPL-2.0

> + * fence-chain: chain fences together in a timeline
> + *
> + * Copyright (C) 2018 Advanced Micro Devices, Inc.
> + * Authors:
> + *     Christian König <christian.koenig@amd.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/dma-fence-chain.h>
> +
> +static bool dma_fence_chain_enable_signaling(struct dma_fence *fence);
> +
> +/**
> + * dma_fence_chain_get_prev - use RCU to get a reference to the previous fence
> + * @chain: chain node to get the previous node from
> + *
> + * Use dma_fence_get_rcu_safe to get a reference to the previous fence of the
> + * chain node.
> + */
> +static struct dma_fence *dma_fence_chain_get_prev(struct dma_fence_chain *chain)
> +{
> +       struct dma_fence *prev;
> +
> +       rcu_read_lock();
> +       prev = dma_fence_get_rcu_safe(&chain->prev);
> +       rcu_read_unlock();
> +       return prev;
> +}
> +
> +/**
> + * dma_fence_chain_walk - chain walking function
> + * @fence: current chain node
> + *
> + * Walk the chain to the next node. Returns the next fence or NULL if we are at
> + * the end of the chain. Garbage collects chain nodes which are already
> + * signaled.
> + */
> +struct dma_fence *dma_fence_chain_walk(struct dma_fence *fence)
> +{
> +       struct dma_fence_chain *chain, *prev_chain;
> +       struct dma_fence *prev, *replacement, *tmp;
> +
> +       chain = to_dma_fence_chain(fence);
> +       if (!chain) {
> +               dma_fence_put(fence);
> +               return NULL;
> +       }
> +
> +       while ((prev = dma_fence_chain_get_prev(chain))) {
> +
> +               prev_chain = to_dma_fence_chain(prev);
> +               if (prev_chain) {
> +                       if (!dma_fence_is_signaled(prev_chain->fence))
> +                               break;
> +
> +                       replacement = dma_fence_chain_get_prev(prev_chain);
> +               } else {
> +                       if (!dma_fence_is_signaled(prev))
> +                               break;
> +
> +                       replacement = NULL;
> +               }
> +
> +               tmp = cmpxchg(&chain->prev, prev, replacement);
> +               if (tmp == prev)
> +                       dma_fence_put(tmp);
> +               else
> +                       dma_fence_put(replacement);

if (cmpxchg(&chain->prev, prev, replacement) == prev)
	dma_fence_put(prev)
else
	dma_fence_put(replacement);

would be a little easier for me to read.

> +               dma_fence_put(prev);
> +       }
> +
> +       dma_fence_put(fence);

Putting the caller's fence caught me by surprise.

I'd be tempted to do

> +
> +/**
> + * dma_fence_chain_for_each - iterate over all fences in chain
> + * @iter: current fence
> + * @head: starting point
> + *
> + * Iterate over all fences in the chain. We keep a reference to the current
> + * fence while inside the loop which must be dropped when breaking out.
> + */
> +#define dma_fence_chain_for_each(iter, head)   \
> +       for (iter = dma_fence_get(head); iter; \
> +            iter = dma_fence_chain_walk(head))

               dma_fence_chain_walk(head) <-- should be iter?

#define dma_fence_chain_for_each(iter, head)   \
       for (iter = dma_fence_get(head); iter; \
            ({ dma_fence_put(iter); iter = dma_fence_chain_walk(iter)))

just so that dma_fence_chain_walk() didn't look unbalanced and the
put/get more clearly inside the for_each.

> +       return prev;
> +}
> +EXPORT_SYMBOL(dma_fence_chain_walk);

> +
> +/**
> + * dma_fence_chain_find_seqno - find fence chain node by seqno
> + * @pfence: pointer to the chain node where to start
> + * @seqno: the sequence number to search for
> + *
> + * Advance the fence pointer to the chain node which will signal this sequence
> + * number. If no sequence number is provided then this is a no-op.
> + *
> + * Returns EINVAL if the fence is not a chain node or the sequence number has
> + * not yet advanced far enough.
> + */
> +int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)

That inout parameter took me by surprise. "find" I expected to return
the fence.

Not used in this patch, so I need to read on to see if its use
simplifies the code or is equally surprising ;)
-Chris
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-11 10:34 ` [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Chunming Zhou
@ 2018-12-13 11:37   ` Chris Wilson
  2018-12-13 12:11     ` [Intel-gfx] " Koenig, Christian
  0 siblings, 1 reply; 24+ messages in thread
From: Chris Wilson @ 2018-12-13 11:37 UTC (permalink / raw)
  To: Christian.Koenig, Chunming Zhou, amd-gfx, dri-devel, intel-gfx
  Cc: Christian König, Christian König

Quoting Chunming Zhou (2018-12-11 10:34:45)
> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> 
> Implement finding the right timeline point in drm_syncobj_find_fence.
> 
> v2: return -EINVAL when the point is not submitted yet.
> v3: fix reference counting bug, add flags handling as well
> 
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>  drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> index 76ce13dafc4d..d964b348ecba 100644
> --- a/drivers/gpu/drm/drm_syncobj.c
> +++ b/drivers/gpu/drm/drm_syncobj.c
> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
>                            struct dma_fence **fence)
>  {
>         struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
> -       int ret = 0;
> +       struct syncobj_wait_entry wait;
> +       int ret;
>  
>         if (!syncobj)
>                 return -ENOENT;
>  
>         *fence = drm_syncobj_fence_get(syncobj);
> -       if (!*fence) {
> +       drm_syncobj_put(syncobj);
> +
> +       if (*fence) {
> +               ret = dma_fence_chain_find_seqno(fence, point);
> +               if (!ret)
> +                       return 0;
> +               dma_fence_put(*fence);
> +       } else {
>                 ret = -EINVAL;
>         }
> -       drm_syncobj_put(syncobj);
> +
> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
> +               return ret;
> +
> +       memset(&wait, 0, sizeof(wait));
> +       wait.task = current;
> +       wait.point = point;
> +       drm_syncobj_fence_add_wait(syncobj, &wait);

> +
> +       do {
> +               set_current_state(TASK_INTERRUPTIBLE);
> +               if (wait.fence) {
> +                       ret = 0;
> +                       break;
> +               }
> +
> +               if (signal_pending(current)) {
> +                       ret = -ERESTARTSYS;
> +                       break;
> +               }
> +
> +               schedule();
> +       } while (1);

I've previously used a dma_fence_proxy so that we could do nonblocking
waits on future submits. That would be preferrable (a requirement for
our stupid BKL-driven code).
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-13 11:37   ` Chris Wilson
@ 2018-12-13 12:11     ` Koenig, Christian
       [not found]       ` <36d34a20-2562-4265-9abc-4d3bd6d358ef-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 24+ messages in thread
From: Koenig, Christian @ 2018-12-13 12:11 UTC (permalink / raw)
  To: Chris Wilson, Zhou, David(ChunMing),
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Christian König

Am 13.12.18 um 12:37 schrieb Chris Wilson:
> Quoting Chunming Zhou (2018-12-11 10:34:45)
>> From: Christian König <ckoenig.leichtzumerken@gmail.com>
>>
>> Implement finding the right timeline point in drm_syncobj_find_fence.
>>
>> v2: return -EINVAL when the point is not submitted yet.
>> v3: fix reference counting bug, add flags handling as well
>>
>> Signed-off-by: Christian König <christian.koenig@amd.com>
>> ---
>>   drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
>>   1 file changed, 40 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
>> index 76ce13dafc4d..d964b348ecba 100644
>> --- a/drivers/gpu/drm/drm_syncobj.c
>> +++ b/drivers/gpu/drm/drm_syncobj.c
>> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
>>                             struct dma_fence **fence)
>>   {
>>          struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
>> -       int ret = 0;
>> +       struct syncobj_wait_entry wait;
>> +       int ret;
>>   
>>          if (!syncobj)
>>                  return -ENOENT;
>>   
>>          *fence = drm_syncobj_fence_get(syncobj);
>> -       if (!*fence) {
>> +       drm_syncobj_put(syncobj);
>> +
>> +       if (*fence) {
>> +               ret = dma_fence_chain_find_seqno(fence, point);
>> +               if (!ret)
>> +                       return 0;
>> +               dma_fence_put(*fence);
>> +       } else {
>>                  ret = -EINVAL;
>>          }
>> -       drm_syncobj_put(syncobj);
>> +
>> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
>> +               return ret;
>> +
>> +       memset(&wait, 0, sizeof(wait));
>> +       wait.task = current;
>> +       wait.point = point;
>> +       drm_syncobj_fence_add_wait(syncobj, &wait);
>> +
>> +       do {
>> +               set_current_state(TASK_INTERRUPTIBLE);
>> +               if (wait.fence) {
>> +                       ret = 0;
>> +                       break;
>> +               }
>> +
>> +               if (signal_pending(current)) {
>> +                       ret = -ERESTARTSYS;
>> +                       break;
>> +               }
>> +
>> +               schedule();
>> +       } while (1);
> I've previously used a dma_fence_proxy so that we could do nonblocking
> waits on future submits. That would be preferrable (a requirement for
> our stupid BKL-driven code).

That is exactly what I would definitely NAK.

I would rather say we should come up with a wait_multiple_events() macro 
and completely nuke the custom implementation of this in:
1. dma_fence_default_wait and dma_fence_wait_any_timeout
2. the radeon fence implementation
3. the nouveau fence implementation
4. the syncobj code

Cause all of them do exactly the same. The dma_fence implementation 
unfortunately came up with a custom event handling mechanism instead of 
extending the core Linux wait_event() system.

This in turn lead to a lot of this duplicated handling.

Christian.

> -Chris

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
       [not found]       ` <36d34a20-2562-4265-9abc-4d3bd6d358ef-5C7GfCeVMHo@public.gmane.org>
@ 2018-12-13 12:21         ` Chris Wilson
  2018-12-13 12:24           ` Koenig, Christian
  0 siblings, 1 reply; 24+ messages in thread
From: Chris Wilson @ 2018-12-13 12:21 UTC (permalink / raw)
  To: Koenig, Christian, Zhou, David(ChunMing),
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Christian König

Quoting Koenig, Christian (2018-12-13 12:11:10)
> Am 13.12.18 um 12:37 schrieb Chris Wilson:
> > Quoting Chunming Zhou (2018-12-11 10:34:45)
> >> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> >>
> >> Implement finding the right timeline point in drm_syncobj_find_fence.
> >>
> >> v2: return -EINVAL when the point is not submitted yet.
> >> v3: fix reference counting bug, add flags handling as well
> >>
> >> Signed-off-by: Christian König <christian.koenig@amd.com>
> >> ---
> >>   drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
> >>   1 file changed, 40 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> >> index 76ce13dafc4d..d964b348ecba 100644
> >> --- a/drivers/gpu/drm/drm_syncobj.c
> >> +++ b/drivers/gpu/drm/drm_syncobj.c
> >> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
> >>                             struct dma_fence **fence)
> >>   {
> >>          struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
> >> -       int ret = 0;
> >> +       struct syncobj_wait_entry wait;
> >> +       int ret;
> >>   
> >>          if (!syncobj)
> >>                  return -ENOENT;
> >>   
> >>          *fence = drm_syncobj_fence_get(syncobj);
> >> -       if (!*fence) {
> >> +       drm_syncobj_put(syncobj);
> >> +
> >> +       if (*fence) {
> >> +               ret = dma_fence_chain_find_seqno(fence, point);
> >> +               if (!ret)
> >> +                       return 0;
> >> +               dma_fence_put(*fence);
> >> +       } else {
> >>                  ret = -EINVAL;
> >>          }
> >> -       drm_syncobj_put(syncobj);
> >> +
> >> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
> >> +               return ret;
> >> +
> >> +       memset(&wait, 0, sizeof(wait));
> >> +       wait.task = current;
> >> +       wait.point = point;
> >> +       drm_syncobj_fence_add_wait(syncobj, &wait);
> >> +
> >> +       do {
> >> +               set_current_state(TASK_INTERRUPTIBLE);
> >> +               if (wait.fence) {
> >> +                       ret = 0;
> >> +                       break;
> >> +               }
> >> +
> >> +               if (signal_pending(current)) {
> >> +                       ret = -ERESTARTSYS;
> >> +                       break;
> >> +               }
> >> +
> >> +               schedule();
> >> +       } while (1);
> > I've previously used a dma_fence_proxy so that we could do nonblocking
> > waits on future submits. That would be preferrable (a requirement for
> > our stupid BKL-driven code).
> 
> That is exactly what I would definitely NAK.
> 
> I would rather say we should come up with a wait_multiple_events() macro 
> and completely nuke the custom implementation of this in:
> 1. dma_fence_default_wait and dma_fence_wait_any_timeout
> 2. the radeon fence implementation
> 3. the nouveau fence implementation
> 4. the syncobj code
> 
> Cause all of them do exactly the same. The dma_fence implementation 
> unfortunately came up with a custom event handling mechanism instead of 
> extending the core Linux wait_event() system.

I don't want a blocking wait at all.
-Chris
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-13 12:21         ` Chris Wilson
@ 2018-12-13 12:24           ` Koenig, Christian
  2018-12-13 16:01             ` Daniel Vetter
  0 siblings, 1 reply; 24+ messages in thread
From: Koenig, Christian @ 2018-12-13 12:24 UTC (permalink / raw)
  To: Chris Wilson, Zhou, David(ChunMing),
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW
  Cc: Christian König

Am 13.12.18 um 13:21 schrieb Chris Wilson:
> Quoting Koenig, Christian (2018-12-13 12:11:10)
>> Am 13.12.18 um 12:37 schrieb Chris Wilson:
>>> Quoting Chunming Zhou (2018-12-11 10:34:45)
>>>> From: Christian König <ckoenig.leichtzumerken@gmail.com>
>>>>
>>>> Implement finding the right timeline point in drm_syncobj_find_fence.
>>>>
>>>> v2: return -EINVAL when the point is not submitted yet.
>>>> v3: fix reference counting bug, add flags handling as well
>>>>
>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>>> ---
>>>>    drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
>>>>    1 file changed, 40 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
>>>> index 76ce13dafc4d..d964b348ecba 100644
>>>> --- a/drivers/gpu/drm/drm_syncobj.c
>>>> +++ b/drivers/gpu/drm/drm_syncobj.c
>>>> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
>>>>                              struct dma_fence **fence)
>>>>    {
>>>>           struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
>>>> -       int ret = 0;
>>>> +       struct syncobj_wait_entry wait;
>>>> +       int ret;
>>>>    
>>>>           if (!syncobj)
>>>>                   return -ENOENT;
>>>>    
>>>>           *fence = drm_syncobj_fence_get(syncobj);
>>>> -       if (!*fence) {
>>>> +       drm_syncobj_put(syncobj);
>>>> +
>>>> +       if (*fence) {
>>>> +               ret = dma_fence_chain_find_seqno(fence, point);
>>>> +               if (!ret)
>>>> +                       return 0;
>>>> +               dma_fence_put(*fence);
>>>> +       } else {
>>>>                   ret = -EINVAL;
>>>>           }
>>>> -       drm_syncobj_put(syncobj);
>>>> +
>>>> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
>>>> +               return ret;
>>>> +
>>>> +       memset(&wait, 0, sizeof(wait));
>>>> +       wait.task = current;
>>>> +       wait.point = point;
>>>> +       drm_syncobj_fence_add_wait(syncobj, &wait);
>>>> +
>>>> +       do {
>>>> +               set_current_state(TASK_INTERRUPTIBLE);
>>>> +               if (wait.fence) {
>>>> +                       ret = 0;
>>>> +                       break;
>>>> +               }
>>>> +
>>>> +               if (signal_pending(current)) {
>>>> +                       ret = -ERESTARTSYS;
>>>> +                       break;
>>>> +               }
>>>> +
>>>> +               schedule();
>>>> +       } while (1);
>>> I've previously used a dma_fence_proxy so that we could do nonblocking
>>> waits on future submits. That would be preferrable (a requirement for
>>> our stupid BKL-driven code).
>> That is exactly what I would definitely NAK.
>>
>> I would rather say we should come up with a wait_multiple_events() macro
>> and completely nuke the custom implementation of this in:
>> 1. dma_fence_default_wait and dma_fence_wait_any_timeout
>> 2. the radeon fence implementation
>> 3. the nouveau fence implementation
>> 4. the syncobj code
>>
>> Cause all of them do exactly the same. The dma_fence implementation
>> unfortunately came up with a custom event handling mechanism instead of
>> extending the core Linux wait_event() system.
> I don't want a blocking wait at all.

Ok I wasn't clear enough :) That is exactly what I would NAK!

The wait must be blocking or otherwise you would allow wait-before-signal.

Christian.

> -Chris

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-13 12:24           ` Koenig, Christian
@ 2018-12-13 16:01             ` Daniel Vetter
       [not found]               ` <20181213160148.GG21184-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Vetter @ 2018-12-13 16:01 UTC (permalink / raw)
  To: Koenig, Christian; +Cc: Christian König, intel-gfx, dri-devel, amd-gfx

On Thu, Dec 13, 2018 at 12:24:57PM +0000, Koenig, Christian wrote:
> Am 13.12.18 um 13:21 schrieb Chris Wilson:
> > Quoting Koenig, Christian (2018-12-13 12:11:10)
> >> Am 13.12.18 um 12:37 schrieb Chris Wilson:
> >>> Quoting Chunming Zhou (2018-12-11 10:34:45)
> >>>> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> >>>>
> >>>> Implement finding the right timeline point in drm_syncobj_find_fence.
> >>>>
> >>>> v2: return -EINVAL when the point is not submitted yet.
> >>>> v3: fix reference counting bug, add flags handling as well
> >>>>
> >>>> Signed-off-by: Christian König <christian.koenig@amd.com>
> >>>> ---
> >>>>    drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
> >>>>    1 file changed, 40 insertions(+), 3 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> >>>> index 76ce13dafc4d..d964b348ecba 100644
> >>>> --- a/drivers/gpu/drm/drm_syncobj.c
> >>>> +++ b/drivers/gpu/drm/drm_syncobj.c
> >>>> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
> >>>>                              struct dma_fence **fence)
> >>>>    {
> >>>>           struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
> >>>> -       int ret = 0;
> >>>> +       struct syncobj_wait_entry wait;
> >>>> +       int ret;
> >>>>    
> >>>>           if (!syncobj)
> >>>>                   return -ENOENT;
> >>>>    
> >>>>           *fence = drm_syncobj_fence_get(syncobj);
> >>>> -       if (!*fence) {
> >>>> +       drm_syncobj_put(syncobj);
> >>>> +
> >>>> +       if (*fence) {
> >>>> +               ret = dma_fence_chain_find_seqno(fence, point);
> >>>> +               if (!ret)
> >>>> +                       return 0;
> >>>> +               dma_fence_put(*fence);
> >>>> +       } else {
> >>>>                   ret = -EINVAL;
> >>>>           }
> >>>> -       drm_syncobj_put(syncobj);
> >>>> +
> >>>> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
> >>>> +               return ret;
> >>>> +
> >>>> +       memset(&wait, 0, sizeof(wait));
> >>>> +       wait.task = current;
> >>>> +       wait.point = point;
> >>>> +       drm_syncobj_fence_add_wait(syncobj, &wait);
> >>>> +
> >>>> +       do {
> >>>> +               set_current_state(TASK_INTERRUPTIBLE);
> >>>> +               if (wait.fence) {
> >>>> +                       ret = 0;
> >>>> +                       break;
> >>>> +               }
> >>>> +
> >>>> +               if (signal_pending(current)) {
> >>>> +                       ret = -ERESTARTSYS;
> >>>> +                       break;
> >>>> +               }
> >>>> +
> >>>> +               schedule();
> >>>> +       } while (1);
> >>> I've previously used a dma_fence_proxy so that we could do nonblocking
> >>> waits on future submits. That would be preferrable (a requirement for
> >>> our stupid BKL-driven code).
> >> That is exactly what I would definitely NAK.
> >>
> >> I would rather say we should come up with a wait_multiple_events() macro
> >> and completely nuke the custom implementation of this in:
> >> 1. dma_fence_default_wait and dma_fence_wait_any_timeout
> >> 2. the radeon fence implementation
> >> 3. the nouveau fence implementation
> >> 4. the syncobj code
> >>
> >> Cause all of them do exactly the same. The dma_fence implementation
> >> unfortunately came up with a custom event handling mechanism instead of
> >> extending the core Linux wait_event() system.
> > I don't want a blocking wait at all.
> 
> Ok I wasn't clear enough :) That is exactly what I would NAK!
> 
> The wait must be blocking or otherwise you would allow wait-before-signal.

Well the current implementation is pulling a rather big trick on readers
in this regard: It looks like a dma_fence, it's implemented as one even,
heck you even open-code a dma_fence_wait here.

Except the semantics are completely different.

So aside from the discussion whether we really want to fully chain them I
think it just doesn't make sense to implement the "wait for fence submit"
as a dma_fence wait. And I'd outright remove that part from the uapi, and
force the wait. The current radv/anv plans I discussed with Jason was that
we'd have a separate submit thread, and hence unconditionally blocking
until the fence has materialized is the right thing to do. Even allowing
that option, either through a flag, or making these things look like
dma_fences (they are _not_) just tricks folks into misunderstanding what's
going on. Code sharing just because the code looks similar is imo a really
bad idea, when the semantics are entirely different (that was also the
reason behind not reusing all the cpu event stuff for dma_fence, they're
not normal cpu events).
-Daniel

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

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
       [not found]               ` <20181213160148.GG21184-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
@ 2018-12-13 16:47                 ` Koenig, Christian
  2018-12-13 17:26                   ` Daniel Vetter
  0 siblings, 1 reply; 24+ messages in thread
From: Koenig, Christian @ 2018-12-13 16:47 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Zhou, David(ChunMing),
	Christian König, intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Chris Wilson,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Am 13.12.18 um 17:01 schrieb Daniel Vetter:
> On Thu, Dec 13, 2018 at 12:24:57PM +0000, Koenig, Christian wrote:
>> Am 13.12.18 um 13:21 schrieb Chris Wilson:
>>> Quoting Koenig, Christian (2018-12-13 12:11:10)
>>>> Am 13.12.18 um 12:37 schrieb Chris Wilson:
>>>>> Quoting Chunming Zhou (2018-12-11 10:34:45)
>>>>>> From: Christian König <ckoenig.leichtzumerken@gmail.com>
>>>>>>
>>>>>> Implement finding the right timeline point in drm_syncobj_find_fence.
>>>>>>
>>>>>> v2: return -EINVAL when the point is not submitted yet.
>>>>>> v3: fix reference counting bug, add flags handling as well
>>>>>>
>>>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
>>>>>> ---
>>>>>>     drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
>>>>>>     1 file changed, 40 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
>>>>>> index 76ce13dafc4d..d964b348ecba 100644
>>>>>> --- a/drivers/gpu/drm/drm_syncobj.c
>>>>>> +++ b/drivers/gpu/drm/drm_syncobj.c
>>>>>> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
>>>>>>                               struct dma_fence **fence)
>>>>>>     {
>>>>>>            struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
>>>>>> -       int ret = 0;
>>>>>> +       struct syncobj_wait_entry wait;
>>>>>> +       int ret;
>>>>>>     
>>>>>>            if (!syncobj)
>>>>>>                    return -ENOENT;
>>>>>>     
>>>>>>            *fence = drm_syncobj_fence_get(syncobj);
>>>>>> -       if (!*fence) {
>>>>>> +       drm_syncobj_put(syncobj);
>>>>>> +
>>>>>> +       if (*fence) {
>>>>>> +               ret = dma_fence_chain_find_seqno(fence, point);
>>>>>> +               if (!ret)
>>>>>> +                       return 0;
>>>>>> +               dma_fence_put(*fence);
>>>>>> +       } else {
>>>>>>                    ret = -EINVAL;
>>>>>>            }
>>>>>> -       drm_syncobj_put(syncobj);
>>>>>> +
>>>>>> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
>>>>>> +               return ret;
>>>>>> +
>>>>>> +       memset(&wait, 0, sizeof(wait));
>>>>>> +       wait.task = current;
>>>>>> +       wait.point = point;
>>>>>> +       drm_syncobj_fence_add_wait(syncobj, &wait);
>>>>>> +
>>>>>> +       do {
>>>>>> +               set_current_state(TASK_INTERRUPTIBLE);
>>>>>> +               if (wait.fence) {
>>>>>> +                       ret = 0;
>>>>>> +                       break;
>>>>>> +               }
>>>>>> +
>>>>>> +               if (signal_pending(current)) {
>>>>>> +                       ret = -ERESTARTSYS;
>>>>>> +                       break;
>>>>>> +               }
>>>>>> +
>>>>>> +               schedule();
>>>>>> +       } while (1);
>>>>> I've previously used a dma_fence_proxy so that we could do nonblocking
>>>>> waits on future submits. That would be preferrable (a requirement for
>>>>> our stupid BKL-driven code).
>>>> That is exactly what I would definitely NAK.
>>>>
>>>> I would rather say we should come up with a wait_multiple_events() macro
>>>> and completely nuke the custom implementation of this in:
>>>> 1. dma_fence_default_wait and dma_fence_wait_any_timeout
>>>> 2. the radeon fence implementation
>>>> 3. the nouveau fence implementation
>>>> 4. the syncobj code
>>>>
>>>> Cause all of them do exactly the same. The dma_fence implementation
>>>> unfortunately came up with a custom event handling mechanism instead of
>>>> extending the core Linux wait_event() system.
>>> I don't want a blocking wait at all.
>> Ok I wasn't clear enough :) That is exactly what I would NAK!
>>
>> The wait must be blocking or otherwise you would allow wait-before-signal.
> Well the current implementation is pulling a rather big trick on readers
> in this regard: It looks like a dma_fence, it's implemented as one even,
> heck you even open-code a dma_fence_wait here.
>
> Except the semantics are completely different.
>
> So aside from the discussion whether we really want to fully chain them I
> think it just doesn't make sense to implement the "wait for fence submit"
> as a dma_fence wait. And I'd outright remove that part from the uapi, and
> force the wait. The current radv/anv plans I discussed with Jason was that
> we'd have a separate submit thread, and hence unconditionally blocking
> until the fence has materialized is the right thing to do. Even allowing
> that option, either through a flag, or making these things look like
> dma_fences (they are _not_) just tricks folks into misunderstanding what's
> going on.

Good, that sounds strongly like something I can agree on as well.

> Code sharing just because the code looks similar is imo a really
> bad idea, when the semantics are entirely different (that was also the
> reason behind not reusing all the cpu event stuff for dma_fence, they're
> not normal cpu events).

Ok, the last sentence is what I don't understand.

What exactly is the semantic difference between the dma_fence_wait and 
the wait_event interface?

I mean the wait_event interface was introduced to prevent drivers from 
openly coding an event interface and getting it wrong all the time.

So a good part of the bugs we have seen around waiting for dma-fences 
are exactly why wait_event was invented in the first place.

The only big thing I can see missing in the wait_event interface is 
waiting for many events at the same time, but that should be a rather 
easy addition.

Regards,
Christian.

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

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-13 16:47                 ` Koenig, Christian
@ 2018-12-13 17:26                   ` Daniel Vetter
  2018-12-13 18:55                     ` Koenig, Christian
  0 siblings, 1 reply; 24+ messages in thread
From: Daniel Vetter @ 2018-12-13 17:26 UTC (permalink / raw)
  To: Christian König, Maarten Lankhorst
  Cc: Christian König, intel-gfx, dri-devel, amd-gfx list

On Thu, Dec 13, 2018 at 5:47 PM Koenig, Christian
<Christian.Koenig@amd.com> wrote:
>
> Am 13.12.18 um 17:01 schrieb Daniel Vetter:
> > On Thu, Dec 13, 2018 at 12:24:57PM +0000, Koenig, Christian wrote:
> >> Am 13.12.18 um 13:21 schrieb Chris Wilson:
> >>> Quoting Koenig, Christian (2018-12-13 12:11:10)
> >>>> Am 13.12.18 um 12:37 schrieb Chris Wilson:
> >>>>> Quoting Chunming Zhou (2018-12-11 10:34:45)
> >>>>>> From: Christian König <ckoenig.leichtzumerken@gmail.com>
> >>>>>>
> >>>>>> Implement finding the right timeline point in drm_syncobj_find_fence.
> >>>>>>
> >>>>>> v2: return -EINVAL when the point is not submitted yet.
> >>>>>> v3: fix reference counting bug, add flags handling as well
> >>>>>>
> >>>>>> Signed-off-by: Christian König <christian.koenig@amd.com>
> >>>>>> ---
> >>>>>>     drivers/gpu/drm/drm_syncobj.c | 43 ++++++++++++++++++++++++++++++++---
> >>>>>>     1 file changed, 40 insertions(+), 3 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> >>>>>> index 76ce13dafc4d..d964b348ecba 100644
> >>>>>> --- a/drivers/gpu/drm/drm_syncobj.c
> >>>>>> +++ b/drivers/gpu/drm/drm_syncobj.c
> >>>>>> @@ -231,16 +231,53 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
> >>>>>>                               struct dma_fence **fence)
> >>>>>>     {
> >>>>>>            struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
> >>>>>> -       int ret = 0;
> >>>>>> +       struct syncobj_wait_entry wait;
> >>>>>> +       int ret;
> >>>>>>
> >>>>>>            if (!syncobj)
> >>>>>>                    return -ENOENT;
> >>>>>>
> >>>>>>            *fence = drm_syncobj_fence_get(syncobj);
> >>>>>> -       if (!*fence) {
> >>>>>> +       drm_syncobj_put(syncobj);
> >>>>>> +
> >>>>>> +       if (*fence) {
> >>>>>> +               ret = dma_fence_chain_find_seqno(fence, point);
> >>>>>> +               if (!ret)
> >>>>>> +                       return 0;
> >>>>>> +               dma_fence_put(*fence);
> >>>>>> +       } else {
> >>>>>>                    ret = -EINVAL;
> >>>>>>            }
> >>>>>> -       drm_syncobj_put(syncobj);
> >>>>>> +
> >>>>>> +       if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
> >>>>>> +               return ret;
> >>>>>> +
> >>>>>> +       memset(&wait, 0, sizeof(wait));
> >>>>>> +       wait.task = current;
> >>>>>> +       wait.point = point;
> >>>>>> +       drm_syncobj_fence_add_wait(syncobj, &wait);
> >>>>>> +
> >>>>>> +       do {
> >>>>>> +               set_current_state(TASK_INTERRUPTIBLE);
> >>>>>> +               if (wait.fence) {
> >>>>>> +                       ret = 0;
> >>>>>> +                       break;
> >>>>>> +               }
> >>>>>> +
> >>>>>> +               if (signal_pending(current)) {
> >>>>>> +                       ret = -ERESTARTSYS;
> >>>>>> +                       break;
> >>>>>> +               }
> >>>>>> +
> >>>>>> +               schedule();
> >>>>>> +       } while (1);
> >>>>> I've previously used a dma_fence_proxy so that we could do nonblocking
> >>>>> waits on future submits. That would be preferrable (a requirement for
> >>>>> our stupid BKL-driven code).
> >>>> That is exactly what I would definitely NAK.
> >>>>
> >>>> I would rather say we should come up with a wait_multiple_events() macro
> >>>> and completely nuke the custom implementation of this in:
> >>>> 1. dma_fence_default_wait and dma_fence_wait_any_timeout
> >>>> 2. the radeon fence implementation
> >>>> 3. the nouveau fence implementation
> >>>> 4. the syncobj code
> >>>>
> >>>> Cause all of them do exactly the same. The dma_fence implementation
> >>>> unfortunately came up with a custom event handling mechanism instead of
> >>>> extending the core Linux wait_event() system.
> >>> I don't want a blocking wait at all.
> >> Ok I wasn't clear enough :) That is exactly what I would NAK!
> >>
> >> The wait must be blocking or otherwise you would allow wait-before-signal.
> > Well the current implementation is pulling a rather big trick on readers
> > in this regard: It looks like a dma_fence, it's implemented as one even,
> > heck you even open-code a dma_fence_wait here.
> >
> > Except the semantics are completely different.
> >
> > So aside from the discussion whether we really want to fully chain them I
> > think it just doesn't make sense to implement the "wait for fence submit"
> > as a dma_fence wait. And I'd outright remove that part from the uapi, and
> > force the wait. The current radv/anv plans I discussed with Jason was that
> > we'd have a separate submit thread, and hence unconditionally blocking
> > until the fence has materialized is the right thing to do. Even allowing
> > that option, either through a flag, or making these things look like
> > dma_fences (they are _not_) just tricks folks into misunderstanding what's
> > going on.
>
> Good, that sounds strongly like something I can agree on as well.
>
> > Code sharing just because the code looks similar is imo a really
> > bad idea, when the semantics are entirely different (that was also the
> > reason behind not reusing all the cpu event stuff for dma_fence, they're
> > not normal cpu events).
>
> Ok, the last sentence is what I don't understand.
>
> What exactly is the semantic difference between the dma_fence_wait and
> the wait_event interface?
>
> I mean the wait_event interface was introduced to prevent drivers from
> openly coding an event interface and getting it wrong all the time.
>
> So a good part of the bugs we have seen around waiting for dma-fences
> are exactly why wait_event was invented in the first place.
>
> The only big thing I can see missing in the wait_event interface is
> waiting for many events at the same time, but that should be a rather
> easy addition.

So this bikeshed was years ago, maybe I should type a patch to
document it, but as far as I remember the big difference is:

- wait_event and friends generally Just Work. It can go wrong of
course, but the usual pattern is that the waker-side does and
uncoditional wake_up_all, and hence all the waiter needs to do is add
themselves to the waiter list.

- dma_buf otoh is entirely different: We wanted to support all kinds
fo signalling modes, including having interrupts disabled by default
(not sure whether we actually achieve this still with all the cpu-side
scheduling the big drivers do). Which means the waker does not
unconditionally call wake_up_all, at least not timeline, and waiters
need to call dma_fence_enable_signalling before they can add
themselves to the waiter list and call schedule().

The other bit difference is how you check for the classic wakeup races
where the event happens between when you checked for it and when you
go to sleep. Because hw is involved, the rules are again a bit
different, and their different between drivers because hw is
incoherent/broken in all kinds of ways. So there's also really tricky
things going on between adding the waiter to the waiter list and
dma_fence_enable_signalling. For pure cpu events you can ignore this
and bake the few necessary barriers into the various macros, dma_fence
needs more.

Adding Maarten, maybe there was more. I definitely remember huge&very
long discussions about all this.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Intel-gfx] [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-13 17:26                   ` Daniel Vetter
@ 2018-12-13 18:55                     ` Koenig, Christian
  0 siblings, 0 replies; 24+ messages in thread
From: Koenig, Christian @ 2018-12-13 18:55 UTC (permalink / raw)
  To: Daniel Vetter, Maarten Lankhorst
  Cc: Christian König, intel-gfx, dri-devel, amd-gfx list

Am 13.12.18 um 18:26 schrieb Daniel Vetter:
>>> Code sharing just because the code looks similar is imo a really
>>> bad idea, when the semantics are entirely different (that was also the
>>> reason behind not reusing all the cpu event stuff for dma_fence, they're
>>> not normal cpu events).
>> Ok, the last sentence is what I don't understand.
>>
>> What exactly is the semantic difference between the dma_fence_wait and
>> the wait_event interface?
>>
>> I mean the wait_event interface was introduced to prevent drivers from
>> openly coding an event interface and getting it wrong all the time.
>>
>> So a good part of the bugs we have seen around waiting for dma-fences
>> are exactly why wait_event was invented in the first place.
>>
>> The only big thing I can see missing in the wait_event interface is
>> waiting for many events at the same time, but that should be a rather
>> easy addition.
> So this bikeshed was years ago, maybe I should type a patch to
> document it, but as far as I remember the big difference is:
>
> - wait_event and friends generally Just Work. It can go wrong of
> course, but the usual pattern is that the waker-side does and
> uncoditional wake_up_all, and hence all the waiter needs to do is add
> themselves to the waiter list.
>
> - dma_buf otoh is entirely different: We wanted to support all kinds
> fo signalling modes, including having interrupts disabled by default
> (not sure whether we actually achieve this still with all the cpu-side
> scheduling the big drivers do). Which means the waker does not
> unconditionally call wake_up_all, at least not timeline, and waiters
> need to call dma_fence_enable_signalling before they can add
> themselves to the waiter list and call schedule().

Well that is not something I'm questioning because we really need this 
behavior as well.

But all of this can be perfectly implemented on top of wake_up_all.

> The other bit difference is how you check for the classic wakeup races
> where the event happens between when you checked for it and when you
> go to sleep. Because hw is involved, the rules are again a bit
> different, and their different between drivers because hw is
> incoherent/broken in all kinds of ways. So there's also really tricky
> things going on between adding the waiter to the waiter list and
> dma_fence_enable_signalling. For pure cpu events you can ignore this
> and bake the few necessary barriers into the various macros, dma_fence
> needs more.

Ah, yes I think I know what you mean with that and I also consider this 
a bad idea as well.

Only very few drivers actually need this behavior and the ones who do 
should be perfectly able to implement this inside the driver code.

The crux is that leaking this behavior into the dma-fence made it 
unnecessary complicated and result in quite a bunch of unnecessary 
irq_work and delayed_work usage.

I will take a look at this over the holidays. Shouldn't be to hard to 
fix and actually has some value additional to being just a nice cleanup.

Regards,
Christian.

>
> Adding Maarten, maybe there was more. I definitely remember huge&very
> long discussions about all this.
> -Daniel

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2018-12-13 18:55 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-11 10:34 [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chunming Zhou
2018-12-11 10:34 ` [PATCH 02/10] drm/syncobj: remove drm_syncobj_cb and cleanup Chunming Zhou
2018-12-11 10:34 ` [PATCH 03/10] drm/syncobj: add new drm_syncobj_add_point interface v3 Chunming Zhou
2018-12-11 10:34 ` [PATCH 04/10] drm/syncobj: add support for timeline point wait v8 Chunming Zhou
2018-12-11 10:34 ` [PATCH 05/10] drm/syncobj: add timeline payload query ioctl v4 Chunming Zhou
2018-12-11 10:34 ` [PATCH 06/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Chunming Zhou
2018-12-13 11:37   ` Chris Wilson
2018-12-13 12:11     ` [Intel-gfx] " Koenig, Christian
     [not found]       ` <36d34a20-2562-4265-9abc-4d3bd6d358ef-5C7GfCeVMHo@public.gmane.org>
2018-12-13 12:21         ` Chris Wilson
2018-12-13 12:24           ` Koenig, Christian
2018-12-13 16:01             ` Daniel Vetter
     [not found]               ` <20181213160148.GG21184-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2018-12-13 16:47                 ` Koenig, Christian
2018-12-13 17:26                   ` Daniel Vetter
2018-12-13 18:55                     ` Koenig, Christian
     [not found] ` <20181211103449.25899-1-david1.zhou-5C7GfCeVMHo@public.gmane.org>
2018-12-11 10:34   ` [PATCH 07/10] drm/amdgpu: add timeline support in amdgpu CS v2 Chunming Zhou
2018-12-11 10:34   ` [PATCH 08/10] drm/syncobj: add transition iotcls between binary and timeline v2 Chunming Zhou
2018-12-13 11:29   ` [Intel-gfx] [PATCH 01/10] dma-buf: add new dma_fence_chain container v4 Chris Wilson
2018-12-11 10:34 ` [PATCH 09/10] drm/syncobj: add timeline signal ioctl for syncobj v2 Chunming Zhou
2018-12-11 10:34 ` [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu Chunming Zhou
2018-12-11 11:18 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/10] dma-buf: add new dma_fence_chain container v4 Patchwork
2018-12-11 11:24 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-12-11 11:38 ` ✓ Fi.CI.BAT: success " Patchwork
2018-12-11 13:39 ` ✓ Fi.CI.IGT: " Patchwork
2018-12-12  5:31 ` [PATCH 01/10] " Zhou, David(ChunMing)

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.