All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline
@ 2017-04-12 12:48 Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson
                   ` (10 more replies)
  0 siblings, 11 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter

2 clflushes on two different objects are not ordered, and so do not
belong to the same timeline (context). Either we use a unique context
for each, or we reserve a special global context to mean unordered.
Ideally, we would reserve 0 to mean unordered (DMA_FENCE_NO_CONTEXT) to
have the same semantics everywhere.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         | 2 ++
 drivers/gpu/drm/i915/i915_gem.c         | 2 +-
 drivers/gpu/drm/i915/i915_gem_clflush.c | 8 +-------
 drivers/gpu/drm/i915/i915_gem_clflush.h | 1 -
 4 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1af4e6f5410c..9ff399fdf92b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1511,6 +1511,8 @@ struct i915_gem_mm {
 	/** LRU list of objects with fence regs on them. */
 	struct list_head fence_list;
 
+	u64 unordered_timeline;
+
 	/* the indicator for dispatch video commands on two BSD rings */
 	atomic_t bsd_engine_dispatch_index;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 33fb11cc5acc..68c0a1c3bf77 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4746,7 +4746,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
 
-	i915_gem_clflush_init(dev_priv);
+	dev_priv->mm.unordered_timeline = dma_fence_context_alloc(1);
 
 	if (!i915.enable_execlists) {
 		dev_priv->gt.resume = intel_legacy_submission_resume;
diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.c b/drivers/gpu/drm/i915/i915_gem_clflush.c
index ffd01e02fe94..ffac7a1f0caf 100644
--- a/drivers/gpu/drm/i915/i915_gem_clflush.c
+++ b/drivers/gpu/drm/i915/i915_gem_clflush.c
@@ -27,7 +27,6 @@
 #include "i915_gem_clflush.h"
 
 static DEFINE_SPINLOCK(clflush_lock);
-static u64 clflush_context;
 
 struct clflush {
 	struct dma_fence dma; /* Must be first for dma_fence_free() */
@@ -157,7 +156,7 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
 		dma_fence_init(&clflush->dma,
 			       &i915_clflush_ops,
 			       &clflush_lock,
-			       clflush_context,
+			       to_i915(obj->base.dev)->mm.unordered_timeline,
 			       0);
 		i915_sw_fence_init(&clflush->wait, i915_clflush_notify);
 
@@ -182,8 +181,3 @@ void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
 		GEM_BUG_ON(obj->base.write_domain != I915_GEM_DOMAIN_CPU);
 	}
 }
-
-void i915_gem_clflush_init(struct drm_i915_private *i915)
-{
-	clflush_context = dma_fence_context_alloc(1);
-}
diff --git a/drivers/gpu/drm/i915/i915_gem_clflush.h b/drivers/gpu/drm/i915/i915_gem_clflush.h
index b62d61a2d15f..2455a7820937 100644
--- a/drivers/gpu/drm/i915/i915_gem_clflush.h
+++ b/drivers/gpu/drm/i915/i915_gem_clflush.h
@@ -28,7 +28,6 @@
 struct drm_i915_private;
 struct drm_i915_gem_object;
 
-void i915_gem_clflush_init(struct drm_i915_private *i915);
 void i915_gem_clflush_object(struct drm_i915_gem_object *obj,
 			     unsigned int flags);
 #define I915_CLFLUSH_FORCE BIT(0)
-- 
2.11.0

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

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

* [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like Chris Wilson
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

Currently we filter out repeated use of the same timeline in the low
level i915_gem_request_await_request(), after having added the
dependency on the old request. However, we can lift this to
i915_gem_request_await_dma_fence() (before the dependency is added)
using the observation that requests along the same timeline are
explicitly ordered via i915_add_request (along with the dependencies).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 313cdff7c6dd..31874a38752e 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -663,6 +663,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 	int ret;
 
 	GEM_BUG_ON(to == from);
+	GEM_BUG_ON(to->timeline == from->timeline);
 
 	if (to->engine->schedule) {
 		ret = i915_priotree_add_dependency(to->i915,
@@ -672,9 +673,6 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 			return ret;
 	}
 
-	if (to->timeline == from->timeline)
-		return 0;
-
 	if (to->engine == from->engine) {
 		ret = i915_sw_fence_await_sw_fence_gfp(&to->submit,
 						       &from->submit,
@@ -723,6 +721,13 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return 0;
 
+	/* Requests on the same timeline are explicitly ordered, along with
+	 * their dependencies, by i915_add_request() which ensures that requests
+	 * are submitted in-order through each ring.
+	 */
+	if (fence->context == req->fence.context)
+		return 0;
+
 	if (dma_fence_is_i915(fence))
 		return i915_gem_request_await_request(req, to_request(fence));
 
-- 
2.11.0

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

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

* [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends Chris Wilson
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

ptr_unpack_bits() is a function-like macro, as such it is meant to be
replaceable by a function. In this case, we should be passing in the
out-param as a pointer.

Bizarrely this does affect code generation:

function                                     old     new   delta
i915_gem_object_pin_map                      409     389     -20

An improvement(?) in this case, but one can't help wonder what
strict-aliasing optimisations we are preventing.

The generated code looks identical in using ptr_unpack_bits (no extra
motions to stack, the pointer and bits appear to be kept in registers),
the difference appears to be code ordering and with a reorder it is able
to use smaller forward jumps.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c   | 2 +-
 drivers/gpu/drm/i915/i915_utils.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 68c0a1c3bf77..d993a3cc8f97 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2612,7 +2612,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	}
 	GEM_BUG_ON(!obj->mm.pages);
 
-	ptr = ptr_unpack_bits(obj->mm.mapping, has_type);
+	ptr = ptr_unpack_bits(obj->mm.mapping, &has_type);
 	if (ptr && has_type != type) {
 		if (pinned) {
 			ret = -EBUSY;
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index c5455d36b617..aca11aad5da7 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -77,7 +77,7 @@
 
 #define ptr_unpack_bits(ptr, bits) ({					\
 	unsigned long __v = (unsigned long)(ptr);			\
-	(bits) = __v & ~PAGE_MASK;					\
+	*(bits) = __v & ~PAGE_MASK;					\
 	(typeof(ptr))(__v & PAGE_MASK);					\
 })
 
-- 
2.11.0

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

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

* [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

Rebrand the current (pointer | bits) pack/unpack utility macros as
explicit bit twiddling for PAGE_SIZE so that we can use the more
flexible underlying macros for different bits.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_cmd_parser.c |  2 +-
 drivers/gpu/drm/i915/i915_gem.c        |  6 +++---
 drivers/gpu/drm/i915/i915_utils.h      | 19 +++++++++++++------
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 2a1a3347495a..f0cb22cc0dd6 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -1284,7 +1284,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
 
 		if (*cmd == MI_BATCH_BUFFER_END) {
 			if (needs_clflush_after) {
-				void *ptr = ptr_mask_bits(shadow_batch_obj->mm.mapping);
+				void *ptr = page_mask_bits(shadow_batch_obj->mm.mapping);
 				drm_clflush_virt_range(ptr,
 						       (void *)(cmd + 1) - ptr);
 			}
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d993a3cc8f97..e5f943ca5216 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2280,7 +2280,7 @@ void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
 	if (obj->mm.mapping) {
 		void *ptr;
 
-		ptr = ptr_mask_bits(obj->mm.mapping);
+		ptr = page_mask_bits(obj->mm.mapping);
 		if (is_vmalloc_addr(ptr))
 			vunmap(ptr);
 		else
@@ -2612,7 +2612,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 	}
 	GEM_BUG_ON(!obj->mm.pages);
 
-	ptr = ptr_unpack_bits(obj->mm.mapping, &has_type);
+	ptr = page_unpack_bits(obj->mm.mapping, &has_type);
 	if (ptr && has_type != type) {
 		if (pinned) {
 			ret = -EBUSY;
@@ -2634,7 +2634,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
 			goto err_unpin;
 		}
 
-		obj->mm.mapping = ptr_pack_bits(ptr, type);
+		obj->mm.mapping = page_pack_bits(ptr, type);
 	}
 
 out_unlock:
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index aca11aad5da7..f0500c65726d 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -70,20 +70,27 @@
 #define overflows_type(x, T) \
 	(sizeof(x) > sizeof(T) && (x) >> (sizeof(T) * BITS_PER_BYTE))
 
-#define ptr_mask_bits(ptr) ({						\
+#define ptr_mask_bits(ptr, n) ({					\
 	unsigned long __v = (unsigned long)(ptr);			\
-	(typeof(ptr))(__v & PAGE_MASK);					\
+	(typeof(ptr))(__v & -BIT(n));					\
 })
 
-#define ptr_unpack_bits(ptr, bits) ({					\
+#define ptr_unmask_bits(ptr, n) ((unsigned long)(ptr) & (BIT(n) - 1))
+
+#define ptr_unpack_bits(ptr, bits, n) ({				\
 	unsigned long __v = (unsigned long)(ptr);			\
-	*(bits) = __v & ~PAGE_MASK;					\
-	(typeof(ptr))(__v & PAGE_MASK);					\
+	*(bits) = __v & (BIT(n) - 1);					\
+	(typeof(ptr))(__v & -BIT(n));					\
 })
 
-#define ptr_pack_bits(ptr, bits)					\
+#define ptr_pack_bits(ptr, bits, n)					\
 	((typeof(ptr))((unsigned long)(ptr) | (bits)))
 
+#define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT)
+#define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT)
+#define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT)
+#define page_unpack_bits(ptr, bits) ptr_unpack_bits(ptr, bits, PAGE_SHIFT)
+
 #define ptr_offset(ptr, member) offsetof(typeof(*(ptr)), member)
 
 #define fetch_and_zero(ptr) ({						\
-- 
2.11.0

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

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

* [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (2 preceding siblings ...)
  2017-04-12 12:48 ` [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 14:24   ` [PATCH v3] " Chris Wilson
  2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

Track the latest fence waited upon on each context, and only add a new
asynchronous wait if the new fence is more recent than the recorded
fence for that context. This requires us to filter out unordered
timelines, which are noted by DMA_FENCE_NO_CONTEXT. However, in the
absence of a universal identifier, we have to use our own
i915->mm.unordered_timeline token.

v2: Throw around the debug crutches
v3: Inline the likely case of the pre-allocation cache being full.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c            |  72 ++++---
 drivers/gpu/drm/i915/i915_gem_timeline.c           | 217 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_timeline.h           |  34 ++++
 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 127 ++++++++++++
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 5 files changed, 424 insertions(+), 27 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 31874a38752e..6e68387aa097 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -714,9 +714,7 @@ int
 i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 				 struct dma_fence *fence)
 {
-	struct dma_fence_array *array;
 	int ret;
-	int i;
 
 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return 0;
@@ -728,39 +726,59 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 	if (fence->context == req->fence.context)
 		return 0;
 
-	if (dma_fence_is_i915(fence))
-		return i915_gem_request_await_request(req, to_request(fence));
+	/* Squash repeated waits to the same timelines, picking the latest */
+	if (fence->context != req->i915->mm.unordered_timeline) {
+		if (intel_timeline_sync_get(req->timeline,
+					    fence->context,
+					    fence->seqno))
+			return 0;
 
-	if (!dma_fence_is_array(fence)) {
+		ret = intel_timeline_sync_reserve(req->timeline);
+		if (unlikely(ret))
+			return ret;
+	}
+
+	if (dma_fence_is_i915(fence)) {
+		ret = i915_gem_request_await_request(req, to_request(fence));
+		if (ret < 0)
+			return ret;
+	} else if (!dma_fence_is_array(fence)) {
 		ret = i915_sw_fence_await_dma_fence(&req->submit,
 						    fence, I915_FENCE_TIMEOUT,
 						    GFP_KERNEL);
-		return ret < 0 ? ret : 0;
-	}
-
-	/* Note that if the fence-array was created in signal-on-any mode,
-	 * we should *not* decompose it into its individual fences. However,
-	 * we don't currently store which mode the fence-array is operating
-	 * in. Fortunately, the only user of signal-on-any is private to
-	 * amdgpu and we should not see any incoming fence-array from
-	 * sync-file being in signal-on-any mode.
-	 */
-
-	array = to_dma_fence_array(fence);
-	for (i = 0; i < array->num_fences; i++) {
-		struct dma_fence *child = array->fences[i];
-
-		if (dma_fence_is_i915(child))
-			ret = i915_gem_request_await_request(req,
-							     to_request(child));
-		else
-			ret = i915_sw_fence_await_dma_fence(&req->submit,
-							    child, I915_FENCE_TIMEOUT,
-							    GFP_KERNEL);
 		if (ret < 0)
 			return ret;
+	} else {
+		struct dma_fence_array *array = to_dma_fence_array(fence);
+		int i;
+
+		/* Note that if the fence-array was created in signal-on-any mode,
+		 * we should *not* decompose it into its individual fences. However,
+		 * we don't currently store which mode the fence-array is operating
+		 * in. Fortunately, the only user of signal-on-any is private to
+		 * amdgpu and we should not see any incoming fence-array from
+		 * sync-file being in signal-on-any mode.
+		 */
+
+		for (i = 0; i < array->num_fences; i++) {
+			struct dma_fence *child = array->fences[i];
+
+			if (dma_fence_is_i915(child))
+				ret = i915_gem_request_await_request(req,
+								     to_request(child));
+			else
+				ret = i915_sw_fence_await_dma_fence(&req->submit,
+								    child, I915_FENCE_TIMEOUT,
+								    GFP_KERNEL);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
+	if (fence->context != req->i915->mm.unordered_timeline)
+		intel_timeline_sync_set(req->timeline,
+					fence->context, fence->seqno);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index b596ca7ee058..c25edfde4833 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -24,6 +24,217 @@
 
 #include "i915_drv.h"
 
+#define SHIFT ilog2(NSEQMAP)
+#define MASK (NSEQMAP - 1)
+
+static void seqmap_free_layers(struct seqmap_layer *p)
+{
+	unsigned int i;
+
+	if (p->height) {
+		for (; (i = ffs(p->bitmap)); p->bitmap &= ~0u << i)
+			seqmap_free_layers(p->slot[i - 1]);
+	}
+
+	kfree(p);
+}
+
+static void seqmap_free(struct seqmap *seqmap)
+{
+	if (seqmap->top)
+		seqmap_free_layers(seqmap->top);
+
+	while (seqmap->freed) {
+		struct seqmap_layer *p;
+
+		p = ptr_mask_bits(seqmap->freed, SEQMAP_COUNT_BITS);
+		seqmap->freed = p->parent;
+		kfree(p);
+	}
+}
+
+__malloc static struct seqmap_layer *
+seqmap_alloc_layer(struct seqmap *shared)
+{
+	struct seqmap_layer *p;
+
+	GEM_BUG_ON(!shared->freed);
+
+	p = ptr_mask_bits(shared->freed, SEQMAP_COUNT_BITS);
+	shared->freed = p->parent;
+
+	return p;
+}
+
+static int layer_idx(const struct seqmap_layer *p, u64 id)
+{
+	return (id >> p->height) & MASK;
+}
+
+bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno)
+{
+	struct seqmap *shared = &tl->sync;
+	struct seqmap_layer *p;
+	unsigned int idx;
+
+	p = shared->hint;
+	if (!p)
+		return false;
+
+	if ((id >> SHIFT) == p->prefix)
+		goto found;
+
+	p = shared->top;
+	do {
+		if ((id >> p->height >> SHIFT) != p->prefix)
+			return false;
+
+		if (!p->height)
+			break;
+
+		p = p->slot[layer_idx(p, id)];
+		if (!p)
+			return false;
+	} while (1);
+
+	shared->hint = p;
+found:
+	idx = id & MASK;
+	if (!(p->bitmap & BIT(idx)))
+		return false;
+
+	return i915_seqno_passed((uintptr_t)p->slot[idx], seqno);
+}
+
+void intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno)
+{
+	struct seqmap *shared = &tl->sync;
+	struct seqmap_layer *p, *cur;
+	unsigned int idx;
+
+	/* We expect to be called in sequence following a  _get(id), which
+	 * should have preloaded the ->hint for us.
+	 */
+	p = shared->hint;
+	if (likely(p && (id >> SHIFT) == p->prefix))
+		goto found_layer;
+
+	if (!p) {
+		GEM_BUG_ON(shared->top);
+		cur = seqmap_alloc_layer(shared);
+		cur->parent = NULL;
+		shared->top = cur;
+		goto new_layer;
+	}
+
+	/* No shortcut, we have to descend the tree to find the right layer
+	 * containing this fence.
+	 *
+	 * Each layer in the tree holds 16 (NSEQMAP) pointers, either fences
+	 * or lower layers. Leaf nodes (height = 0) contain the fences, all
+	 * other nodes (height > 0) are internal layers that point to a lower
+	 * node. Each internal layer has at least 2 descendents.
+	 *
+	 * Starting at the top, we check whether the current prefix matches. If
+	 * it doesn't, we have gone passed our layer and need to insert a join
+	 * into the tree, and a new leaf node as a descendent as well as the
+	 * original layer.
+	 *
+	 * The matching prefix means we are still following the right branch
+	 * of the tree. If it has height 0, we have found our leaf and just
+	 * need to replace the fence slot with ourselves. If the height is
+	 * not zero, our slot contains the next layer in the tree (unless
+	 * it is empty, in which case we can add ourselves as a new leaf).
+	 * As descend the tree the prefix grows (and height decreases).
+	 */
+	p = shared->top;
+	do {
+		if ((id >> p->height >> SHIFT) != p->prefix) {
+			/* insert a join above the current layer */
+			cur = seqmap_alloc_layer(shared);
+			cur->height = ALIGN(fls64((id >> p->height >> SHIFT) ^ p->prefix),
+					    SHIFT) + p->height;
+			cur->prefix = id >> cur->height >> SHIFT;
+
+			if (p->parent)
+				p->parent->slot[layer_idx(p->parent, id)] = cur;
+			else
+				shared->top = cur;
+			cur->parent = p->parent;
+
+			idx = p->prefix >> (cur->height - p->height - SHIFT) & MASK;
+			cur->slot[idx] = p;
+			cur->bitmap |= BIT(idx);
+			p->parent = cur;
+		} else if (!p->height) {
+			/* matching base layer */
+			shared->hint = p;
+			goto found_layer;
+		} else {
+			/* descend into the next layer */
+			idx = layer_idx(p, id);
+			cur = p->slot[idx];
+			if (unlikely(!cur)) {
+				cur = seqmap_alloc_layer(shared);
+				p->slot[idx] = cur;
+				p->bitmap |= BIT(idx);
+				cur->parent = p;
+				goto new_layer;
+			}
+		}
+
+		p = cur;
+	} while (1);
+
+found_layer:
+	GEM_BUG_ON(p->height);
+	GEM_BUG_ON(p->prefix != id >> SHIFT);
+	idx = id & MASK;
+	p->slot[idx] = (void *)(uintptr_t)seqno;
+	p->bitmap |= BIT(idx);
+	GEM_BUG_ON(shared->hint != p);
+	return;
+
+new_layer:
+	GEM_BUG_ON(cur->height);
+	cur->prefix = id >> SHIFT;
+	idx = id & MASK;
+	cur->slot[idx] = (void *)(uintptr_t)seqno;
+	cur->bitmap = BIT(idx);
+	shared->hint = cur;
+	return;
+}
+
+int __intel_timeline_sync_reserve(struct intel_timeline *tl)
+{
+	struct seqmap *shared = &tl->sync;
+	int count;
+
+	might_sleep();
+
+	/* To guarantee being able to replace a fence in the radixtree,
+	 * we need at most 2 layers: one to create a join in the tree,
+	 * and one to contain the fence. Typically we expect to reuse
+	 * a layer and so avoid any insertions.
+	 *
+	 * We use the low bits of the freed list to track its length
+	 * since we only need a couple of bits.
+	 */
+	count = ptr_unmask_bits(shared->freed, SEQMAP_COUNT_BITS);
+	while (count++ < 2) {
+		struct seqmap_layer *p;
+
+		p = kzalloc(sizeof(*p), GFP_KERNEL);
+		if (unlikely(!p))
+			return -ENOMEM;
+
+		p->parent = shared->freed;
+		shared->freed = ptr_pack_bits(p, count, SEQMAP_COUNT_BITS);
+	}
+
+	return 0;
+}
+
 static int __i915_gem_timeline_init(struct drm_i915_private *i915,
 				    struct i915_gem_timeline *timeline,
 				    const char *name,
@@ -91,8 +302,14 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
 		struct intel_timeline *tl = &timeline->engine[i];
 
 		GEM_BUG_ON(!list_empty(&tl->requests));
+
+		seqmap_free(&tl->sync);
 	}
 
 	list_del(&timeline->link);
 	kfree(timeline->name);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/i915_gem_timeline.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 6c53e14cab2a..4cb597401803 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -26,11 +26,30 @@
 #define I915_GEM_TIMELINE_H
 
 #include <linux/list.h>
+#include <linux/radix-tree.h>
 
+#include "i915_utils.h"
 #include "i915_gem_request.h"
 
 struct i915_gem_timeline;
 
+#define NSEQMAP 16
+
+struct seqmap_layer {
+	u64 prefix;
+	unsigned int height;
+	unsigned int bitmap;
+	struct seqmap_layer *parent;
+	void *slot[NSEQMAP];
+};
+
+struct seqmap {
+	struct seqmap_layer *hint;
+	struct seqmap_layer *top;
+	struct seqmap_layer *freed;
+#define SEQMAP_COUNT_BITS 2
+};
+
 struct intel_timeline {
 	u64 fence_context;
 	u32 seqno;
@@ -55,6 +74,8 @@ struct intel_timeline {
 	 * struct_mutex.
 	 */
 	struct i915_gem_active last_request;
+
+	struct seqmap sync;
 	u32 sync_seqno[I915_NUM_ENGINES];
 
 	struct i915_gem_timeline *common;
@@ -75,4 +96,17 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
 int i915_gem_timeline_init__global(struct drm_i915_private *i915);
 void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
 
+bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno);
+
+int __intel_timeline_sync_reserve(struct intel_timeline *tl);
+static inline int intel_timeline_sync_reserve(struct intel_timeline *tl)
+{
+	if (likely(ptr_unmask_bits(tl->sync.freed, SEQMAP_COUNT_BITS) == 2))
+		return 0;
+
+	return __intel_timeline_sync_reserve(tl);
+}
+
+void intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno);
+
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
new file mode 100644
index 000000000000..15e2b2e63081
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+#include "mock_gem_device.h"
+
+static int igt_seqmap(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	const struct {
+		const char *name;
+		u32 seqno;
+		bool expected;
+		bool set;
+	} pass[] = {
+		{ "unset", 0, false, false },
+		{ "new", 0, false, true },
+		{ "0a", 0, true, true },
+		{ "1a", 1, false, true },
+		{ "1b", 1, true, true },
+		{ "0b", 0, true, false },
+		{ "2a", 2, false, true },
+		{ "4", 4, false, true },
+		{ "INT_MAX", INT_MAX, false, true },
+		{ "INT_MAX-1", INT_MAX-1, true, false },
+		{ "INT_MAX+1", (u32)INT_MAX+1, false, true },
+		{ "INT_MAX", INT_MAX, true, false },
+		{ "UINT_MAX", UINT_MAX, false, true },
+		{ "wrap", 0, false, true },
+		{ "unwrap", UINT_MAX, true, false },
+		{},
+	}, *p;
+	struct intel_timeline *tl;
+	int order, offset;
+	int ret;
+
+	tl = &i915->gt.global_timeline.engine[RCS];
+	for (p = pass; p->name; p++) {
+		for (order = 1; order < 64; order++) {
+			for (offset = -1; offset <= (order > 1); offset++) {
+				u64 ctx = BIT_ULL(order) + offset;
+
+				if (intel_timeline_sync_get(tl,
+							    ctx,
+							    p->seqno) != p->expected) {
+					pr_err("1: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
+					       p->name, ctx, p->seqno, yesno(p->expected));
+					return -EINVAL;
+				}
+
+				if (p->set) {
+					ret = intel_timeline_sync_reserve(tl);
+					if (ret)
+						return ret;
+
+					intel_timeline_sync_set(tl, ctx, p->seqno);
+				}
+			}
+		}
+	}
+
+	tl = &i915->gt.global_timeline.engine[BCS];
+	for (order = 1; order < 64; order++) {
+		for (offset = -1; offset <= (order > 1); offset++) {
+			u64 ctx = BIT_ULL(order) + offset;
+
+			for (p = pass; p->name; p++) {
+				if (intel_timeline_sync_get(tl,
+							    ctx,
+							    p->seqno) != p->expected) {
+					pr_err("2: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
+					       p->name, ctx, p->seqno, yesno(p->expected));
+					return -EINVAL;
+				}
+
+				if (p->set) {
+					ret = intel_timeline_sync_reserve(tl);
+					if (ret)
+						return ret;
+
+					intel_timeline_sync_set(tl, ctx, p->seqno);
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+int i915_gem_timeline_mock_selftests(void)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_seqmap),
+	};
+	struct drm_i915_private *i915;
+	int err;
+
+	i915 = mock_gem_device();
+	if (!i915)
+		return -ENOMEM;
+
+	err = i915_subtests(tests, i915);
+	drm_dev_unref(&i915->drm);
+
+	return err;
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index be9a9ebf5692..8d0f50c25df8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -12,6 +12,7 @@ selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
 selftest(scatterlist, scatterlist_mock_selftests)
 selftest(uncore, intel_uncore_mock_selftests)
 selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
+selftest(timelines, i915_gem_timeline_mock_selftests)
 selftest(requests, i915_gem_request_mock_selftests)
 selftest(objects, i915_gem_object_mock_selftests)
 selftest(dmabuf, i915_gem_dmabuf_mock_selftests)
-- 
2.11.0

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

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

* [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[]
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (3 preceding siblings ...)
  2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-13 10:49   ` Joonas Lahtinen
  2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

With the addition of the inter-context intel_time.sync map, having a
very similar sync_seqno[] is confusing. Aide the reader by denoting that
this a pre-allocated array for storing semaphore sync points wrt to the
global seqno.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_request.c  | 8 ++++----
 drivers/gpu/drm/i915/i915_gem_timeline.h | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 6e68387aa097..87ca3453140a 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -218,8 +218,8 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 		tl->seqno = seqno;
 
 		list_for_each_entry(timeline, &i915->gt.timelines, link)
-			memset(timeline->engine[id].sync_seqno, 0,
-			       sizeof(timeline->engine[id].sync_seqno));
+			memset(timeline->engine[id].global_sync, 0,
+			       sizeof(timeline->engine[id].global_sync));
 	}
 
 	return 0;
@@ -688,7 +688,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 		return ret < 0 ? ret : 0;
 	}
 
-	if (seqno <= to->timeline->sync_seqno[from->engine->id])
+	if (seqno <= to->timeline->global_sync[from->engine->id])
 		return 0;
 
 	trace_i915_gem_ring_sync_to(to, from);
@@ -706,7 +706,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 			return ret;
 	}
 
-	to->timeline->sync_seqno[from->engine->id] = seqno;
+	to->timeline->global_sync[from->engine->id] = seqno;
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 4cb597401803..48437612bb4b 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -76,7 +76,7 @@ struct intel_timeline {
 	struct i915_gem_active last_request;
 
 	struct seqmap sync;
-	u32 sync_seqno[I915_NUM_ENGINES];
+	u32 global_sync[I915_NUM_ENGINES];
 
 	struct i915_gem_timeline *common;
 };
-- 
2.11.0

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

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

* [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (4 preceding siblings ...)
  2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 16:31   ` Michał Winiarski
  2017-04-13 10:46   ` Joonas Lahtinen
  2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

Although we do check the completion-status of the request before
actually adding a wait on it (either to its submit fence or its
completion dma-fence), we currently do not check before adding it to the
dependency lists.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_request.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 87ca3453140a..436693b12bae 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -665,6 +665,9 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 	GEM_BUG_ON(to == from);
 	GEM_BUG_ON(to->timeline == from->timeline);
 
+	if (i915_gem_request_completed(from))
+		return 0;
+
 	if (to->engine->schedule) {
 		ret = i915_priotree_add_dependency(to->i915,
 						   &to->priotree,
-- 
2.11.0

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

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

* [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (5 preceding siblings ...)
  2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 16:54   ` Michał Winiarski
  2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

As we may unwind the requests, even though the request we are awaiting
has a global_seqno that seqno may be revoked during the await and so we
can not reliably use it as a barrier for all future awaits on the same
timeline.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michał Winiarski <michal.winiarski@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c | 34 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 436693b12bae..17feeb68cdff 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -684,33 +684,31 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 	}
 
 	seqno = i915_gem_request_global_seqno(from);
-	if (!seqno) {
-		ret = i915_sw_fence_await_dma_fence(&to->submit,
-						    &from->fence, 0,
-						    GFP_KERNEL);
-		return ret < 0 ? ret : 0;
-	}
+	if (!seqno)
+		goto await_dma_fence;
 
-	if (seqno <= to->timeline->global_sync[from->engine->id])
-		return 0;
-
-	trace_i915_gem_ring_sync_to(to, from);
 	if (!i915.semaphores) {
-		if (!i915_spin_request(from, TASK_INTERRUPTIBLE, 2)) {
-			ret = i915_sw_fence_await_dma_fence(&to->submit,
-							    &from->fence, 0,
-							    GFP_KERNEL);
-			if (ret < 0)
-				return ret;
-		}
+		if (!__i915_spin_request(from, seqno, TASK_INTERRUPTIBLE, 2))
+			goto await_dma_fence;
 	} else {
+		if (seqno <= to->timeline->global_sync[from->engine->id])
+			return 0;
+
+		trace_i915_gem_ring_sync_to(to, from);
 		ret = to->engine->semaphore.sync_to(to, from);
 		if (ret)
 			return ret;
+
+		to->timeline->global_sync[from->engine->id] = seqno;
 	}
 
-	to->timeline->global_sync[from->engine->id] = seqno;
 	return 0;
+
+await_dma_fence:
+	ret = i915_sw_fence_await_dma_fence(&to->submit,
+					    &from->fence, 0,
+					    GFP_KERNEL);
+	return ret < 0 ? ret : 0;
 }
 
 int
-- 
2.11.0

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

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

* [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (6 preceding siblings ...)
  2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson
@ 2017-04-12 12:48 ` Chris Wilson
  2017-04-12 14:41   ` Joonas Lahtinen
  2017-04-12 13:20 ` ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Patchwork
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 12:48 UTC (permalink / raw)
  To: intel-gfx

Rather than use a global modparam, we can just check to see if the
engine has semaphores configured upon it.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_request.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 17feeb68cdff..38307079bd35 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -687,10 +687,12 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 	if (!seqno)
 		goto await_dma_fence;
 
-	if (!i915.semaphores) {
+	if (!to->engine->semaphore.sync_to) {
 		if (!__i915_spin_request(from, seqno, TASK_INTERRUPTIBLE, 2))
 			goto await_dma_fence;
 	} else {
+		GEM_BUG_ON(!from->engine->semaphore.signal);
+
 		if (seqno <= to->timeline->global_sync[from->engine->id])
 			return 0;
 
-- 
2.11.0

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

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

* ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (7 preceding siblings ...)
  2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson
@ 2017-04-12 13:20 ` Patchwork
  2017-04-12 15:01 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) Patchwork
  2017-04-12 17:00 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) Patchwork
  10 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2017-04-12 13:20 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline
URL   : https://patchwork.freedesktop.org/series/22924/
State : success

== Summary ==

Series 22924v1 Series without cover letter
https://patchwork.freedesktop.org/api/1.0/series/22924/revisions/1/mbox/

Test gem_exec_fence:
        Subgroup await-hang-default:
                incomplete -> PASS       (fi-hsw-4770) fdo#99726
Test gem_exec_flush:
        Subgroup basic-batch-kernel-default-uc:
                fail       -> PASS       (fi-snb-2600) fdo#100007

fdo#99726 https://bugs.freedesktop.org/show_bug.cgi?id=99726
fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007

fi-bdw-5557u     total:278  pass:267  dwarn:0   dfail:0   fail:0   skip:11  time:431s
fi-bdw-gvtdvm    total:278  pass:256  dwarn:8   dfail:0   fail:0   skip:14  time:425s
fi-bsw-n3050     total:278  pass:242  dwarn:0   dfail:0   fail:0   skip:36  time:575s
fi-bxt-j4205     total:278  pass:259  dwarn:0   dfail:0   fail:0   skip:19  time:507s
fi-byt-j1900     total:278  pass:254  dwarn:0   dfail:0   fail:0   skip:24  time:487s
fi-byt-n2820     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:487s
fi-hsw-4770      total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:603s
fi-hsw-4770r     total:278  pass:262  dwarn:0   dfail:0   fail:0   skip:16  time:403s
fi-ilk-650       total:278  pass:228  dwarn:0   dfail:0   fail:0   skip:50  time:424s
fi-ivb-3520m     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:490s
fi-ivb-3770      total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:463s
fi-kbl-7500u     total:278  pass:260  dwarn:0   dfail:0   fail:0   skip:18  time:455s
fi-kbl-7560u     total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:567s
fi-skl-6260u     total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:453s
fi-skl-6700hq    total:278  pass:261  dwarn:0   dfail:0   fail:0   skip:17  time:570s
fi-skl-6700k     total:278  pass:256  dwarn:4   dfail:0   fail:0   skip:18  time:457s
fi-skl-6770hq    total:278  pass:268  dwarn:0   dfail:0   fail:0   skip:10  time:496s
fi-skl-gvtdvm    total:278  pass:265  dwarn:0   dfail:0   fail:0   skip:13  time:434s
fi-snb-2520m     total:278  pass:250  dwarn:0   dfail:0   fail:0   skip:28  time:527s
fi-snb-2600      total:278  pass:249  dwarn:0   dfail:0   fail:0   skip:29  time:410s

53b9521a6f113b5fcfd8c6a1f2ba3194e2d21381 drm-tip: 2017y-04m-12d-12h-39m-39s UTC integration manifest
d00ced5 drm/i915: Switch the global i915.semaphores check to a local predicate
ee45627 drm/i915: Do not record a successful syncpoint for a dma-await
a3ec281 drm/i915: Confirm the request is still active before adding it to the await
4132e6e drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[]
77635c1 drm/i915: Squash repeated awaits on the same fence
037170d drm/i915: Redefine ptr_pack_bits() and friends
a06b39f drm/i915: Make ptr_unpack_bits() more function-like
0ed32ff drm/i915: Lift timeline ordering to await_dma_fence
0547c98 drm/i915: Mark up clflushes as belonging to an unordered timeline

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_4492/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v3] drm/i915: Squash repeated awaits on the same fence
  2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson
@ 2017-04-12 14:24   ` Chris Wilson
  2017-04-12 15:39     ` [PATCH v4] " Chris Wilson
  0 siblings, 1 reply; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 14:24 UTC (permalink / raw)
  To: intel-gfx

Track the latest fence waited upon on each context, and only add a new
asynchronous wait if the new fence is more recent than the recorded
fence for that context. This requires us to filter out unordered
timelines, which are noted by DMA_FENCE_NO_CONTEXT. However, in the
absence of a universal identifier, we have to use our own
i915->mm.unordered_timeline token.

v2: Throw around the debug crutches
v3: Inline the likely case of the pre-allocation cache being full.
v4: Drop the pre-allocation support, we can lose the most recent fence
in case of allocation failure -- it just means we may emit more awaits
than strictly necessary but will not break.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c            |  66 ++++---
 drivers/gpu/drm/i915/i915_gem_timeline.c           | 194 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_timeline.h           |  18 ++
 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 123 +++++++++++++
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 5 files changed, 375 insertions(+), 27 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 31874a38752e..f679c16aa5c6 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -714,9 +714,7 @@ int
 i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 				 struct dma_fence *fence)
 {
-	struct dma_fence_array *array;
 	int ret;
-	int i;
 
 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return 0;
@@ -728,39 +726,53 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 	if (fence->context == req->fence.context)
 		return 0;
 
-	if (dma_fence_is_i915(fence))
-		return i915_gem_request_await_request(req, to_request(fence));
+	/* Squash repeated waits to the same timelines, picking the latest */
+	if (fence->context != req->i915->mm.unordered_timeline &&
+	    intel_timeline_sync_get(req->timeline,
+				    fence->context, fence->seqno))
+		return 0;
 
-	if (!dma_fence_is_array(fence)) {
+	if (dma_fence_is_i915(fence)) {
+		ret = i915_gem_request_await_request(req, to_request(fence));
+		if (ret < 0)
+			return ret;
+	} else if (!dma_fence_is_array(fence)) {
 		ret = i915_sw_fence_await_dma_fence(&req->submit,
 						    fence, I915_FENCE_TIMEOUT,
 						    GFP_KERNEL);
-		return ret < 0 ? ret : 0;
-	}
-
-	/* Note that if the fence-array was created in signal-on-any mode,
-	 * we should *not* decompose it into its individual fences. However,
-	 * we don't currently store which mode the fence-array is operating
-	 * in. Fortunately, the only user of signal-on-any is private to
-	 * amdgpu and we should not see any incoming fence-array from
-	 * sync-file being in signal-on-any mode.
-	 */
-
-	array = to_dma_fence_array(fence);
-	for (i = 0; i < array->num_fences; i++) {
-		struct dma_fence *child = array->fences[i];
-
-		if (dma_fence_is_i915(child))
-			ret = i915_gem_request_await_request(req,
-							     to_request(child));
-		else
-			ret = i915_sw_fence_await_dma_fence(&req->submit,
-							    child, I915_FENCE_TIMEOUT,
-							    GFP_KERNEL);
 		if (ret < 0)
 			return ret;
+	} else {
+		struct dma_fence_array *array = to_dma_fence_array(fence);
+		int i;
+
+		/* Note that if the fence-array was created in signal-on-any mode,
+		 * we should *not* decompose it into its individual fences. However,
+		 * we don't currently store which mode the fence-array is operating
+		 * in. Fortunately, the only user of signal-on-any is private to
+		 * amdgpu and we should not see any incoming fence-array from
+		 * sync-file being in signal-on-any mode.
+		 */
+
+		for (i = 0; i < array->num_fences; i++) {
+			struct dma_fence *child = array->fences[i];
+
+			if (dma_fence_is_i915(child))
+				ret = i915_gem_request_await_request(req,
+								     to_request(child));
+			else
+				ret = i915_sw_fence_await_dma_fence(&req->submit,
+								    child, I915_FENCE_TIMEOUT,
+								    GFP_KERNEL);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
+	if (fence->context != req->i915->mm.unordered_timeline)
+		intel_timeline_sync_set(req->timeline,
+					fence->context, fence->seqno);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index b596ca7ee058..446eefa70e6d 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -24,6 +24,194 @@
 
 #include "i915_drv.h"
 
+#define SHIFT ilog2(NSEQMAP)
+#define MASK (NSEQMAP - 1)
+
+static void __seqmap_free(struct seqmap *p)
+{
+	unsigned int i;
+
+	if (p->height) {
+		for (; (i = ffs(p->bitmap)); p->bitmap &= ~0u << i)
+			__seqmap_free(p->slot[i - 1]);
+	}
+
+	kfree(p);
+}
+
+static void seqmap_free(struct seqmap *seqmap)
+{
+	if (!seqmap)
+		return;
+
+	while (seqmap->parent)
+		seqmap = seqmap->parent;
+
+	__seqmap_free(seqmap);
+}
+
+static int layer_idx(const struct seqmap *p, u64 id)
+{
+	return (id >> p->height) & MASK;
+}
+
+bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno)
+{
+	struct seqmap *p;
+	unsigned int idx;
+
+	p = tl->sync;
+	if (!p)
+		return false;
+
+	if ((id >> SHIFT) == p->prefix)
+		goto found;
+
+	/* First climb the tree back to a parent branch */
+	do {
+		p = p->parent;
+		if (!p)
+			return false;
+
+		if ((id >> p->height >> SHIFT) == p->prefix)
+			break;
+	} while (1);
+
+	/* And then descend again until we find our leaf */
+	do {
+		if (!p->height)
+			break;
+
+		p = p->slot[layer_idx(p, id)];
+		if (!p)
+			return false;
+
+		if ((id >> p->height >> SHIFT) != p->prefix)
+			return false;
+	} while (1);
+
+	tl->sync = p;
+found:
+	idx = id & MASK;
+	if (!(p->bitmap & BIT(idx)))
+		return false;
+
+	return i915_seqno_passed((uintptr_t)p->slot[idx], seqno);
+}
+
+int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno)
+{
+	struct seqmap *p;
+	unsigned int idx;
+
+	/* We expect to be called in sequence following a  _get(id), which
+	 * should have preloaded the tl->sync hint for us.
+	 */
+	p = tl->sync;
+	if (likely(p && (id >> SHIFT) == p->prefix))
+		goto set;
+
+	if (!p) {
+		p = kzalloc(sizeof(*p), GFP_KERNEL);
+		if (unlikely(!p))
+			return -ENOMEM;
+
+		p->prefix = id >> SHIFT;
+		goto found;
+	}
+
+	/* Climb back up the tree until we find a common prefix */
+	do {
+		if (!p->parent)
+			break;
+
+		p = p->parent;
+
+		if ((id >> p->height >> SHIFT) == p->prefix)
+			break;
+	} while (1);
+
+	/* No shortcut, we have to descend the tree to find the right layer
+	 * containing this fence.
+	 *
+	 * Each layer in the tree holds 16 (NSEQMAP) pointers, either fences
+	 * or lower layers. Leaf nodes (height = 0) contain the fences, all
+	 * other nodes (height > 0) are internal layers that point to a lower
+	 * node. Each internal layer has at least 2 descendents.
+	 *
+	 * Starting at the top, we check whether the current prefix matches. If
+	 * it doesn't, we have gone passed our layer and need to insert a join
+	 * into the tree, and a new leaf node as a descendent as well as the
+	 * original layer.
+	 *
+	 * The matching prefix means we are still following the right branch
+	 * of the tree. If it has height 0, we have found our leaf and just
+	 * need to replace the fence slot with ourselves. If the height is
+	 * not zero, our slot contains the next layer in the tree (unless
+	 * it is empty, in which case we can add ourselves as a new leaf).
+	 * As descend the tree the prefix grows (and height decreases).
+	 */
+	do {
+		struct seqmap *next;
+
+		if ((id >> p->height >> SHIFT) != p->prefix) {
+			/* insert a join above the current layer */
+			next = kzalloc(sizeof(*next), GFP_KERNEL);
+			if (unlikely(!next))
+				return -ENOMEM;
+
+			next->height = ALIGN(fls64((id >> p->height >> SHIFT) ^ p->prefix),
+					    SHIFT) + p->height;
+			next->prefix = id >> next->height >> SHIFT;
+
+			if (p->parent)
+				p->parent->slot[layer_idx(p->parent, id)] = next;
+			next->parent = p->parent;
+
+			idx = p->prefix >> (next->height - p->height - SHIFT) & MASK;
+			next->slot[idx] = p;
+			next->bitmap |= BIT(idx);
+			p->parent = next;
+
+			/* ascend to the join */
+			p = next;
+		} else {
+			if (!p->height)
+				break;
+		}
+
+		/* descend into the next layer */
+		GEM_BUG_ON(!p->height);
+		idx = layer_idx(p, id);
+		next = p->slot[idx];
+		if (unlikely(!next)) {
+			next = kzalloc(sizeof(*next), GFP_KERNEL);
+			if (unlikely(!next))
+				return -ENOMEM;
+
+			p->slot[idx] = next;
+			p->bitmap |= BIT(idx);
+			next->parent = p;
+			next->prefix = id >> SHIFT;
+
+			p = next;
+			break;
+		}
+
+		p = next;
+	} while (1);
+
+found:
+	GEM_BUG_ON(p->height);
+	GEM_BUG_ON(p->prefix != id >> SHIFT);
+	tl->sync = p;
+set:
+	idx = id & MASK;
+	p->slot[idx] = (void *)(uintptr_t)seqno;
+	p->bitmap |= BIT(idx);
+	return 0;
+}
+
 static int __i915_gem_timeline_init(struct drm_i915_private *i915,
 				    struct i915_gem_timeline *timeline,
 				    const char *name,
@@ -91,8 +279,14 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
 		struct intel_timeline *tl = &timeline->engine[i];
 
 		GEM_BUG_ON(!list_empty(&tl->requests));
+
+		seqmap_free(tl->sync);
 	}
 
 	list_del(&timeline->link);
 	kfree(timeline->name);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/i915_gem_timeline.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 6c53e14cab2a..64bad92320de 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -26,11 +26,23 @@
 #define I915_GEM_TIMELINE_H
 
 #include <linux/list.h>
+#include <linux/radix-tree.h>
 
+#include "i915_utils.h"
 #include "i915_gem_request.h"
 
 struct i915_gem_timeline;
 
+#define NSEQMAP 16
+
+struct seqmap {
+	u64 prefix;
+	unsigned int height;
+	unsigned int bitmap;
+	struct seqmap *parent;
+	void *slot[NSEQMAP];
+};
+
 struct intel_timeline {
 	u64 fence_context;
 	u32 seqno;
@@ -55,6 +67,8 @@ struct intel_timeline {
 	 * struct_mutex.
 	 */
 	struct i915_gem_active last_request;
+
+	struct seqmap *sync;
 	u32 sync_seqno[I915_NUM_ENGINES];
 
 	struct i915_gem_timeline *common;
@@ -75,4 +89,8 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
 int i915_gem_timeline_init__global(struct drm_i915_private *i915);
 void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
 
+bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno);
+
+int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno);
+
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
new file mode 100644
index 000000000000..c0bb8ecac93b
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+#include "mock_gem_device.h"
+
+static int igt_seqmap(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	const struct {
+		const char *name;
+		u32 seqno;
+		bool expected;
+		bool set;
+	} pass[] = {
+		{ "unset", 0, false, false },
+		{ "new", 0, false, true },
+		{ "0a", 0, true, true },
+		{ "1a", 1, false, true },
+		{ "1b", 1, true, true },
+		{ "0b", 0, true, false },
+		{ "2a", 2, false, true },
+		{ "4", 4, false, true },
+		{ "INT_MAX", INT_MAX, false, true },
+		{ "INT_MAX-1", INT_MAX-1, true, false },
+		{ "INT_MAX+1", (u32)INT_MAX+1, false, true },
+		{ "INT_MAX", INT_MAX, true, false },
+		{ "UINT_MAX", UINT_MAX, false, true },
+		{ "wrap", 0, false, true },
+		{ "unwrap", UINT_MAX, true, false },
+		{},
+	}, *p;
+	struct intel_timeline *tl;
+	int order, offset;
+	int ret;
+
+	tl = &i915->gt.global_timeline.engine[RCS];
+	for (p = pass; p->name; p++) {
+		for (order = 1; order < 64; order++) {
+			for (offset = -1; offset <= (order > 1); offset++) {
+				u64 ctx = BIT_ULL(order) + offset;
+
+				if (intel_timeline_sync_get(tl,
+							    ctx,
+							    p->seqno) != p->expected) {
+					pr_err("1: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
+					       p->name, ctx, p->seqno, yesno(p->expected));
+					return -EINVAL;
+				}
+
+				if (p->set) {
+					ret = intel_timeline_sync_set(tl, ctx, p->seqno);
+					if (ret)
+						return ret;
+				}
+			}
+		}
+	}
+
+	tl = &i915->gt.global_timeline.engine[BCS];
+	for (order = 1; order < 64; order++) {
+		for (offset = -1; offset <= (order > 1); offset++) {
+			u64 ctx = BIT_ULL(order) + offset;
+
+			for (p = pass; p->name; p++) {
+				if (intel_timeline_sync_get(tl,
+							    ctx,
+							    p->seqno) != p->expected) {
+					pr_err("2: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
+					       p->name, ctx, p->seqno, yesno(p->expected));
+					return -EINVAL;
+				}
+
+				if (p->set) {
+					ret = intel_timeline_sync_set(tl, ctx, p->seqno);
+					if (ret)
+						return ret;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+int i915_gem_timeline_mock_selftests(void)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_seqmap),
+	};
+	struct drm_i915_private *i915;
+	int err;
+
+	i915 = mock_gem_device();
+	if (!i915)
+		return -ENOMEM;
+
+	err = i915_subtests(tests, i915);
+	drm_dev_unref(&i915->drm);
+
+	return err;
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index be9a9ebf5692..8d0f50c25df8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -12,6 +12,7 @@ selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
 selftest(scatterlist, scatterlist_mock_selftests)
 selftest(uncore, intel_uncore_mock_selftests)
 selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
+selftest(timelines, i915_gem_timeline_mock_selftests)
 selftest(requests, i915_gem_request_mock_selftests)
 selftest(objects, i915_gem_object_mock_selftests)
 selftest(dmabuf, i915_gem_dmabuf_mock_selftests)
-- 
2.11.0

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

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

* Re: [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate
  2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson
@ 2017-04-12 14:41   ` Joonas Lahtinen
  0 siblings, 0 replies; 19+ messages in thread
From: Joonas Lahtinen @ 2017-04-12 14:41 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On ke, 2017-04-12 at 13:48 +0100, Chris Wilson wrote:
> Rather than use a global modparam, we can just check to see if the
> engine has semaphores configured upon it.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

Should be good.

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regars, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2)
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (8 preceding siblings ...)
  2017-04-12 13:20 ` ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Patchwork
@ 2017-04-12 15:01 ` Patchwork
  2017-04-12 17:00 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) Patchwork
  10 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2017-04-12 15:01 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2)
URL   : https://patchwork.freedesktop.org/series/22924/
State : failure

== Summary ==

scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_perf.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_perf.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/opregion.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/opregion.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dp_aux_backlight.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_dp_aux_backlight.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/dvo_tfp410.o' failed
make[4]: *** [drivers/gpu/drm/i915/dvo_tfp410.o] Error 1
  LD      net/ipv6/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dsi_pll.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_dsi_pll.o] Error 1
  LD      drivers/video/console/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/sched_policy.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/sched_policy.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_bios.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_bios.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_panel.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_panel.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dvo.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_dvo.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/display.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/display.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/cmd_parser.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/cmd_parser.o] Error 1
  LD      drivers/video/fbdev/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/firmware.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/firmware.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_cdclk.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_cdclk.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/dvo_ch7xxx.o' failed
make[4]: *** [drivers/gpu/drm/i915/dvo_ch7xxx.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dsi_vbt.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_dsi_vbt.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_pm.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_pm.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_lspcon.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_lspcon.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_opregion.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_opregion.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_sdvo.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_sdvo.o] Error 1
  LD      drivers/video/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_sprite.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_sprite.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/render.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/render.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/handlers.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/handlers.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_lpe_audio.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_lpe_audio.o] Error 1
  LD      drivers/usb/gadget/udc/udc-core.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/mmio.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/mmio.o] Error 1
  LD      drivers/usb/gadget/udc/built-in.o
  LD      drivers/usb/gadget/built-in.o
  LD      drivers/scsi/scsi_mod.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_display.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_display.o] Error 1
  LD      drivers/pci/built-in.o
  LD      net/ipv4/built-in.o
scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
make[3]: *** Waiting for unfinished jobs....
  LD      drivers/tty/serial/8250/8250_base.o
  LD      drivers/tty/serial/8250/built-in.o
  LD      drivers/tty/serial/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000/e1000.o
scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:553: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
make[1]: *** Waiting for unfinished jobs....
  LD      fs/btrfs/btrfs.o
  CC      arch/x86/kernel/cpu/capflags.o
  LD      arch/x86/kernel/cpu/built-in.o
  LD      drivers/usb/core/usbcore.o
  LD      drivers/scsi/sd_mod.o
  LD      arch/x86/kernel/built-in.o
  LD      drivers/scsi/built-in.o
  LD      drivers/usb/core/built-in.o
  LD      fs/btrfs/built-in.o
  LD      arch/x86/built-in.o
  LD      drivers/tty/vt/built-in.o
  LD      drivers/tty/built-in.o
  LD [M]  drivers/net/ethernet/intel/igb/igb.o
  LD      drivers/usb/host/xhci-hcd.o
  LD      drivers/md/md-mod.o
  LD      drivers/md/built-in.o
  LD      net/core/built-in.o
  LD      net/built-in.o
  LD      fs/ext4/ext4.o
  LD      fs/ext4/built-in.o
  LD      fs/built-in.o
  LD      drivers/usb/host/built-in.o
  LD      drivers/usb/built-in.o
  LD [M]  drivers/net/ethernet/intel/e1000e/e1000e.o
  LD      drivers/net/ethernet/built-in.o
  LD      drivers/net/built-in.o
Makefile:1002: recipe for target 'drivers' failed
make: *** [drivers] Error 2

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

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

* [PATCH v4] drm/i915: Squash repeated awaits on the same fence
  2017-04-12 14:24   ` [PATCH v3] " Chris Wilson
@ 2017-04-12 15:39     ` Chris Wilson
  0 siblings, 0 replies; 19+ messages in thread
From: Chris Wilson @ 2017-04-12 15:39 UTC (permalink / raw)
  To: intel-gfx

Track the latest fence waited upon on each context, and only add a new
asynchronous wait if the new fence is more recent than the recorded
fence for that context. This requires us to filter out unordered
timelines, which are noted by DMA_FENCE_NO_CONTEXT. However, in the
absence of a universal identifier, we have to use our own
i915->mm.unordered_timeline token.

v2: Throw around the debug crutches
v3: Inline the likely case of the pre-allocation cache being full.
v4: Drop the pre-allocation support, we can lose the most recent fence
in case of allocation failure -- it just means we may emit more awaits
than strictly necessary but will not break.
v5: Trim allocation size for leaf nodes, they only need an array of u32
not pointers.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_gem_request.c            |  66 ++++---
 drivers/gpu/drm/i915/i915_gem_timeline.c           | 215 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_timeline.h           |   8 +
 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c | 123 ++++++++++++
 .../gpu/drm/i915/selftests/i915_mock_selftests.h   |   1 +
 5 files changed, 386 insertions(+), 27 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem_timeline.c

diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 31874a38752e..f679c16aa5c6 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -714,9 +714,7 @@ int
 i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 				 struct dma_fence *fence)
 {
-	struct dma_fence_array *array;
 	int ret;
-	int i;
 
 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return 0;
@@ -728,39 +726,53 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 	if (fence->context == req->fence.context)
 		return 0;
 
-	if (dma_fence_is_i915(fence))
-		return i915_gem_request_await_request(req, to_request(fence));
+	/* Squash repeated waits to the same timelines, picking the latest */
+	if (fence->context != req->i915->mm.unordered_timeline &&
+	    intel_timeline_sync_get(req->timeline,
+				    fence->context, fence->seqno))
+		return 0;
 
-	if (!dma_fence_is_array(fence)) {
+	if (dma_fence_is_i915(fence)) {
+		ret = i915_gem_request_await_request(req, to_request(fence));
+		if (ret < 0)
+			return ret;
+	} else if (!dma_fence_is_array(fence)) {
 		ret = i915_sw_fence_await_dma_fence(&req->submit,
 						    fence, I915_FENCE_TIMEOUT,
 						    GFP_KERNEL);
-		return ret < 0 ? ret : 0;
-	}
-
-	/* Note that if the fence-array was created in signal-on-any mode,
-	 * we should *not* decompose it into its individual fences. However,
-	 * we don't currently store which mode the fence-array is operating
-	 * in. Fortunately, the only user of signal-on-any is private to
-	 * amdgpu and we should not see any incoming fence-array from
-	 * sync-file being in signal-on-any mode.
-	 */
-
-	array = to_dma_fence_array(fence);
-	for (i = 0; i < array->num_fences; i++) {
-		struct dma_fence *child = array->fences[i];
-
-		if (dma_fence_is_i915(child))
-			ret = i915_gem_request_await_request(req,
-							     to_request(child));
-		else
-			ret = i915_sw_fence_await_dma_fence(&req->submit,
-							    child, I915_FENCE_TIMEOUT,
-							    GFP_KERNEL);
 		if (ret < 0)
 			return ret;
+	} else {
+		struct dma_fence_array *array = to_dma_fence_array(fence);
+		int i;
+
+		/* Note that if the fence-array was created in signal-on-any mode,
+		 * we should *not* decompose it into its individual fences. However,
+		 * we don't currently store which mode the fence-array is operating
+		 * in. Fortunately, the only user of signal-on-any is private to
+		 * amdgpu and we should not see any incoming fence-array from
+		 * sync-file being in signal-on-any mode.
+		 */
+
+		for (i = 0; i < array->num_fences; i++) {
+			struct dma_fence *child = array->fences[i];
+
+			if (dma_fence_is_i915(child))
+				ret = i915_gem_request_await_request(req,
+								     to_request(child));
+			else
+				ret = i915_sw_fence_await_dma_fence(&req->submit,
+								    child, I915_FENCE_TIMEOUT,
+								    GFP_KERNEL);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
+	if (fence->context != req->i915->mm.unordered_timeline)
+		intel_timeline_sync_set(req->timeline,
+					fence->context, fence->seqno);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index b596ca7ee058..15ff9f37b6dc 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -24,6 +24,215 @@
 
 #include "i915_drv.h"
 
+#define NSYNC 16
+#define SHIFT ilog2(NSYNC)
+#define MASK (NSYNC - 1)
+
+struct intel_timeline_sync {
+	u64 prefix;
+	unsigned int height;
+	unsigned int bitmap;
+	struct intel_timeline_sync *parent;
+};
+
+static inline u32 *__sync_seqno(struct intel_timeline_sync *p)
+{
+	return (u32 *)(p + 1);
+}
+
+static inline struct intel_timeline_sync **
+__sync_child(struct intel_timeline_sync *p)
+{
+	return (struct intel_timeline_sync **)(p + 1);
+}
+
+static void __sync_free(struct intel_timeline_sync *p)
+{
+	unsigned int i;
+
+	if (p->height) {
+		for (; (i = ffs(p->bitmap)); p->bitmap &= ~0u << i)
+			__sync_free(__sync_child(p)[i - 1]);
+	}
+
+	kfree(p);
+}
+
+static void sync_free(struct intel_timeline_sync *sync)
+{
+	if (!sync)
+		return;
+
+	while (sync->parent)
+		sync = sync->parent;
+
+	__sync_free(sync);
+}
+
+static int layer_idx(const struct intel_timeline_sync *p, u64 id)
+{
+	return (id >> p->height) & MASK;
+}
+
+bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno)
+{
+	struct intel_timeline_sync *p;
+	unsigned int idx;
+
+	p = tl->sync;
+	if (!p)
+		return false;
+
+	if ((id >> SHIFT) == p->prefix)
+		goto found;
+
+	/* First climb the tree back to a parent branch */
+	do {
+		p = p->parent;
+		if (!p)
+			return false;
+
+		if ((id >> p->height >> SHIFT) == p->prefix)
+			break;
+	} while (1);
+
+	/* And then descend again until we find our leaf */
+	do {
+		if (!p->height)
+			break;
+
+		p = __sync_child(p)[layer_idx(p, id)];
+		if (!p)
+			return false;
+
+		if ((id >> p->height >> SHIFT) != p->prefix)
+			return false;
+	} while (1);
+
+	tl->sync = p;
+found:
+	idx = id & MASK;
+	if (!(p->bitmap & BIT(idx)))
+		return false;
+
+	return i915_seqno_passed(__sync_seqno(p)[idx], seqno);
+}
+
+int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno)
+{
+	struct intel_timeline_sync *p;
+	unsigned int idx;
+
+	/* We expect to be called in sequence following a  _get(id), which
+	 * should have preloaded the tl->sync hint for us.
+	 */
+	p = tl->sync;
+	if (likely(p && (id >> SHIFT) == p->prefix))
+		goto set;
+
+	if (!p) {
+		p = kzalloc(sizeof(*p) + NSYNC * sizeof(seqno), GFP_KERNEL);
+		if (unlikely(!p))
+			return -ENOMEM;
+
+		p->prefix = id >> SHIFT;
+		goto found;
+	}
+
+	/* Climb back up the tree until we find a common prefix */
+	do {
+		if (!p->parent)
+			break;
+
+		p = p->parent;
+
+		if ((id >> p->height >> SHIFT) == p->prefix)
+			break;
+	} while (1);
+
+	/* No shortcut, we have to descend the tree to find the right layer
+	 * containing this fence.
+	 *
+	 * Each layer in the tree holds 16 (NSYNC) pointers, either fences
+	 * or lower layers. Leaf nodes (height = 0) contain the fences, all
+	 * other nodes (height > 0) are internal layers that point to a lower
+	 * node. Each internal layer has at least 2 descendents.
+	 *
+	 * Starting at the top, we check whether the current prefix matches. If
+	 * it doesn't, we have gone passed our layer and need to insert a join
+	 * into the tree, and a new leaf node as a descendent as well as the
+	 * original layer.
+	 *
+	 * The matching prefix means we are still following the right branch
+	 * of the tree. If it has height 0, we have found our leaf and just
+	 * need to replace the fence slot with ourselves. If the height is
+	 * not zero, our slot contains the next layer in the tree (unless
+	 * it is empty, in which case we can add ourselves as a new leaf).
+	 * As descend the tree the prefix grows (and height decreases).
+	 */
+	do {
+		struct intel_timeline_sync *next;
+
+		if ((id >> p->height >> SHIFT) != p->prefix) {
+			/* insert a join above the current layer */
+			next = kzalloc(sizeof(*next) + NSYNC * sizeof(next),
+				       GFP_KERNEL);
+			if (unlikely(!next))
+				return -ENOMEM;
+
+			next->height = ALIGN(fls64((id >> p->height >> SHIFT) ^ p->prefix),
+					    SHIFT) + p->height;
+			next->prefix = id >> next->height >> SHIFT;
+
+			if (p->parent)
+				__sync_child(p->parent)[layer_idx(p->parent, id)] = next;
+			next->parent = p->parent;
+
+			idx = p->prefix >> (next->height - p->height - SHIFT) & MASK;
+			__sync_child(next)[idx] = p;
+			next->bitmap |= BIT(idx);
+			p->parent = next;
+
+			/* ascend to the join */
+			p = next;
+		} else {
+			if (!p->height)
+				break;
+		}
+
+		/* descend into the next layer */
+		GEM_BUG_ON(!p->height);
+		idx = layer_idx(p, id);
+		next = __sync_child(p)[idx];
+		if (unlikely(!next)) {
+			next = kzalloc(sizeof(*next) + NSYNC * sizeof(seqno),
+				       GFP_KERNEL);
+			if (unlikely(!next))
+				return -ENOMEM;
+
+			__sync_child(p)[idx] = next;
+			p->bitmap |= BIT(idx);
+			next->parent = p;
+			next->prefix = id >> SHIFT;
+
+			p = next;
+			break;
+		}
+
+		p = next;
+	} while (1);
+
+found:
+	GEM_BUG_ON(p->height);
+	GEM_BUG_ON(p->prefix != id >> SHIFT);
+	tl->sync = p;
+set:
+	idx = id & MASK;
+	__sync_seqno(p)[idx] = seqno;
+	p->bitmap |= BIT(idx);
+	return 0;
+}
+
 static int __i915_gem_timeline_init(struct drm_i915_private *i915,
 				    struct i915_gem_timeline *timeline,
 				    const char *name,
@@ -91,8 +300,14 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
 		struct intel_timeline *tl = &timeline->engine[i];
 
 		GEM_BUG_ON(!list_empty(&tl->requests));
+
+		sync_free(tl->sync);
 	}
 
 	list_del(&timeline->link);
 	kfree(timeline->name);
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/i915_gem_timeline.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 6c53e14cab2a..22a80daa6efa 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -26,10 +26,13 @@
 #define I915_GEM_TIMELINE_H
 
 #include <linux/list.h>
+#include <linux/radix-tree.h>
 
+#include "i915_utils.h"
 #include "i915_gem_request.h"
 
 struct i915_gem_timeline;
+struct intel_timeline_sync;
 
 struct intel_timeline {
 	u64 fence_context;
@@ -55,6 +58,8 @@ struct intel_timeline {
 	 * struct_mutex.
 	 */
 	struct i915_gem_active last_request;
+
+	struct intel_timeline_sync *sync;
 	u32 sync_seqno[I915_NUM_ENGINES];
 
 	struct i915_gem_timeline *common;
@@ -75,4 +80,7 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
 int i915_gem_timeline_init__global(struct drm_i915_private *i915);
 void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
 
+bool intel_timeline_sync_get(struct intel_timeline *tl, u64 id, u32 seqno);
+int intel_timeline_sync_set(struct intel_timeline *tl, u64 id, u32 seqno);
+
 #endif
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
new file mode 100644
index 000000000000..c0bb8ecac93b
--- /dev/null
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "../i915_selftest.h"
+#include "mock_gem_device.h"
+
+static int igt_seqmap(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	const struct {
+		const char *name;
+		u32 seqno;
+		bool expected;
+		bool set;
+	} pass[] = {
+		{ "unset", 0, false, false },
+		{ "new", 0, false, true },
+		{ "0a", 0, true, true },
+		{ "1a", 1, false, true },
+		{ "1b", 1, true, true },
+		{ "0b", 0, true, false },
+		{ "2a", 2, false, true },
+		{ "4", 4, false, true },
+		{ "INT_MAX", INT_MAX, false, true },
+		{ "INT_MAX-1", INT_MAX-1, true, false },
+		{ "INT_MAX+1", (u32)INT_MAX+1, false, true },
+		{ "INT_MAX", INT_MAX, true, false },
+		{ "UINT_MAX", UINT_MAX, false, true },
+		{ "wrap", 0, false, true },
+		{ "unwrap", UINT_MAX, true, false },
+		{},
+	}, *p;
+	struct intel_timeline *tl;
+	int order, offset;
+	int ret;
+
+	tl = &i915->gt.global_timeline.engine[RCS];
+	for (p = pass; p->name; p++) {
+		for (order = 1; order < 64; order++) {
+			for (offset = -1; offset <= (order > 1); offset++) {
+				u64 ctx = BIT_ULL(order) + offset;
+
+				if (intel_timeline_sync_get(tl,
+							    ctx,
+							    p->seqno) != p->expected) {
+					pr_err("1: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
+					       p->name, ctx, p->seqno, yesno(p->expected));
+					return -EINVAL;
+				}
+
+				if (p->set) {
+					ret = intel_timeline_sync_set(tl, ctx, p->seqno);
+					if (ret)
+						return ret;
+				}
+			}
+		}
+	}
+
+	tl = &i915->gt.global_timeline.engine[BCS];
+	for (order = 1; order < 64; order++) {
+		for (offset = -1; offset <= (order > 1); offset++) {
+			u64 ctx = BIT_ULL(order) + offset;
+
+			for (p = pass; p->name; p++) {
+				if (intel_timeline_sync_get(tl,
+							    ctx,
+							    p->seqno) != p->expected) {
+					pr_err("2: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
+					       p->name, ctx, p->seqno, yesno(p->expected));
+					return -EINVAL;
+				}
+
+				if (p->set) {
+					ret = intel_timeline_sync_set(tl, ctx, p->seqno);
+					if (ret)
+						return ret;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+int i915_gem_timeline_mock_selftests(void)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(igt_seqmap),
+	};
+	struct drm_i915_private *i915;
+	int err;
+
+	i915 = mock_gem_device();
+	if (!i915)
+		return -ENOMEM;
+
+	err = i915_subtests(tests, i915);
+	drm_dev_unref(&i915->drm);
+
+	return err;
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
index be9a9ebf5692..8d0f50c25df8 100644
--- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
@@ -12,6 +12,7 @@ selftest(sanitycheck, i915_mock_sanitycheck) /* keep first (igt selfcheck) */
 selftest(scatterlist, scatterlist_mock_selftests)
 selftest(uncore, intel_uncore_mock_selftests)
 selftest(breadcrumbs, intel_breadcrumbs_mock_selftests)
+selftest(timelines, i915_gem_timeline_mock_selftests)
 selftest(requests, i915_gem_request_mock_selftests)
 selftest(objects, i915_gem_object_mock_selftests)
 selftest(dmabuf, i915_gem_dmabuf_mock_selftests)
-- 
2.11.0

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

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

* Re: [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await
  2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson
@ 2017-04-12 16:31   ` Michał Winiarski
  2017-04-13 10:46   ` Joonas Lahtinen
  1 sibling, 0 replies; 19+ messages in thread
From: Michał Winiarski @ 2017-04-12 16:31 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Wed, Apr 12, 2017 at 01:48:23PM +0100, Chris Wilson wrote:
> Although we do check the completion-status of the request before
> actually adding a wait on it (either to its submit fence or its
> completion dma-fence), we currently do not check before adding it to the
> dependency lists.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

Reviewed-by: Michał Winiarski <michal.winiarski@intel.com>

-Michał

> ---
>  drivers/gpu/drm/i915/i915_gem_request.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
> index 87ca3453140a..436693b12bae 100644
> --- a/drivers/gpu/drm/i915/i915_gem_request.c
> +++ b/drivers/gpu/drm/i915/i915_gem_request.c
> @@ -665,6 +665,9 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
>  	GEM_BUG_ON(to == from);
>  	GEM_BUG_ON(to->timeline == from->timeline);
>  
> +	if (i915_gem_request_completed(from))
> +		return 0;
> +
>  	if (to->engine->schedule) {
>  		ret = i915_priotree_add_dependency(to->i915,
>  						   &to->priotree,
> -- 
> 2.11.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await
  2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson
@ 2017-04-12 16:54   ` Michał Winiarski
  0 siblings, 0 replies; 19+ messages in thread
From: Michał Winiarski @ 2017-04-12 16:54 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Wed, Apr 12, 2017 at 01:48:24PM +0100, Chris Wilson wrote:
> As we may unwind the requests, even though the request we are awaiting
> has a global_seqno that seqno may be revoked during the await and so we
> can not reliably use it as a barrier for all future awaits on the same
> timeline.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Michał Winiarski <michal.winiarski@intel.com>

Reviewed-by: Michał Winiarski <michal.winiarski@intel.com>

-Michał

> ---
>  drivers/gpu/drm/i915/i915_gem_request.c | 34 ++++++++++++++++-----------------
>  1 file changed, 16 insertions(+), 18 deletions(-)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3)
  2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
                   ` (9 preceding siblings ...)
  2017-04-12 15:01 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) Patchwork
@ 2017-04-12 17:00 ` Patchwork
  10 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2017-04-12 17:00 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3)
URL   : https://patchwork.freedesktop.org/series/22924/
State : failure

== Summary ==

scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/cfg_space.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/cfg_space.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_modes.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_modes.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_cdclk.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_cdclk.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_gem_gtt.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_gem_gtt.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/dvo_ns2501.o' failed
make[4]: *** [drivers/gpu/drm/i915/dvo_ns2501.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_vgpu.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_vgpu.o] Error 1
  LD      net/ipv6/ipv6.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_pm.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_pm.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/edid.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/edid.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/render.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/render.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_lvds.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_lvds.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dp.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_dp.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/vgpu.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/vgpu.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/mmio.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/mmio.o] Error 1
  LD [M]  drivers/net/ethernet/intel/igbvf/igbvf.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_gem.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_gem.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_i2c.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_i2c.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/sched_policy.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/sched_policy.o] Error 1
  LD      drivers/usb/gadget/udc/udc-core.o
  LD      net/ipv6/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_dp_mst.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_dp_mst.o] Error 1
  LD      drivers/usb/gadget/udc/built-in.o
  LD      drivers/usb/gadget/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_opregion.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_opregion.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/aperture_gm.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/aperture_gm.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_display.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_display.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_oa_hsw.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_oa_hsw.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/gtt.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/gtt.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/cmd_parser.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/cmd_parser.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/i915_gpu_error.o' failed
make[4]: *** [drivers/gpu/drm/i915/i915_gpu_error.o] Error 1
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/intel_gvt.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_gvt.o] Error 1
  LD      drivers/gpu/drm/drm.o
  LD [M]  drivers/net/ethernet/intel/e1000/e1000.o
  LD      drivers/tty/serial/8250/8250_base.o
  LD      drivers/tty/serial/8250/built-in.o
  LD      fs/btrfs/btrfs.o
  LD      drivers/tty/serial/built-in.o
scripts/Makefile.build:294: recipe for target 'drivers/gpu/drm/i915/gvt/handlers.o' failed
make[4]: *** [drivers/gpu/drm/i915/gvt/handlers.o] Error 1
scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:553: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:553: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
make[1]: *** Waiting for unfinished jobs....
  LD      fs/btrfs/built-in.o
  LD      drivers/tty/vt/built-in.o
  CC      arch/x86/kernel/cpu/capflags.o
  LD      drivers/tty/built-in.o
  LD      arch/x86/kernel/cpu/built-in.o
  LD      drivers/md/md-mod.o
  LD      drivers/md/built-in.o
  LD      arch/x86/kernel/built-in.o
  AR      lib/lib.a
  EXPORTS lib/lib-ksyms.o
  LD      lib/built-in.o
  LD      drivers/usb/core/usbcore.o
  LD      drivers/usb/core/built-in.o
  LD      arch/x86/built-in.o
  LD [M]  drivers/net/ethernet/intel/igb/igb.o
  LD [M]  drivers/net/ethernet/intel/e1000e/e1000e.o
  LD      drivers/usb/host/xhci-hcd.o
  LD      net/ipv4/built-in.o
  LD      drivers/usb/host/built-in.o
  LD      drivers/usb/built-in.o
  LD      fs/ext4/ext4.o
  LD      fs/ext4/built-in.o
  LD      fs/built-in.o
  LD      net/core/built-in.o
  LD      net/built-in.o
  LD      drivers/net/ethernet/built-in.o
  LD      drivers/net/built-in.o
Makefile:1002: recipe for target 'drivers' failed
make: *** [drivers] Error 2

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

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

* Re: [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await
  2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson
  2017-04-12 16:31   ` Michał Winiarski
@ 2017-04-13 10:46   ` Joonas Lahtinen
  1 sibling, 0 replies; 19+ messages in thread
From: Joonas Lahtinen @ 2017-04-13 10:46 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On ke, 2017-04-12 at 13:48 +0100, Chris Wilson wrote:
> Although we do check the completion-status of the request before
> actually adding a wait on it (either to its submit fence or its
> completion dma-fence), we currently do not check before adding it to the
> dependency lists.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

Well, it's not going to hurt.

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[]
  2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson
@ 2017-04-13 10:49   ` Joonas Lahtinen
  0 siblings, 0 replies; 19+ messages in thread
From: Joonas Lahtinen @ 2017-04-13 10:49 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On ke, 2017-04-12 at 13:48 +0100, Chris Wilson wrote:
> With the addition of the inter-context intel_time.sync map, having a

intel_timeline.sync?

> very similar sync_seqno[] is confusing. Aide the reader by denoting that
> this a pre-allocated array for storing semaphore sync points wrt to the
> global seqno.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-04-13 10:49 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-12 12:48 [PATCH v2 1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Chris Wilson
2017-04-12 12:48 ` [PATCH v2 2/9] drm/i915: Lift timeline ordering to await_dma_fence Chris Wilson
2017-04-12 12:48 ` [PATCH v2 3/9] drm/i915: Make ptr_unpack_bits() more function-like Chris Wilson
2017-04-12 12:48 ` [PATCH v2 4/9] drm/i915: Redefine ptr_pack_bits() and friends Chris Wilson
2017-04-12 12:48 ` [PATCH v2 5/9] drm/i915: Squash repeated awaits on the same fence Chris Wilson
2017-04-12 14:24   ` [PATCH v3] " Chris Wilson
2017-04-12 15:39     ` [PATCH v4] " Chris Wilson
2017-04-12 12:48 ` [PATCH v2 6/9] drm/i915: Rename intel_timeline.sync_seqno[] to .global_sync[] Chris Wilson
2017-04-13 10:49   ` Joonas Lahtinen
2017-04-12 12:48 ` [PATCH v2 7/9] drm/i915: Confirm the request is still active before adding it to the await Chris Wilson
2017-04-12 16:31   ` Michał Winiarski
2017-04-13 10:46   ` Joonas Lahtinen
2017-04-12 12:48 ` [PATCH v2 8/9] drm/i915: Do not record a successful syncpoint for a dma-await Chris Wilson
2017-04-12 16:54   ` Michał Winiarski
2017-04-12 12:48 ` [PATCH v2 9/9] drm/i915: Switch the global i915.semaphores check to a local predicate Chris Wilson
2017-04-12 14:41   ` Joonas Lahtinen
2017-04-12 13:20 ` ✓ Fi.CI.BAT: success for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline Patchwork
2017-04-12 15:01 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev2) Patchwork
2017-04-12 17:00 ` ✗ Fi.CI.BAT: failure for series starting with [v2,1/9] drm/i915: Mark up clflushes as belonging to an unordered timeline (rev3) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.