AMD-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
@ 2018-12-04 11:59 Christian König
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel, amd-gfx

For a lot of use cases we need 64bit sequence numbers. Currently drivers
overload the dma_fence structure to store the additional bits.

Stop doing that and make the sequence number in the dma_fence always
64bit.

For compatibility with hardware which can do only 32bit sequences the
comparisons in __dma_fence_is_later only takes the lower 32bits as significant
when the upper 32bits are all zero.

v2: change the logic in __dma_fence_is_later

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/dma-buf/dma-fence.c            |  2 +-
 drivers/dma-buf/sw_sync.c              |  2 +-
 drivers/dma-buf/sync_file.c            |  4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c |  2 +-
 drivers/gpu/drm/i915/i915_sw_fence.c   |  2 +-
 drivers/gpu/drm/i915/intel_engine_cs.c |  2 +-
 drivers/gpu/drm/vgem/vgem_fence.c      |  4 ++--
 include/linux/dma-fence.h              | 22 +++++++++++++++-------
 8 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 136ec04d683f..3aa8733f832a 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -649,7 +649,7 @@ EXPORT_SYMBOL(dma_fence_wait_any_timeout);
  */
 void
 dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
-	       spinlock_t *lock, u64 context, unsigned seqno)
+	       spinlock_t *lock, u64 context, u64 seqno)
 {
 	BUG_ON(!lock);
 	BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 53c1d6d36a64..32dcf7b4c935 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -172,7 +172,7 @@ static bool timeline_fence_enable_signaling(struct dma_fence *fence)
 static void timeline_fence_value_str(struct dma_fence *fence,
 				    char *str, int size)
 {
-	snprintf(str, size, "%d", fence->seqno);
+	snprintf(str, size, "%lld", fence->seqno);
 }
 
 static void timeline_fence_timeline_value_str(struct dma_fence *fence,
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 35dd06479867..4f6305ca52c8 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -144,7 +144,7 @@ char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
 	} else {
 		struct dma_fence *fence = sync_file->fence;
 
-		snprintf(buf, len, "%s-%s%llu-%d",
+		snprintf(buf, len, "%s-%s%llu-%lld",
 			 fence->ops->get_driver_name(fence),
 			 fence->ops->get_timeline_name(fence),
 			 fence->context,
@@ -258,7 +258,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
 
 			i_b++;
 		} else {
-			if (pt_a->seqno - pt_b->seqno <= INT_MAX)
+			if (__dma_fence_is_later(pt_a->seqno, pt_b->seqno))
 				add_fence(fences, &i, pt_a);
 			else
 				add_fence(fences, &i, pt_b);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index 12f2bf97611f..bfaf5c6323be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -388,7 +388,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
 			   soffset, eoffset, eoffset - soffset);
 
 		if (i->fence)
-			seq_printf(m, " protected by 0x%08x on context %llu",
+			seq_printf(m, " protected by 0x%016llx on context %llu",
 				   i->fence->seqno, i->fence->context);
 
 		seq_printf(m, "\n");
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
index 6dbeed079ae5..11bcdabd5177 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -393,7 +393,7 @@ static void timer_i915_sw_fence_wake(struct timer_list *t)
 	if (!fence)
 		return;
 
-	pr_notice("Asynchronous wait on fence %s:%s:%x timed out (hint:%pS)\n",
+	pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%pS)\n",
 		  cb->dma->ops->get_driver_name(cb->dma),
 		  cb->dma->ops->get_timeline_name(cb->dma),
 		  cb->dma->seqno,
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 217ed3ee1cab..f28a66c67d34 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1236,7 +1236,7 @@ static void print_request(struct drm_printer *m,
 
 	x = print_sched_attr(rq->i915, &rq->sched.attr, buf, x, sizeof(buf));
 
-	drm_printf(m, "%s%x%s [%llx:%x]%s @ %dms: %s\n",
+	drm_printf(m, "%s%x%s [%llx:%llx]%s @ %dms: %s\n",
 		   prefix,
 		   rq->global_seqno,
 		   i915_request_completed(rq) ? "!" : "",
diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
index c1c420afe2dd..eb17c0cd3727 100644
--- a/drivers/gpu/drm/vgem/vgem_fence.c
+++ b/drivers/gpu/drm/vgem/vgem_fence.c
@@ -53,13 +53,13 @@ static void vgem_fence_release(struct dma_fence *base)
 
 static void vgem_fence_value_str(struct dma_fence *fence, char *str, int size)
 {
-	snprintf(str, size, "%u", fence->seqno);
+	snprintf(str, size, "%llu", fence->seqno);
 }
 
 static void vgem_fence_timeline_value_str(struct dma_fence *fence, char *str,
 					  int size)
 {
-	snprintf(str, size, "%u",
+	snprintf(str, size, "%llu",
 		 dma_fence_is_signaled(fence) ? fence->seqno : 0);
 }
 
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index 999e4b104410..6b788467b2e3 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -77,7 +77,7 @@ struct dma_fence {
 	struct list_head cb_list;
 	spinlock_t *lock;
 	u64 context;
-	unsigned seqno;
+	u64 seqno;
 	unsigned long flags;
 	ktime_t timestamp;
 	int error;
@@ -244,7 +244,7 @@ struct dma_fence_ops {
 };
 
 void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
-		    spinlock_t *lock, u64 context, unsigned seqno);
+		    spinlock_t *lock, u64 context, u64 seqno);
 
 void dma_fence_release(struct kref *kref);
 void dma_fence_free(struct dma_fence *fence);
@@ -414,9 +414,17 @@ dma_fence_is_signaled(struct dma_fence *fence)
  * Returns true if f1 is chronologically later than f2. Both fences must be
  * from the same context, since a seqno is not common across contexts.
  */
-static inline bool __dma_fence_is_later(u32 f1, u32 f2)
+static inline bool __dma_fence_is_later(u64 f1, u64 f2)
 {
-	return (int)(f1 - f2) > 0;
+	/* This is for backward compatibility with drivers which can only handle
+	 * 32bit sequence numbers. Use a 64bit compare when any of the higher
+	 * bits are none zero, otherwise use a 32bit compare with wrap around
+	 * handling.
+	 */
+	if (upper_32_bits(f1) || upper_32_bits(f2))
+		return f1 > f2;
+
+	return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0;
 }
 
 /**
@@ -548,21 +556,21 @@ u64 dma_fence_context_alloc(unsigned num);
 	do {								\
 		struct dma_fence *__ff = (f);				\
 		if (IS_ENABLED(CONFIG_DMA_FENCE_TRACE))			\
-			pr_info("f %llu#%u: " fmt,			\
+			pr_info("f %llu#%llu: " fmt,			\
 				__ff->context, __ff->seqno, ##args);	\
 	} while (0)
 
 #define DMA_FENCE_WARN(f, fmt, args...) \
 	do {								\
 		struct dma_fence *__ff = (f);				\
-		pr_warn("f %llu#%u: " fmt, __ff->context, __ff->seqno,	\
+		pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\
 			 ##args);					\
 	} while (0)
 
 #define DMA_FENCE_ERR(f, fmt, args...) \
 	do {								\
 		struct dma_fence *__ff = (f);				\
-		pr_err("f %llu#%u: " fmt, __ff->context, __ff->seqno,	\
+		pr_err("f %llu#%llu: " fmt, __ff->context, __ff->seqno,	\
 			##args);					\
 	} while (0)
 
-- 
2.14.1

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

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

* [PATCH 02/10] dma-buf: add new dma_fence_chain container v3
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 12:19     ` Chunming Zhou
  2018-12-04 11:59   ` [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2" Christian König
                     ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/dma-buf/Makefile          |   3 +-
 drivers/dma-buf/dma-fence-chain.c | 234 ++++++++++++++++++++++++++++++++++++++
 include/linux/dma-fence-chain.h   |  81 +++++++++++++
 3 files changed, 317 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..1ec234d66081
--- /dev/null
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -0,0 +1,234 @@
+/*
+ * 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);
+}
+
+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_chain_for_each(fence, &head->base) {
+		struct dma_fence_chain *chain = to_dma_fence_chain(fence);
+		struct dma_fence *f = chain ? chain->fence : fence;
+
+		if (!dma_fence_add_callback(f, &head->cb, dma_fence_chain_cb))
+			return true;
+	}
+	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.14.1

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

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

* [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2"
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-12-04 11:59   ` [PATCH 02/10] dma-buf: add new dma_fence_chain container v3 Christian König
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 12:20     ` Chunming Zhou
  2018-12-04 11:59   ` [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup Christian König
                     ` (6 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

This reverts commit 9a09a42369a4a37a959c051d8e1a1f948c1529a4.

The whole interface isn't thought through. Since this function can't
fail we actually can't allocate an object to store the sync point.

Sorry, I should have taken the lead on this from the very beginning and
reviewed it more thoughtfully. Going to propose a new interface as a
follow up change.

Signed-off-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     |  2 +-
 drivers/gpu/drm/drm_syncobj.c              | 14 ++++++--------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  2 +-
 drivers/gpu/drm/v3d/v3d_gem.c              |  3 +--
 drivers/gpu/drm/vc4/vc4_gem.c              |  2 +-
 include/drm/drm_syncobj.h                  |  2 +-
 6 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index c0740a924769..149b3065119b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1200,7 +1200,7 @@ 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], 0, p->fence);
+		drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence);
 }
 
 static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 5c5ba1f14307..db30a0e89db8 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -140,13 +140,11 @@ void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
 /**
  * drm_syncobj_replace_fence - replace fence in a sync object.
  * @syncobj: Sync object to replace fence in
- * @point: timeline point
  * @fence: fence to install in sync file.
  *
- * This replaces the fence on a sync object, or a timeline point fence.
+ * This replaces the fence on a sync object.
  */
 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
-			       u64 point,
 			       struct dma_fence *fence)
 {
 	struct dma_fence *old_fence;
@@ -184,7 +182,7 @@ static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
 {
 	struct dma_fence *fence = dma_fence_get_stub();
 
-	drm_syncobj_replace_fence(syncobj, 0, fence);
+	drm_syncobj_replace_fence(syncobj, fence);
 	dma_fence_put(fence);
 }
 
@@ -233,7 +231,7 @@ void drm_syncobj_free(struct kref *kref)
 	struct drm_syncobj *syncobj = container_of(kref,
 						   struct drm_syncobj,
 						   refcount);
-	drm_syncobj_replace_fence(syncobj, 0, NULL);
+	drm_syncobj_replace_fence(syncobj, NULL);
 	kfree(syncobj);
 }
 EXPORT_SYMBOL(drm_syncobj_free);
@@ -267,7 +265,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
 		drm_syncobj_assign_null_handle(syncobj);
 
 	if (fence)
-		drm_syncobj_replace_fence(syncobj, 0, fence);
+		drm_syncobj_replace_fence(syncobj, fence);
 
 	*out_syncobj = syncobj;
 	return 0;
@@ -452,7 +450,7 @@ static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
 		return -ENOENT;
 	}
 
-	drm_syncobj_replace_fence(syncobj, 0, fence);
+	drm_syncobj_replace_fence(syncobj, fence);
 	dma_fence_put(fence);
 	drm_syncobj_put(syncobj);
 	return 0;
@@ -923,7 +921,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
 		return ret;
 
 	for (i = 0; i < args->count_handles; i++)
-		drm_syncobj_replace_fence(syncobjs[i], 0, NULL);
+		drm_syncobj_replace_fence(syncobjs[i], NULL);
 
 	drm_syncobj_array_free(syncobjs, args->count_handles);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 1aaccbe7e1de..786d719e652d 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -2186,7 +2186,7 @@ signal_fence_array(struct i915_execbuffer *eb,
 		if (!(flags & I915_EXEC_FENCE_SIGNAL))
 			continue;
 
-		drm_syncobj_replace_fence(syncobj, 0, fence);
+		drm_syncobj_replace_fence(syncobj, fence);
 	}
 }
 
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index b88c96911453..655be1a865fa 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -588,8 +588,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
 	/* Update the return sync object for the */
 	sync_out = drm_syncobj_find(file_priv, args->out_sync);
 	if (sync_out) {
-		drm_syncobj_replace_fence(sync_out, 0,
-					  exec->render_done_fence);
+		drm_syncobj_replace_fence(sync_out, exec->render_done_fence);
 		drm_syncobj_put(sync_out);
 	}
 
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 41881ce4132d..aea2b8dfec17 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -681,7 +681,7 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
 	exec->fence = &fence->base;
 
 	if (out_sync)
-		drm_syncobj_replace_fence(out_sync, 0, exec->fence);
+		drm_syncobj_replace_fence(out_sync, exec->fence);
 
 	vc4_update_bo_seqnos(exec, seqno);
 
diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
index 2eda44def639..b1fe921f8e8f 100644
--- a/include/drm/drm_syncobj.h
+++ b/include/drm/drm_syncobj.h
@@ -131,7 +131,7 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
 
 struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
 				     u32 handle);
-void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, u64 point,
+void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
 			       struct dma_fence *fence);
 int drm_syncobj_find_fence(struct drm_file *file_private,
 			   u32 handle, u64 point, u64 flags,
-- 
2.14.1

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

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

* [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-12-04 11:59   ` [PATCH 02/10] dma-buf: add new dma_fence_chain container v3 Christian König
  2018-12-04 11:59   ` [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2" Christian König
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 12:29     ` Chunming Zhou
  2018-12-05 10:00     ` Christian König
  2018-12-04 11:59   ` [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2 Christian König
                     ` (5 subsequent siblings)
  8 siblings, 2 replies; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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.14.1

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

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

* [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (2 preceding siblings ...)
  2018-12-04 11:59   ` [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup Christian König
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 12:31     ` Chunming Zhou
  2018-12-04 11:59   ` [PATCH 07/10] drm/syncobj: add timeline payload query ioctl v4 Christian König
                     ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

v2: rebase and cleanup

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..64fcfea1c39f 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 = rcu_dereference_protected(syncobj->fence,
+					 lockdep_is_held(&syncobj->lock));
+	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);
+}
+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.14.1

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

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

* [PATCH 06/10] drm/syncobj: add support for timeline point wait v7
  2018-12-04 11:59 [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2 Christian König
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
@ 2018-12-04 11:59 ` Christian König
  2018-12-04 11:59 ` [PATCH 09/10] drm/amdgpu: add timeline support in amdgpu CS v2 Christian König
  2 siblings, 0 replies; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel, amd-gfx

From: Chunming Zhou <david1.zhou@amd.com>

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

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  | 151 +++++++++++++++++++++++++++++++++--------
 include/uapi/drm/drm.h         |  15 ++++
 4 files changed, 140 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 0c4eb4a9ab31..566d44e3c782 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -183,6 +183,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 64fcfea1c39f..86063475f46c 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,9 @@ 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;
+	int ret;
+
 	if (wait->fence)
 		return;
 
@@ -103,11 +107,14 @@ 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));
+	ret = dma_fence_chain_find_seqno(&fence, wait->point);
+	if (ret) {
+		dma_fence_put(fence);
 		list_add_tail(&wait->node, &syncobj->cb_list);
+	} else {
+		wait->fence = fence;
+	}
 	spin_unlock(&syncobj->lock);
 }
 
@@ -148,10 +155,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,25 @@ 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;
+	int ret;
+
 	/* This happens inside the syncobj lock */
-	wait->fence = dma_fence_get(rcu_dereference_protected(syncobj->fence,
-							      lockdep_is_held(&syncobj->lock)));
-	wake_up_process(wait->task);
+	fence = rcu_dereference_protected(syncobj->fence,
+					  lockdep_is_held(&syncobj->lock));
+	dma_fence_get(fence);
+	ret = dma_fence_chain_find_seqno(&fence, wait->point);
+	if (ret) {
+		dma_fence_put(fence);
+	} 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 +671,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 +699,15 @@ 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;
+		int ret;
+
 		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]);
+		ret = dma_fence_chain_find_seqno(&fence, points[i]);
+		if (ret) {
+			dma_fence_put(fence);
 			if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
 				continue;
 			} else {
@@ -679,8 +715,10 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 				goto cleanup_entries;
 			}
 		}
+		entries[i].fence = fence;
 
-		if (dma_fence_is_signaled(entries[i].fence)) {
+		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 +751,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 +797,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
 	}
 	kfree(entries);
 
+err_free_points:
+	kfree(points);
+
 	return timeout;
 }
 
@@ -796,19 +838,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 +950,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 cebdb2541eb7..627032df23e6 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -738,6 +738,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 */
@@ -748,6 +749,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;
@@ -910,6 +924,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.14.1

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

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

* [PATCH 07/10] drm/syncobj: add timeline payload query ioctl v4
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (3 preceding siblings ...)
  2018-12-04 11:59   ` [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2 Christian König
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 11:59   ` [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Christian König
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Chunming Zhou <david1.zhou@amd.com>

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  | 40 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/drm/drm.h         | 11 +++++++++++
 4 files changed, 55 insertions(+)

diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 566d44e3c782..9c4826411a3c 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -189,6 +189,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 86063475f46c..ee44cf2a8a12 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1057,3 +1057,43 @@ 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_query *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->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 627032df23e6..14ca02a3d5f2 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -768,6 +768,15 @@ struct drm_syncobj_array {
 	__u32 pad;
 };
 
+struct drm_syncobj_timeline_query {
+	__u64 handles;
+	/* points are timeline syncobjs payloads returned by query ioctl */
+	__u64 points;
+	__u32 count_handles;
+	__u32 pad;
+};
+
+
 /* Query current scanout sequence number */
 struct drm_crtc_get_sequence {
 	__u32 crtc_id;		/* requested crtc_id */
@@ -925,6 +934,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_query)
+
 /**
  * Device specific ioctls should only be in their respective headers
  * The device specific ioctl range is from 0x40 to 0x9f.
-- 
2.14.1

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

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

* [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (4 preceding siblings ...)
  2018-12-04 11:59   ` [PATCH 07/10] drm/syncobj: add timeline payload query ioctl v4 Christian König
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 12:47     ` Chunming Zhou
  2018-12-04 11:59   ` [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu Christian König
                     ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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 ee44cf2a8a12..fdbec8cedc3d 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.14.1

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

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

* [PATCH 09/10] drm/amdgpu: add timeline support in amdgpu CS v2
  2018-12-04 11:59 [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2 Christian König
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
  2018-12-04 11:59 ` [PATCH 06/10] drm/syncobj: add support for timeline point wait v7 Christian König
@ 2018-12-04 11:59 ` Christian König
  2 siblings, 0 replies; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel, amd-gfx

From: Chunming Zhou <david1.zhou@amd.com>

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 aa26a144c7f5..c1cd1c8ee6ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -429,6 +429,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;
@@ -458,8 +464,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 149b3065119b..c61fb0e6881b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -214,6 +214,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:
@@ -803,9 +805,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);
 
@@ -1107,13 +1111,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);
@@ -1124,46 +1133,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;
 }
 
@@ -1177,18 +1255,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;
 		}
 	}
 
@@ -1199,8 +1291,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.14.1

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

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

* [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (5 preceding siblings ...)
  2018-12-04 11:59   ` [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Christian König
@ 2018-12-04 11:59   ` Christian König
  2018-12-04 12:12   ` [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2 Chunming Zhou
  2018-12-04 12:52   ` Chris Wilson
  8 siblings, 0 replies; 21+ messages in thread
From: Christian König @ 2018-12-04 11:59 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

From: Chunming Zhou <david1.zhou@amd.com>

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 90f474f98b6e..316bfc1a6a75 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.14.1

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

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

* Re: [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (6 preceding siblings ...)
  2018-12-04 11:59   ` [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu Christian König
@ 2018-12-04 12:12   ` Chunming Zhou
  2018-12-04 12:52   ` Chris Wilson
  8 siblings, 0 replies; 21+ messages in thread
From: Chunming Zhou @ 2018-12-04 12:12 UTC (permalink / raw)
  To: Christian König,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org



在 2018/12/4 19:59, Christian König 写道:
> For a lot of use cases we need 64bit sequence numbers. Currently drivers
> overload the dma_fence structure to store the additional bits.
>
> Stop doing that and make the sequence number in the dma_fence always
> 64bit.
>
> For compatibility with hardware which can do only 32bit sequences the
> comparisons in __dma_fence_is_later only takes the lower 32bits as significant
> when the upper 32bits are all zero.
>
> v2: change the logic in __dma_fence_is_later
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>

> ---
>   drivers/dma-buf/dma-fence.c            |  2 +-
>   drivers/dma-buf/sw_sync.c              |  2 +-
>   drivers/dma-buf/sync_file.c            |  4 ++--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c |  2 +-
>   drivers/gpu/drm/i915/i915_sw_fence.c   |  2 +-
>   drivers/gpu/drm/i915/intel_engine_cs.c |  2 +-
>   drivers/gpu/drm/vgem/vgem_fence.c      |  4 ++--
>   include/linux/dma-fence.h              | 22 +++++++++++++++-------
>   8 files changed, 24 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
> index 136ec04d683f..3aa8733f832a 100644
> --- a/drivers/dma-buf/dma-fence.c
> +++ b/drivers/dma-buf/dma-fence.c
> @@ -649,7 +649,7 @@ EXPORT_SYMBOL(dma_fence_wait_any_timeout);
>    */
>   void
>   dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
> -	       spinlock_t *lock, u64 context, unsigned seqno)
> +	       spinlock_t *lock, u64 context, u64 seqno)
>   {
>   	BUG_ON(!lock);
>   	BUG_ON(!ops || !ops->get_driver_name || !ops->get_timeline_name);
> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> index 53c1d6d36a64..32dcf7b4c935 100644
> --- a/drivers/dma-buf/sw_sync.c
> +++ b/drivers/dma-buf/sw_sync.c
> @@ -172,7 +172,7 @@ static bool timeline_fence_enable_signaling(struct dma_fence *fence)
>   static void timeline_fence_value_str(struct dma_fence *fence,
>   				    char *str, int size)
>   {
> -	snprintf(str, size, "%d", fence->seqno);
> +	snprintf(str, size, "%lld", fence->seqno);
>   }
>   
>   static void timeline_fence_timeline_value_str(struct dma_fence *fence,
> diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
> index 35dd06479867..4f6305ca52c8 100644
> --- a/drivers/dma-buf/sync_file.c
> +++ b/drivers/dma-buf/sync_file.c
> @@ -144,7 +144,7 @@ char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
>   	} else {
>   		struct dma_fence *fence = sync_file->fence;
>   
> -		snprintf(buf, len, "%s-%s%llu-%d",
> +		snprintf(buf, len, "%s-%s%llu-%lld",
>   			 fence->ops->get_driver_name(fence),
>   			 fence->ops->get_timeline_name(fence),
>   			 fence->context,
> @@ -258,7 +258,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
>   
>   			i_b++;
>   		} else {
> -			if (pt_a->seqno - pt_b->seqno <= INT_MAX)
> +			if (__dma_fence_is_later(pt_a->seqno, pt_b->seqno))
>   				add_fence(fences, &i, pt_a);
>   			else
>   				add_fence(fences, &i, pt_b);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
> index 12f2bf97611f..bfaf5c6323be 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
> @@ -388,7 +388,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
>   			   soffset, eoffset, eoffset - soffset);
>   
>   		if (i->fence)
> -			seq_printf(m, " protected by 0x%08x on context %llu",
> +			seq_printf(m, " protected by 0x%016llx on context %llu",
>   				   i->fence->seqno, i->fence->context);
>   
>   		seq_printf(m, "\n");
> diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c
> index 6dbeed079ae5..11bcdabd5177 100644
> --- a/drivers/gpu/drm/i915/i915_sw_fence.c
> +++ b/drivers/gpu/drm/i915/i915_sw_fence.c
> @@ -393,7 +393,7 @@ static void timer_i915_sw_fence_wake(struct timer_list *t)
>   	if (!fence)
>   		return;
>   
> -	pr_notice("Asynchronous wait on fence %s:%s:%x timed out (hint:%pS)\n",
> +	pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%pS)\n",
>   		  cb->dma->ops->get_driver_name(cb->dma),
>   		  cb->dma->ops->get_timeline_name(cb->dma),
>   		  cb->dma->seqno,
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
> index 217ed3ee1cab..f28a66c67d34 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -1236,7 +1236,7 @@ static void print_request(struct drm_printer *m,
>   
>   	x = print_sched_attr(rq->i915, &rq->sched.attr, buf, x, sizeof(buf));
>   
> -	drm_printf(m, "%s%x%s [%llx:%x]%s @ %dms: %s\n",
> +	drm_printf(m, "%s%x%s [%llx:%llx]%s @ %dms: %s\n",
>   		   prefix,
>   		   rq->global_seqno,
>   		   i915_request_completed(rq) ? "!" : "",
> diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c
> index c1c420afe2dd..eb17c0cd3727 100644
> --- a/drivers/gpu/drm/vgem/vgem_fence.c
> +++ b/drivers/gpu/drm/vgem/vgem_fence.c
> @@ -53,13 +53,13 @@ static void vgem_fence_release(struct dma_fence *base)
>   
>   static void vgem_fence_value_str(struct dma_fence *fence, char *str, int size)
>   {
> -	snprintf(str, size, "%u", fence->seqno);
> +	snprintf(str, size, "%llu", fence->seqno);
>   }
>   
>   static void vgem_fence_timeline_value_str(struct dma_fence *fence, char *str,
>   					  int size)
>   {
> -	snprintf(str, size, "%u",
> +	snprintf(str, size, "%llu",
>   		 dma_fence_is_signaled(fence) ? fence->seqno : 0);
>   }
>   
> diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
> index 999e4b104410..6b788467b2e3 100644
> --- a/include/linux/dma-fence.h
> +++ b/include/linux/dma-fence.h
> @@ -77,7 +77,7 @@ struct dma_fence {
>   	struct list_head cb_list;
>   	spinlock_t *lock;
>   	u64 context;
> -	unsigned seqno;
> +	u64 seqno;
>   	unsigned long flags;
>   	ktime_t timestamp;
>   	int error;
> @@ -244,7 +244,7 @@ struct dma_fence_ops {
>   };
>   
>   void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
> -		    spinlock_t *lock, u64 context, unsigned seqno);
> +		    spinlock_t *lock, u64 context, u64 seqno);
>   
>   void dma_fence_release(struct kref *kref);
>   void dma_fence_free(struct dma_fence *fence);
> @@ -414,9 +414,17 @@ dma_fence_is_signaled(struct dma_fence *fence)
>    * Returns true if f1 is chronologically later than f2. Both fences must be
>    * from the same context, since a seqno is not common across contexts.
>    */
> -static inline bool __dma_fence_is_later(u32 f1, u32 f2)
> +static inline bool __dma_fence_is_later(u64 f1, u64 f2)
>   {
> -	return (int)(f1 - f2) > 0;
> +	/* This is for backward compatibility with drivers which can only handle
> +	 * 32bit sequence numbers. Use a 64bit compare when any of the higher
> +	 * bits are none zero, otherwise use a 32bit compare with wrap around
> +	 * handling.
> +	 */
> +	if (upper_32_bits(f1) || upper_32_bits(f2))
> +		return f1 > f2;
> +
> +	return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0;
>   }
>   
>   /**
> @@ -548,21 +556,21 @@ u64 dma_fence_context_alloc(unsigned num);
>   	do {								\
>   		struct dma_fence *__ff = (f);				\
>   		if (IS_ENABLED(CONFIG_DMA_FENCE_TRACE))			\
> -			pr_info("f %llu#%u: " fmt,			\
> +			pr_info("f %llu#%llu: " fmt,			\
>   				__ff->context, __ff->seqno, ##args);	\
>   	} while (0)
>   
>   #define DMA_FENCE_WARN(f, fmt, args...) \
>   	do {								\
>   		struct dma_fence *__ff = (f);				\
> -		pr_warn("f %llu#%u: " fmt, __ff->context, __ff->seqno,	\
> +		pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\
>   			 ##args);					\
>   	} while (0)
>   
>   #define DMA_FENCE_ERR(f, fmt, args...) \
>   	do {								\
>   		struct dma_fence *__ff = (f);				\
> -		pr_err("f %llu#%u: " fmt, __ff->context, __ff->seqno,	\
> +		pr_err("f %llu#%llu: " fmt, __ff->context, __ff->seqno,	\
>   			##args);					\
>   	} while (0)
>   

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

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

* Re: [PATCH 02/10] dma-buf: add new dma_fence_chain container v3
  2018-12-04 11:59   ` [PATCH 02/10] dma-buf: add new dma_fence_chain container v3 Christian König
@ 2018-12-04 12:19     ` Chunming Zhou
  0 siblings, 0 replies; 21+ messages in thread
From: Chunming Zhou @ 2018-12-04 12:19 UTC (permalink / raw)
  To: Christian König, dri-devel@lists.freedesktop.org,
	amd-gfx@lists.freedesktop.org



在 2018/12/4 19:59, Christian König 写道:
> 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
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Chunming Zhou <david1.zhou@amd.com>

> ---
>   drivers/dma-buf/Makefile          |   3 +-
>   drivers/dma-buf/dma-fence-chain.c | 234 ++++++++++++++++++++++++++++++++++++++
>   include/linux/dma-fence-chain.h   |  81 +++++++++++++
>   3 files changed, 317 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..1ec234d66081
> --- /dev/null
> +++ b/drivers/dma-buf/dma-fence-chain.c
> @@ -0,0 +1,234 @@
> +/*
> + * 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);
> +}
> +
> +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_chain_for_each(fence, &head->base) {
> +		struct dma_fence_chain *chain = to_dma_fence_chain(fence);
> +		struct dma_fence *f = chain ? chain->fence : fence;
> +
> +		if (!dma_fence_add_callback(f, &head->cb, dma_fence_chain_cb))
> +			return true;
> +	}
> +	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 */

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

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

* Re: [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2"
  2018-12-04 11:59   ` [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2" Christian König
@ 2018-12-04 12:20     ` Chunming Zhou
  0 siblings, 0 replies; 21+ messages in thread
From: Chunming Zhou @ 2018-12-04 12:20 UTC (permalink / raw)
  To: Christian König, dri-devel@lists.freedesktop.org,
	amd-gfx@lists.freedesktop.org



在 2018/12/4 19:59, Christian König 写道:
> This reverts commit 9a09a42369a4a37a959c051d8e1a1f948c1529a4.
>
> The whole interface isn't thought through. Since this function can't
> fail we actually can't allocate an object to store the sync point.
>
> Sorry, I should have taken the lead on this from the very beginning and
> reviewed it more thoughtfully. Going to propose a new interface as a
> follow up change.
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     |  2 +-
>   drivers/gpu/drm/drm_syncobj.c              | 14 ++++++--------
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c |  2 +-
>   drivers/gpu/drm/v3d/v3d_gem.c              |  3 +--
>   drivers/gpu/drm/vc4/vc4_gem.c              |  2 +-
>   include/drm/drm_syncobj.h                  |  2 +-
>   6 files changed, 11 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index c0740a924769..149b3065119b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -1200,7 +1200,7 @@ 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], 0, p->fence);
> +		drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence);
>   }
>   
>   static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
> diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> index 5c5ba1f14307..db30a0e89db8 100644
> --- a/drivers/gpu/drm/drm_syncobj.c
> +++ b/drivers/gpu/drm/drm_syncobj.c
> @@ -140,13 +140,11 @@ void drm_syncobj_remove_callback(struct drm_syncobj *syncobj,
>   /**
>    * drm_syncobj_replace_fence - replace fence in a sync object.
>    * @syncobj: Sync object to replace fence in
> - * @point: timeline point
>    * @fence: fence to install in sync file.
>    *
> - * This replaces the fence on a sync object, or a timeline point fence.
> + * This replaces the fence on a sync object.
>    */
>   void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
> -			       u64 point,
>   			       struct dma_fence *fence)
>   {
>   	struct dma_fence *old_fence;
> @@ -184,7 +182,7 @@ static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
>   {
>   	struct dma_fence *fence = dma_fence_get_stub();
>   
> -	drm_syncobj_replace_fence(syncobj, 0, fence);
> +	drm_syncobj_replace_fence(syncobj, fence);
>   	dma_fence_put(fence);
>   }
>   
> @@ -233,7 +231,7 @@ void drm_syncobj_free(struct kref *kref)
>   	struct drm_syncobj *syncobj = container_of(kref,
>   						   struct drm_syncobj,
>   						   refcount);
> -	drm_syncobj_replace_fence(syncobj, 0, NULL);
> +	drm_syncobj_replace_fence(syncobj, NULL);
>   	kfree(syncobj);
>   }
>   EXPORT_SYMBOL(drm_syncobj_free);
> @@ -267,7 +265,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
>   		drm_syncobj_assign_null_handle(syncobj);
>   
>   	if (fence)
> -		drm_syncobj_replace_fence(syncobj, 0, fence);
> +		drm_syncobj_replace_fence(syncobj, fence);
>   
>   	*out_syncobj = syncobj;
>   	return 0;
> @@ -452,7 +450,7 @@ static int drm_syncobj_import_sync_file_fence(struct drm_file *file_private,
>   		return -ENOENT;
>   	}
>   
> -	drm_syncobj_replace_fence(syncobj, 0, fence);
> +	drm_syncobj_replace_fence(syncobj, fence);
>   	dma_fence_put(fence);
>   	drm_syncobj_put(syncobj);
>   	return 0;
> @@ -923,7 +921,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data,
>   		return ret;
>   
>   	for (i = 0; i < args->count_handles; i++)
> -		drm_syncobj_replace_fence(syncobjs[i], 0, NULL);
> +		drm_syncobj_replace_fence(syncobjs[i], NULL);
>   
>   	drm_syncobj_array_free(syncobjs, args->count_handles);
>   
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index 1aaccbe7e1de..786d719e652d 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -2186,7 +2186,7 @@ signal_fence_array(struct i915_execbuffer *eb,
>   		if (!(flags & I915_EXEC_FENCE_SIGNAL))
>   			continue;
>   
> -		drm_syncobj_replace_fence(syncobj, 0, fence);
> +		drm_syncobj_replace_fence(syncobj, fence);
>   	}
>   }
>   
> diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
> index b88c96911453..655be1a865fa 100644
> --- a/drivers/gpu/drm/v3d/v3d_gem.c
> +++ b/drivers/gpu/drm/v3d/v3d_gem.c
> @@ -588,8 +588,7 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
>   	/* Update the return sync object for the */
>   	sync_out = drm_syncobj_find(file_priv, args->out_sync);
>   	if (sync_out) {
> -		drm_syncobj_replace_fence(sync_out, 0,
> -					  exec->render_done_fence);
> +		drm_syncobj_replace_fence(sync_out, exec->render_done_fence);
>   		drm_syncobj_put(sync_out);
>   	}
>   
> diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
> index 41881ce4132d..aea2b8dfec17 100644
> --- a/drivers/gpu/drm/vc4/vc4_gem.c
> +++ b/drivers/gpu/drm/vc4/vc4_gem.c
> @@ -681,7 +681,7 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
>   	exec->fence = &fence->base;
>   
>   	if (out_sync)
> -		drm_syncobj_replace_fence(out_sync, 0, exec->fence);
> +		drm_syncobj_replace_fence(out_sync, exec->fence);
>   
>   	vc4_update_bo_seqnos(exec, seqno);
>   
> diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h
> index 2eda44def639..b1fe921f8e8f 100644
> --- a/include/drm/drm_syncobj.h
> +++ b/include/drm/drm_syncobj.h
> @@ -131,7 +131,7 @@ drm_syncobj_fence_get(struct drm_syncobj *syncobj)
>   
>   struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private,
>   				     u32 handle);
> -void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, u64 point,
> +void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
>   			       struct dma_fence *fence);
>   int drm_syncobj_find_fence(struct drm_file *file_private,
>   			   u32 handle, u64 point, u64 flags,

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

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

* Re: [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
  2018-12-04 11:59   ` [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup Christian König
@ 2018-12-04 12:29     ` Chunming Zhou
  2018-12-05 10:00     ` Christian König
  1 sibling, 0 replies; 21+ messages in thread
From: Chunming Zhou @ 2018-12-04 12:29 UTC (permalink / raw)
  To: Christian König, dri-devel@lists.freedesktop.org,
	amd-gfx@lists.freedesktop.org



在 2018/12/4 19:59, Christian König 写道:
> 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>

Reviewed-by: Chunming Zhou <david1.zhou@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);
>   
>   /**

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

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

* Re: [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2
  2018-12-04 11:59   ` [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2 Christian König
@ 2018-12-04 12:31     ` Chunming Zhou
  0 siblings, 0 replies; 21+ messages in thread
From: Chunming Zhou @ 2018-12-04 12:31 UTC (permalink / raw)
  To: Christian König, dri-devel@lists.freedesktop.org,
	amd-gfx@lists.freedesktop.org



在 2018/12/4 19:59, Christian König 写道:
> Use the dma_fence_chain object to create a timeline of fence objects
> instead of just replacing the existing fence.
>
> v2: rebase and cleanup
>
> Signed-off-by: Christian König <christian.koenig@amd.com>

Reviewed-by: Chunming Zhou <david1.zhou@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..64fcfea1c39f 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 = rcu_dereference_protected(syncobj->fence,
> +					 lockdep_is_held(&syncobj->lock));
> +	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);
> +}
> +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,

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

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

* Re: [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3
  2018-12-04 11:59   ` [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Christian König
@ 2018-12-04 12:47     ` Chunming Zhou
  0 siblings, 0 replies; 21+ messages in thread
From: Chunming Zhou @ 2018-12-04 12:47 UTC (permalink / raw)
  To: Christian König, dri-devel@lists.freedesktop.org,
	amd-gfx@lists.freedesktop.org



在 2018/12/4 19:59, Christian König 写道:
> 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 ee44cf2a8a12..fdbec8cedc3d 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)

This condition isn't need, which is already in 
drm_syncobj_remove_wait(), with that fix, Reviewed-by: Chunming Zhou 
<david1.zhou@amd.com>

> +		drm_syncobj_remove_wait(syncobj, &wait);
> +
>   	return ret;
>   }
>   EXPORT_SYMBOL(drm_syncobj_find_fence);

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

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

* Re: [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
       [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
                     ` (7 preceding siblings ...)
  2018-12-04 12:12   ` [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2 Chunming Zhou
@ 2018-12-04 12:52   ` Chris Wilson
  2018-12-04 12:57     ` Chris Wilson
  8 siblings, 1 reply; 21+ messages in thread
From: Chris Wilson @ 2018-12-04 12:52 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Quoting Christian König (2018-12-04 11:59:39)
> -static inline bool __dma_fence_is_later(u32 f1, u32 f2)
> +static inline bool __dma_fence_is_later(u64 f1, u64 f2)
>  {
> -       return (int)(f1 - f2) > 0;
> +       /* This is for backward compatibility with drivers which can only handle
> +        * 32bit sequence numbers. Use a 64bit compare when any of the higher
> +        * bits are none zero, otherwise use a 32bit compare with wrap around
> +        * handling.
> +        */
> +       if (upper_32_bits(f1) || upper_32_bits(f2))
> +               return f1 > f2;
> +
> +       return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0;

Or just "(int64_t)(f1 - f2) > 0", works if drivers are only using the low
32b and if they use the full 64b.
-Chris
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* Re: [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2
  2018-12-04 12:52   ` Chris Wilson
@ 2018-12-04 12:57     ` Chris Wilson
  0 siblings, 0 replies; 21+ messages in thread
From: Chris Wilson @ 2018-12-04 12:57 UTC (permalink / raw)
  To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Quoting Chris Wilson (2018-12-04 12:52:15)
> Quoting Christian König (2018-12-04 11:59:39)
> > -static inline bool __dma_fence_is_later(u32 f1, u32 f2)
> > +static inline bool __dma_fence_is_later(u64 f1, u64 f2)
> >  {
> > -       return (int)(f1 - f2) > 0;
> > +       /* This is for backward compatibility with drivers which can only handle
> > +        * 32bit sequence numbers. Use a 64bit compare when any of the higher
> > +        * bits are none zero, otherwise use a 32bit compare with wrap around
> > +        * handling.
> > +        */
> > +       if (upper_32_bits(f1) || upper_32_bits(f2))
> > +               return f1 > f2;
> > +
> > +       return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0;
> 
> Or just "(int64_t)(f1 - f2) > 0", works if drivers are only using the low
> 32b and if they use the full 64b.

No, it doesn't.
-Chris
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

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

* Re: [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
  2018-12-04 11:59   ` [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup Christian König
  2018-12-04 12:29     ` Chunming Zhou
@ 2018-12-05 10:00     ` Christian König
  2018-12-07 14:20       ` Daniel Vetter
  1 sibling, 1 reply; 21+ messages in thread
From: Christian König @ 2018-12-05 10:00 UTC (permalink / raw)
  To: dri-devel, amd-gfx, Daniel Vetter

Hi Daniel,

can I get a review for this one? It is essentially just a follow up 
cleanup on one of your patches and shouldn't have any functional effect.

Thanks,
Christian.

Am 04.12.18 um 12:59 schrieb Christian König:
> 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);
>   
>   /**

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

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

* Re: [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
  2018-12-05 10:00     ` Christian König
@ 2018-12-07 14:20       ` Daniel Vetter
  2018-12-07 14:23         ` Christian König
  0 siblings, 1 reply; 21+ messages in thread
From: Daniel Vetter @ 2018-12-07 14:20 UTC (permalink / raw)
  To: Christian König; +Cc: amd-gfx, dri-devel

On Wed, Dec 05, 2018 at 11:00:33AM +0100, Christian König wrote:
> Hi Daniel,
> 
> can I get a review for this one? It is essentially just a follow up cleanup
> on one of your patches and shouldn't have any functional effect.

Unfortunately badly backlogged an a handful of massive context switches
away from getting back to this. Also brain's all mushed up :-/

I think better to get Chris/Jason/Dave to take a look and ack.

Apologies :-(
-Daniel

> 
> Thanks,
> Christian.
> 
> Am 04.12.18 um 12:59 schrieb Christian König:
> > 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);
> >   /**
> 

-- 
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] 21+ messages in thread

* Re: [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup
  2018-12-07 14:20       ` Daniel Vetter
@ 2018-12-07 14:23         ` Christian König
  0 siblings, 0 replies; 21+ messages in thread
From: Christian König @ 2018-12-07 14:23 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: amd-gfx, dri-devel

Am 07.12.18 um 15:20 schrieb Daniel Vetter:
> On Wed, Dec 05, 2018 at 11:00:33AM +0100, Christian König wrote:
>> Hi Daniel,
>>
>> can I get a review for this one? It is essentially just a follow up cleanup
>> on one of your patches and shouldn't have any functional effect.
> Unfortunately badly backlogged an a handful of massive context switches
> away from getting back to this. Also brain's all mushed up :-/
>
> I think better to get Chris/Jason/Dave to take a look and ack.
>
> Apologies :-(

No problem, I'm totally overworked as well.

Christian.

> -Daniel
>
>> Thanks,
>> Christian.
>>
>> Am 04.12.18 um 12:59 schrieb Christian König:
>>> 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);
>>>    /**

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

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

end of thread, other threads:[~2018-12-07 14:23 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-04 11:59 [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2 Christian König
     [not found] ` <20181204115948.15202-1-christian.koenig-5C7GfCeVMHo@public.gmane.org>
2018-12-04 11:59   ` [PATCH 02/10] dma-buf: add new dma_fence_chain container v3 Christian König
2018-12-04 12:19     ` Chunming Zhou
2018-12-04 11:59   ` [PATCH 03/10] drm: revert "expand replace_fence to support timeline point v2" Christian König
2018-12-04 12:20     ` Chunming Zhou
2018-12-04 11:59   ` [PATCH 04/10] drm/syncobj: remove drm_syncobj_cb and cleanup Christian König
2018-12-04 12:29     ` Chunming Zhou
2018-12-05 10:00     ` Christian König
2018-12-07 14:20       ` Daniel Vetter
2018-12-07 14:23         ` Christian König
2018-12-04 11:59   ` [PATCH 05/10] drm/syncobj: add new drm_syncobj_add_point interface v2 Christian König
2018-12-04 12:31     ` Chunming Zhou
2018-12-04 11:59   ` [PATCH 07/10] drm/syncobj: add timeline payload query ioctl v4 Christian König
2018-12-04 11:59   ` [PATCH 08/10] drm/syncobj: use the timeline point in drm_syncobj_find_fence v3 Christian König
2018-12-04 12:47     ` Chunming Zhou
2018-12-04 11:59   ` [PATCH 10/10] drm/amdgpu: update version for timeline syncobj support in amdgpu Christian König
2018-12-04 12:12   ` [PATCH 01/10] dma-buf: make fence sequence numbers 64 bit v2 Chunming Zhou
2018-12-04 12:52   ` Chris Wilson
2018-12-04 12:57     ` Chris Wilson
2018-12-04 11:59 ` [PATCH 06/10] drm/syncobj: add support for timeline point wait v7 Christian König
2018-12-04 11:59 ` [PATCH 09/10] drm/amdgpu: add timeline support in amdgpu CS v2 Christian König

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox