All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
@ 2018-04-23 18:08 Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 2/6] drm/i915: Retire requests along rings Chris Wilson
                   ` (14 more replies)
  0 siblings, 15 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 18:08 UTC (permalink / raw)
  To: intel-gfx

In commit 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine"), we
moved from a global inflight counter to per-engine counters in the
hope that will be easy to run concurrently in future. However, with the
advent of the desire to move requests between engines, we do need a
global counter to preserve the semantics that no engine wraps in the
middle of a submit. (Although this semantic is now only required for gen7
semaphore support, which only supports greater-then comparisons!)

v2: Keep a global counter of all requests ever submitted and force the
reset when it wraps.

References: 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c      |  5 ++--
 drivers/gpu/drm/i915/i915_drv.h          |  1 +
 drivers/gpu/drm/i915/i915_gem_timeline.h |  6 -----
 drivers/gpu/drm/i915/i915_request.c      | 33 ++++++++++++------------
 drivers/gpu/drm/i915/intel_engine_cs.c   |  5 ++--
 5 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 2f05f5262bba..547e97102b85 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1340,10 +1340,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
 		struct rb_node *rb;
 
 		seq_printf(m, "%s:\n", engine->name);
-		seq_printf(m, "\tseqno = %x [current %x, last %x], inflight %d\n",
+		seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
 			   engine->hangcheck.seqno, seqno[id],
-			   intel_engine_last_submit(engine),
-			   engine->timeline->inflight_seqnos);
+			   intel_engine_last_submit(engine));
 		seq_printf(m, "\twaiters? %s, fake irq active? %s, stalled? %s\n",
 			   yesno(intel_engine_has_waiter(engine)),
 			   yesno(test_bit(engine->id,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8444ca8d5aa3..8fd9fb6efba5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2061,6 +2061,7 @@ struct drm_i915_private {
 		struct list_head timelines;
 		struct i915_gem_timeline global_timeline;
 		u32 active_requests;
+		u32 request_serial;
 
 		/**
 		 * Is the GPU currently considered idle, or busy executing
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 33e01bf6aa36..6e82119e2cd8 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -37,12 +37,6 @@ struct intel_timeline {
 	u64 fence_context;
 	u32 seqno;
 
-	/**
-	 * Count of outstanding requests, from the time they are constructed
-	 * to the moment they are retired. Loosely coupled to hardware.
-	 */
-	u32 inflight_seqnos;
-
 	spinlock_t lock;
 
 	/**
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index b692a9f7c357..f3d04f0ab21c 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -241,6 +241,7 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 			       sizeof(timeline->engine[id].global_sync));
 	}
 
+	i915->gt.request_serial = seqno;
 	return 0;
 }
 
@@ -257,18 +258,22 @@ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
 	return reset_all_global_seqno(i915, seqno - 1);
 }
 
-static int reserve_engine(struct intel_engine_cs *engine)
+static int reserve_gt(struct drm_i915_private *i915)
 {
-	struct drm_i915_private *i915 = engine->i915;
-	u32 active = ++engine->timeline->inflight_seqnos;
-	u32 seqno = engine->timeline->seqno;
 	int ret;
 
-	/* Reservation is fine until we need to wrap around */
-	if (unlikely(add_overflows(seqno, active))) {
+	/*
+	 * Reservation is fine until we may need to wrap around
+	 *
+	 * By incrementing the serial for every request, we know that no
+	 * individual engine may exceed that serial (as each is reset to 0
+	 * on any wrap). This protects even the most pessimistic of migrations
+	 * of every request from all engines onto just one.
+	 */
+	if (unlikely(++i915->gt.request_serial == 0)) {
 		ret = reset_all_global_seqno(i915, 0);
 		if (ret) {
-			engine->timeline->inflight_seqnos--;
+			i915->gt.request_serial--;
 			return ret;
 		}
 	}
@@ -279,15 +284,10 @@ static int reserve_engine(struct intel_engine_cs *engine)
 	return 0;
 }
 
-static void unreserve_engine(struct intel_engine_cs *engine)
+static void unreserve_gt(struct drm_i915_private *i915)
 {
-	struct drm_i915_private *i915 = engine->i915;
-
 	if (!--i915->gt.active_requests)
 		i915_gem_park(i915);
-
-	GEM_BUG_ON(!engine->timeline->inflight_seqnos);
-	engine->timeline->inflight_seqnos--;
 }
 
 void i915_gem_retire_noop(struct i915_gem_active *active,
@@ -362,7 +362,6 @@ static void i915_request_retire(struct i915_request *request)
 	list_del_init(&request->link);
 	spin_unlock_irq(&engine->timeline->lock);
 
-	unreserve_engine(request->engine);
 	advance_ring(request);
 
 	free_capture_list(request);
@@ -424,6 +423,8 @@ static void i915_request_retire(struct i915_request *request)
 	}
 	spin_unlock_irq(&request->lock);
 
+	unreserve_gt(request->i915);
+
 	i915_sched_node_fini(request->i915, &request->sched);
 	i915_request_put(request);
 }
@@ -642,7 +643,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 		return ERR_CAST(ring);
 	GEM_BUG_ON(!ring);
 
-	ret = reserve_engine(engine);
+	ret = reserve_gt(i915);
 	if (ret)
 		goto err_unpin;
 
@@ -784,7 +785,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 
 	kmem_cache_free(i915->requests, rq);
 err_unreserve:
-	unreserve_engine(engine);
+	unreserve_gt(i915);
 err_unpin:
 	engine->context_unpin(engine, ctx);
 	return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index be608f7111f5..a55a849b81b6 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1318,12 +1318,11 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 	if (i915_terminally_wedged(&engine->i915->gpu_error))
 		drm_printf(m, "*** WEDGED ***\n");
 
-	drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n",
+	drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms]\n",
 		   intel_engine_get_seqno(engine),
 		   intel_engine_last_submit(engine),
 		   engine->hangcheck.seqno,
-		   jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
-		   engine->timeline->inflight_seqnos);
+		   jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp));
 	drm_printf(m, "\tReset count: %d (global %d)\n",
 		   i915_reset_engine_count(error, engine),
 		   i915_reset_count(error));
-- 
2.17.0

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

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

* [PATCH v2 2/6] drm/i915: Retire requests along rings
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
@ 2018-04-23 18:08 ` Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 3/6] drm/i915: Only track live rings for retiring Chris Wilson
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 18:08 UTC (permalink / raw)
  To: intel-gfx

In the next patch, rings are the central timeline as requests may jump
between engines. Therefore in the future as we retire in order along the
engine timeline, we may retire out-of-order within a ring (as the ring now
occurs along multiple engines), leading to much hilarity in miscomputing
the position of ring->head.

As an added bonus, retiring along the ring reduces the penalty of having
one execlists client do cleanup for another (old legacy submission
shares a ring between all clients). The downside is that slow and
irregular (off the critical path) process of cleaning up stale requests
after userspace becomes a modicum less efficient.

In the long run, it will become apparent that the ordered
ring->request_list matches the ring->timeline, a fun challenge for the
future will be unifying the two lists to avoid duplication!

v2: We need both engine-order and ring-order processing to maintain our
knowledge of where individual rings have completed upto as well as
knowing what was last executing on any engine. And finally by decoupling
retiring the contexts on the engine and the timelines along the rings,
we do have to keep a reference to the context on each request
(previously it was guaranteed by the context being pinned).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               |   3 +-
 drivers/gpu/drm/i915/i915_gem.c               |   1 +
 drivers/gpu/drm/i915/i915_request.c           | 135 ++++++++++--------
 drivers/gpu/drm/i915/i915_utils.h             |   6 +
 drivers/gpu/drm/i915/intel_ringbuffer.c       |   6 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h       |   1 +
 drivers/gpu/drm/i915/selftests/mock_engine.c  |  27 +++-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |   2 +
 8 files changed, 116 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8fd9fb6efba5..1837c01d44d0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2058,8 +2058,9 @@ struct drm_i915_private {
 		void (*resume)(struct drm_i915_private *);
 		void (*cleanup_engine)(struct intel_engine_cs *engine);
 
-		struct list_head timelines;
 		struct i915_gem_timeline global_timeline;
+		struct list_head timelines;
+		struct list_head rings;
 		u32 active_requests;
 		u32 request_serial;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 795ca83aed7a..906e2395c245 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5600,6 +5600,7 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 		goto err_dependencies;
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
+	INIT_LIST_HEAD(&dev_priv->gt.rings);
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
 	err = i915_gem_timeline_init__global(dev_priv);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index f3d04f0ab21c..0a117bf9e455 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -298,6 +298,7 @@ void i915_gem_retire_noop(struct i915_gem_active *active,
 
 static void advance_ring(struct i915_request *request)
 {
+	struct intel_ring *ring = request->ring;
 	unsigned int tail;
 
 	/*
@@ -309,7 +310,8 @@ static void advance_ring(struct i915_request *request)
 	 * Note this requires that we are always called in request
 	 * completion order.
 	 */
-	if (list_is_last(&request->ring_link, &request->ring->request_list)) {
+	GEM_BUG_ON(!list_is_first(&request->ring_link, &ring->request_list));
+	if (list_is_last(&request->ring_link, &ring->request_list)) {
 		/*
 		 * We may race here with execlists resubmitting this request
 		 * as we retire it. The resubmission will move the ring->tail
@@ -322,9 +324,9 @@ static void advance_ring(struct i915_request *request)
 	} else {
 		tail = request->postfix;
 	}
-	list_del(&request->ring_link);
+	list_del_init(&request->ring_link);
 
-	request->ring->head = tail;
+	ring->head = tail;
 }
 
 static void free_capture_list(struct i915_request *request)
@@ -340,16 +342,68 @@ static void free_capture_list(struct i915_request *request)
 	}
 }
 
-static void i915_request_retire(struct i915_request *request)
+static void __request_retire__engine(struct i915_request *request)
 {
 	struct intel_engine_cs *engine = request->engine;
+
+	local_irq_disable();
+
+	spin_lock(&engine->timeline->lock);
+	GEM_BUG_ON(!list_is_first(&request->link, &engine->timeline->requests));
+	list_del_init(&request->link);
+	spin_unlock(&engine->timeline->lock);
+
+	spin_lock(&request->lock);
+	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags))
+		dma_fence_signal_locked(&request->fence);
+	if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
+		intel_engine_cancel_signaling(request);
+	if (request->waitboost) {
+		GEM_BUG_ON(!atomic_read(&request->i915->gt_pm.rps.num_waiters));
+		atomic_dec(&request->i915->gt_pm.rps.num_waiters);
+	}
+	spin_unlock(&request->lock);
+
+	local_irq_enable();
+
+	/*
+	 * The backing object for the context is done after switching to the
+	 * *next* context. Therefore we cannot retire the previous context until
+	 * the next context has already started running. However, since we
+	 * cannot take the required locks at i915_request_submit() we
+	 * defer the unpinning of the active context to now, retirement of
+	 * the subsequent request.
+	 */
+	if (engine->last_retired_context)
+		engine->context_unpin(engine, engine->last_retired_context);
+	engine->last_retired_context = request->ctx;
+}
+
+static void __retire_engine_upto(struct intel_engine_cs *engine,
+				 struct i915_request *rq)
+{
+	struct i915_request *tmp;
+
+	if (list_empty(&rq->link))
+		return;
+
+	do {
+		tmp = list_first_entry(&engine->timeline->requests,
+				       typeof(*tmp), link);
+
+		__request_retire__engine(tmp);
+	} while (tmp != rq);
+}
+
+static void i915_request_retire(struct i915_request *request)
+{
 	struct i915_gem_active *active, *next;
 
 	GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n",
-		  engine->name,
+		  request->engine->name,
 		  request->fence.context, request->fence.seqno,
 		  request->global_seqno,
-		  intel_engine_get_seqno(engine));
+		  intel_engine_get_seqno(request->engine));
 
 	lockdep_assert_held(&request->i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915_sw_fence_signaled(&request->submit));
@@ -358,12 +412,7 @@ static void i915_request_retire(struct i915_request *request)
 
 	trace_i915_request_retire(request);
 
-	spin_lock_irq(&engine->timeline->lock);
-	list_del_init(&request->link);
-	spin_unlock_irq(&engine->timeline->lock);
-
 	advance_ring(request);
-
 	free_capture_list(request);
 
 	/*
@@ -400,49 +449,30 @@ static void i915_request_retire(struct i915_request *request)
 	/* Retirement decays the ban score as it is a sign of ctx progress */
 	atomic_dec_if_positive(&request->ctx->ban_score);
 
-	/*
-	 * The backing object for the context is done after switching to the
-	 * *next* context. Therefore we cannot retire the previous context until
-	 * the next context has already started running. However, since we
-	 * cannot take the required locks at i915_request_submit() we
-	 * defer the unpinning of the active context to now, retirement of
-	 * the subsequent request.
-	 */
-	if (engine->last_retired_context)
-		engine->context_unpin(engine, engine->last_retired_context);
-	engine->last_retired_context = request->ctx;
-
-	spin_lock_irq(&request->lock);
-	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags))
-		dma_fence_signal_locked(&request->fence);
-	if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
-		intel_engine_cancel_signaling(request);
-	if (request->waitboost) {
-		GEM_BUG_ON(!atomic_read(&request->i915->gt_pm.rps.num_waiters));
-		atomic_dec(&request->i915->gt_pm.rps.num_waiters);
-	}
-	spin_unlock_irq(&request->lock);
+	__retire_engine_upto(request->engine, request);
 
 	unreserve_gt(request->i915);
 
 	i915_sched_node_fini(request->i915, &request->sched);
+
+	i915_gem_context_put(request->ctx);
 	i915_request_put(request);
 }
 
 void i915_request_retire_upto(struct i915_request *rq)
 {
-	struct intel_engine_cs *engine = rq->engine;
+	struct intel_ring *ring = rq->ring;
 	struct i915_request *tmp;
 
 	lockdep_assert_held(&rq->i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915_request_completed(rq));
 
-	if (list_empty(&rq->link))
+	if (list_empty(&rq->ring_link))
 		return;
 
 	do {
-		tmp = list_first_entry(&engine->timeline->requests,
-				       typeof(*tmp), link);
+		tmp = list_first_entry(&ring->request_list,
+				       typeof(*tmp), ring_link);
 
 		i915_request_retire(tmp);
 	} while (tmp != rq);
@@ -651,9 +681,9 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 	if (ret)
 		goto err_unreserve;
 
-	/* Move the oldest request to the slab-cache (if not in use!) */
-	rq = list_first_entry_or_null(&engine->timeline->requests,
-				      typeof(*rq), link);
+	/* Move our oldest request to the slab-cache (if not in use!) */
+	rq = list_first_entry_or_null(&ring->request_list,
+				      typeof(*rq), ring_link);
 	if (rq && i915_request_completed(rq))
 		i915_request_retire(rq);
 
@@ -733,7 +763,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 	INIT_LIST_HEAD(&rq->active_list);
 	rq->i915 = i915;
 	rq->engine = engine;
-	rq->ctx = ctx;
+	rq->ctx = i915_gem_context_get(ctx);
 	rq->ring = ring;
 
 	/* No zalloc, must clear what we need by hand */
@@ -777,6 +807,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 
 err_unwind:
 	rq->ring->emit = rq->head;
+	i915_gem_context_put(ctx);
 
 	/* Make sure we didn't add ourselves to external state before freeing */
 	GEM_BUG_ON(!list_empty(&rq->active_list));
@@ -1357,38 +1388,30 @@ long i915_request_wait(struct i915_request *rq,
 	return timeout;
 }
 
-static void engine_retire_requests(struct intel_engine_cs *engine)
+static void ring_retire_requests(struct intel_ring *ring)
 {
 	struct i915_request *request, *next;
-	u32 seqno = intel_engine_get_seqno(engine);
-	LIST_HEAD(retire);
 
-	spin_lock_irq(&engine->timeline->lock);
 	list_for_each_entry_safe(request, next,
-				 &engine->timeline->requests, link) {
-		if (!i915_seqno_passed(seqno, request->global_seqno))
+				 &ring->request_list, ring_link) {
+		if (!i915_request_completed(request))
 			break;
 
-		list_move_tail(&request->link, &retire);
-	}
-	spin_unlock_irq(&engine->timeline->lock);
-
-	list_for_each_entry_safe(request, next, &retire, link)
 		i915_request_retire(request);
+	}
 }
 
 void i915_retire_requests(struct drm_i915_private *i915)
 {
-	struct intel_engine_cs *engine;
-	enum intel_engine_id id;
+	struct intel_ring *ring, *next;
 
 	lockdep_assert_held(&i915->drm.struct_mutex);
 
 	if (!i915->gt.active_requests)
 		return;
 
-	for_each_engine(engine, i915, id)
-		engine_retire_requests(engine);
+	list_for_each_entry_safe(ring, next, &i915->gt.rings, link)
+		ring_retire_requests(ring);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h
index 0695717522ea..00165ad55fb3 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -120,6 +120,12 @@ static inline u64 ptr_to_u64(const void *ptr)
 
 #include <linux/list.h>
 
+static inline int list_is_first(const struct list_head *list,
+				const struct list_head *head)
+{
+	return head->next == list;
+}
+
 static inline void __list_del_many(struct list_head *head,
 				   struct list_head *first)
 {
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index c68ac605b8a9..75dca28782ee 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1065,7 +1065,6 @@ int intel_ring_pin(struct intel_ring *ring,
 
 void intel_ring_reset(struct intel_ring *ring, u32 tail)
 {
-	GEM_BUG_ON(!list_empty(&ring->request_list));
 	ring->tail = tail;
 	ring->head = tail;
 	ring->emit = tail;
@@ -1124,6 +1123,7 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
 
 	GEM_BUG_ON(!is_power_of_2(size));
 	GEM_BUG_ON(RING_CTL_SIZE(size) & ~RING_NR_PAGES);
+	lockdep_assert_held(&engine->i915->drm.struct_mutex);
 
 	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
 	if (!ring)
@@ -1149,6 +1149,8 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
 	}
 	ring->vma = vma;
 
+	list_add(&ring->link, &engine->i915->gt.rings);
+
 	return ring;
 }
 
@@ -1160,6 +1162,8 @@ intel_ring_free(struct intel_ring *ring)
 	i915_vma_close(ring->vma);
 	__i915_gem_object_release_unless_active(obj);
 
+	list_del(&ring->link);
+
 	kfree(ring);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index c5e27905b0e1..d816f8dea245 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -129,6 +129,7 @@ struct intel_ring {
 	void *vaddr;
 
 	struct list_head request_list;
+	struct list_head link;
 
 	u32 head;
 	u32 tail;
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 78a89efa1119..a0bc324edadd 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -140,9 +140,18 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	INIT_LIST_HEAD(&ring->request_list);
 	intel_ring_update_space(ring);
 
+	list_add(&ring->link, &engine->i915->gt.rings);
+
 	return ring;
 }
 
+static void mock_ring_free(struct intel_ring *ring)
+{
+	list_del(&ring->link);
+
+	kfree(ring);
+}
+
 struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 				    const char *name,
 				    int id)
@@ -155,12 +164,6 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 	if (!engine)
 		return NULL;
 
-	engine->base.buffer = mock_ring(&engine->base);
-	if (!engine->base.buffer) {
-		kfree(engine);
-		return NULL;
-	}
-
 	/* minimal engine setup for requests */
 	engine->base.i915 = i915;
 	snprintf(engine->base.name, sizeof(engine->base.name), "%s", name);
@@ -185,7 +188,16 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 	timer_setup(&engine->hw_delay, hw_delay_complete, 0);
 	INIT_LIST_HEAD(&engine->hw_queue);
 
+	engine->base.buffer = mock_ring(&engine->base);
+	if (!engine->base.buffer)
+		goto err_breadcrumbs;
+
 	return &engine->base;
+
+err_breadcrumbs:
+	intel_engine_fini_breadcrumbs(&engine->base);
+	kfree(engine);
+	return NULL;
 }
 
 void mock_engine_flush(struct intel_engine_cs *engine)
@@ -219,8 +231,9 @@ void mock_engine_free(struct intel_engine_cs *engine)
 	if (engine->last_retired_context)
 		engine->context_unpin(engine, engine->last_retired_context);
 
+	mock_ring_free(engine->buffer);
+
 	intel_engine_fini_breadcrumbs(engine);
 
-	kfree(engine->buffer);
 	kfree(engine);
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index e6d4b882599a..ac4bacf8b5b9 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -44,6 +44,7 @@ void mock_device_flush(struct drm_i915_private *i915)
 		mock_engine_flush(engine);
 
 	i915_retire_requests(i915);
+	GEM_BUG_ON(i915->gt.active_requests);
 }
 
 static void mock_device_release(struct drm_device *dev)
@@ -224,6 +225,7 @@ struct drm_i915_private *mock_gem_device(void)
 		goto err_dependencies;
 
 	mutex_lock(&i915->drm.struct_mutex);
+	INIT_LIST_HEAD(&i915->gt.rings);
 	INIT_LIST_HEAD(&i915->gt.timelines);
 	err = i915_gem_timeline_init__global(i915);
 	if (err) {
-- 
2.17.0

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

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

* [PATCH v2 3/6] drm/i915: Only track live rings for retiring
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 2/6] drm/i915: Retire requests along rings Chris Wilson
@ 2018-04-23 18:08 ` Chris Wilson
  2018-04-24  9:37   ` Tvrtko Ursulin
  2018-04-23 18:08 ` [PATCH v2 4/6] drm/i915: Move timeline from GTT to ring Chris Wilson
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 18:08 UTC (permalink / raw)
  To: intel-gfx

We don't need to track every ring for its lifetime as they are managed
by the contexts/engines. What we do want to track are the live rings so
that we can sporadically clean up requests if userspace falls behind. We
can simply restrict the gt->rings list to being only gt->live_rings.

v2: s/live/active/ for consistency with gt.active_requests

Suggested-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h                  |  3 ++-
 drivers/gpu/drm/i915/i915_gem.c                  |  6 ++++--
 drivers/gpu/drm/i915/i915_request.c              | 10 ++++++++--
 drivers/gpu/drm/i915/intel_ringbuffer.c          |  4 ----
 drivers/gpu/drm/i915/intel_ringbuffer.h          |  2 +-
 drivers/gpu/drm/i915/selftests/mock_engine.c     |  4 ----
 drivers/gpu/drm/i915/selftests/mock_gem_device.c |  5 +++--
 7 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1837c01d44d0..54351cace362 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2060,7 +2060,8 @@ struct drm_i915_private {
 
 		struct i915_gem_timeline global_timeline;
 		struct list_head timelines;
-		struct list_head rings;
+
+		struct list_head active_rings;
 		u32 active_requests;
 		u32 request_serial;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 906e2395c245..56c79df5ebce 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -141,6 +141,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 {
 	lockdep_assert_held(&i915->drm.struct_mutex);
 	GEM_BUG_ON(i915->gt.active_requests);
+	GEM_BUG_ON(!list_empty(&i915->gt.active_rings));
 
 	if (!i915->gt.awake)
 		return I915_EPOCH_INVALID;
@@ -5599,9 +5600,10 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 	if (!dev_priv->priorities)
 		goto err_dependencies;
 
-	mutex_lock(&dev_priv->drm.struct_mutex);
-	INIT_LIST_HEAD(&dev_priv->gt.rings);
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
+	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
+
+	mutex_lock(&dev_priv->drm.struct_mutex);
 	err = i915_gem_timeline_init__global(dev_priv);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 	if (err)
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 0a117bf9e455..f13b7a1a0aa9 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -321,6 +321,7 @@ static void advance_ring(struct i915_request *request)
 		 * noops - they are safe to be replayed on a reset.
 		 */
 		tail = READ_ONCE(request->tail);
+		list_del(&ring->active_link);
 	} else {
 		tail = request->postfix;
 	}
@@ -1081,6 +1082,8 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
 	i915_gem_active_set(&timeline->last_request, request);
 
 	list_add_tail(&request->ring_link, &ring->request_list);
+	if (list_is_first(&request->ring_link, &ring->request_list))
+		list_add(&ring->active_link, &request->i915->gt.active_rings);
 	request->emitted_jiffies = jiffies;
 
 	/*
@@ -1403,14 +1406,17 @@ static void ring_retire_requests(struct intel_ring *ring)
 
 void i915_retire_requests(struct drm_i915_private *i915)
 {
-	struct intel_ring *ring, *next;
+	struct intel_ring *ring, *tmp;
 
 	lockdep_assert_held(&i915->drm.struct_mutex);
 
 	if (!i915->gt.active_requests)
 		return;
 
-	list_for_each_entry_safe(ring, next, &i915->gt.rings, link)
+	/* An outstanding request must be on a still active ring somewhere */
+	GEM_BUG_ON(list_empty(&i915->gt.active_rings));
+
+	list_for_each_entry_safe(ring, tmp, &i915->gt.active_rings, active_link)
 		ring_retire_requests(ring);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 75dca28782ee..3d02b2c779e7 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1149,8 +1149,6 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
 	}
 	ring->vma = vma;
 
-	list_add(&ring->link, &engine->i915->gt.rings);
-
 	return ring;
 }
 
@@ -1162,8 +1160,6 @@ intel_ring_free(struct intel_ring *ring)
 	i915_vma_close(ring->vma);
 	__i915_gem_object_release_unless_active(obj);
 
-	list_del(&ring->link);
-
 	kfree(ring);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index d816f8dea245..e8d17bcd9bee 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -129,7 +129,7 @@ struct intel_ring {
 	void *vaddr;
 
 	struct list_head request_list;
-	struct list_head link;
+	struct list_head active_link;
 
 	u32 head;
 	u32 tail;
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index a0bc324edadd..74a88913623f 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -140,15 +140,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	INIT_LIST_HEAD(&ring->request_list);
 	intel_ring_update_space(ring);
 
-	list_add(&ring->link, &engine->i915->gt.rings);
-
 	return ring;
 }
 
 static void mock_ring_free(struct intel_ring *ring)
 {
-	list_del(&ring->link);
-
 	kfree(ring);
 }
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index ac4bacf8b5b9..f22a2b35a283 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -224,9 +224,10 @@ struct drm_i915_private *mock_gem_device(void)
 	if (!i915->priorities)
 		goto err_dependencies;
 
-	mutex_lock(&i915->drm.struct_mutex);
-	INIT_LIST_HEAD(&i915->gt.rings);
 	INIT_LIST_HEAD(&i915->gt.timelines);
+	INIT_LIST_HEAD(&i915->gt.active_rings);
+
+	mutex_lock(&i915->drm.struct_mutex);
 	err = i915_gem_timeline_init__global(i915);
 	if (err) {
 		mutex_unlock(&i915->drm.struct_mutex);
-- 
2.17.0

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

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

* [PATCH v2 4/6] drm/i915: Move timeline from GTT to ring
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 2/6] drm/i915: Retire requests along rings Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 3/6] drm/i915: Only track live rings for retiring Chris Wilson
@ 2018-04-23 18:08 ` Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 5/6] drm/i915: Split i915_gem_timeline into individual timelines Chris Wilson
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 18:08 UTC (permalink / raw)
  To: intel-gfx

In the future, we want to move a request between engines. To achieve
this, we first realise that we have two timelines in effect here. The
first runs through the GTT is required for ordering vma access, which is
tracked currently by engine. The second is implied by sequential
execution of commands inside the ringbuffer. This timeline is one that
maps to userspace's expectations when submitting requests (i.e. given the
same context, batch A is executed before batch B). As the rings's
timelines map to userspace and the GTT timeline an implementation
detail, move the timeline from the GTT into the ring itself (per-context
in logical-ring-contexts/execlists, or a global per-engine timeline for
the shared ringbuffers in legacy submission.

The two timelines are still assumed to be equivalent at the moment (no
migrating requests between engines yet) and so we can simply move from
one to the other without adding extra ordering.

v2: Reinforce that one isn't allowed to mix the engine execution
timeline with the client timeline from userspace (on the ring).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               | 13 +----
 drivers/gpu/drm/i915/i915_gem.c               |  9 ++--
 drivers/gpu/drm/i915/i915_gem_context.c       | 15 +++++-
 drivers/gpu/drm/i915/i915_gem_context.h       |  2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c           |  3 --
 drivers/gpu/drm/i915/i915_gem_gtt.h           |  1 -
 drivers/gpu/drm/i915/i915_gem_timeline.c      | 54 +++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_timeline.h      |  4 ++
 drivers/gpu/drm/i915/i915_request.c           | 15 +++---
 drivers/gpu/drm/i915/intel_engine_cs.c        |  3 +-
 drivers/gpu/drm/i915/intel_lrc.c              |  2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c       | 10 +++-
 drivers/gpu/drm/i915/intel_ringbuffer.h       |  5 +-
 drivers/gpu/drm/i915/selftests/mock_engine.c  |  3 +-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  4 +-
 drivers/gpu/drm/i915/selftests/mock_gtt.c     |  1 -
 16 files changed, 102 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 54351cace362..b9bd8328f501 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2058,7 +2058,8 @@ struct drm_i915_private {
 		void (*resume)(struct drm_i915_private *);
 		void (*cleanup_engine)(struct intel_engine_cs *engine);
 
-		struct i915_gem_timeline global_timeline;
+		struct i915_gem_timeline execution_timeline;
+		struct i915_gem_timeline legacy_timeline;
 		struct list_head timelines;
 
 		struct list_head active_rings;
@@ -3234,16 +3235,6 @@ i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
 	return ctx;
 }
 
-static inline struct intel_timeline *
-i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
-				 struct intel_engine_cs *engine)
-{
-	struct i915_address_space *vm;
-
-	vm = ctx->ppgtt ? &ctx->ppgtt->base : &ctx->i915->ggtt.base;
-	return &vm->timeline.engine[engine->id];
-}
-
 int i915_perf_open_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file);
 int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 56c79df5ebce..d60f3bd4bc66 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3110,10 +3110,10 @@ static void engine_skip_context(struct i915_request *request)
 {
 	struct intel_engine_cs *engine = request->engine;
 	struct i915_gem_context *hung_ctx = request->ctx;
-	struct intel_timeline *timeline;
+	struct intel_timeline *timeline = request->timeline;
 	unsigned long flags;
 
-	timeline = i915_gem_context_lookup_timeline(hung_ctx, engine);
+	GEM_BUG_ON(timeline == engine->timeline);
 
 	spin_lock_irqsave(&engine->timeline->lock, flags);
 	spin_lock(&timeline->lock);
@@ -3782,7 +3782,7 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
 
 		ret = wait_for_engines(i915);
 	} else {
-		ret = wait_for_timeline(&i915->gt.global_timeline, flags);
+		ret = wait_for_timeline(&i915->gt.execution_timeline, flags);
 	}
 
 	return ret;
@@ -5652,7 +5652,8 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
 	WARN_ON(dev_priv->mm.object_count);
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
-	i915_gem_timeline_fini(&dev_priv->gt.global_timeline);
+	i915_gem_timeline_fini(&dev_priv->gt.legacy_timeline);
+	i915_gem_timeline_fini(&dev_priv->gt.execution_timeline);
 	WARN_ON(!list_empty(&dev_priv->gt.timelines));
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 74435affe23f..58b185abe652 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -122,6 +122,7 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
 	lockdep_assert_held(&ctx->i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
 
+	i915_gem_timeline_free(ctx->timeline);
 	i915_ppgtt_put(ctx->ppgtt);
 
 	for (i = 0; i < I915_NUM_ENGINES; i++) {
@@ -376,6 +377,18 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
 		ctx->desc_template = default_desc_template(dev_priv, ppgtt);
 	}
 
+	if (HAS_EXECLISTS(dev_priv)) {
+		struct i915_gem_timeline *timeline;
+
+		timeline = i915_gem_timeline_create(dev_priv, ctx->name);
+		if (IS_ERR(timeline)) {
+			__destroy_hw_context(ctx, file_priv);
+			return ERR_CAST(timeline);
+		}
+
+		ctx->timeline = timeline;
+	}
+
 	trace_i915_context_create(ctx);
 
 	return ctx;
@@ -584,7 +597,7 @@ static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
 	list_for_each_entry(timeline, &engine->i915->gt.timelines, link) {
 		struct intel_timeline *tl;
 
-		if (timeline == &engine->i915->gt.global_timeline)
+		if (timeline == &engine->i915->gt.execution_timeline)
 			continue;
 
 		tl = &timeline->engine[engine->id];
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index b12a8a8c5af9..140edcb424df 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -58,6 +58,8 @@ struct i915_gem_context {
 	/** file_priv: owning file descriptor */
 	struct drm_i915_file_private *file_priv;
 
+	struct i915_gem_timeline *timeline;
+
 	/**
 	 * @ppgtt: unique address space (GTT)
 	 *
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 21d72f695adb..e9d828324f67 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2111,8 +2111,6 @@ static void i915_address_space_init(struct i915_address_space *vm,
 				    struct drm_i915_private *dev_priv,
 				    const char *name)
 {
-	i915_gem_timeline_init(dev_priv, &vm->timeline, name);
-
 	drm_mm_init(&vm->mm, 0, vm->total);
 	vm->mm.head_node.color = I915_COLOR_UNEVICTABLE;
 
@@ -2129,7 +2127,6 @@ static void i915_address_space_fini(struct i915_address_space *vm)
 	if (pagevec_count(&vm->free_pages))
 		vm_free_pages_release(vm, true);
 
-	i915_gem_timeline_fini(&vm->timeline);
 	drm_mm_takedown(&vm->mm);
 	list_del(&vm->global_link);
 }
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 6efc017e8bb3..98107925de48 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -257,7 +257,6 @@ struct i915_pml4 {
 
 struct i915_address_space {
 	struct drm_mm mm;
-	struct i915_gem_timeline timeline;
 	struct drm_i915_private *i915;
 	struct device *dma;
 	/* Every address space belongs to a struct file - except for the global
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index e9fd87604067..24f4068cc137 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -95,12 +95,28 @@ int i915_gem_timeline_init(struct drm_i915_private *i915,
 
 int i915_gem_timeline_init__global(struct drm_i915_private *i915)
 {
-	static struct lock_class_key class;
+	static struct lock_class_key class1, class2;
+	int err;
+
+	err = __i915_gem_timeline_init(i915,
+				       &i915->gt.execution_timeline,
+				       "[execution]", &class1,
+				       "i915_execution_timeline");
+	if (err)
+		return err;
+
+	err = __i915_gem_timeline_init(i915,
+				       &i915->gt.legacy_timeline,
+				       "[global]", &class2,
+				       "i915_global_timeline");
+	if (err)
+		goto err_exec_timeline;
+
+	return 0;
 
-	return __i915_gem_timeline_init(i915,
-					&i915->gt.global_timeline,
-					"[execution]",
-					&class, "&global_timeline->lock");
+err_exec_timeline:
+	i915_gem_timeline_fini(&i915->gt.execution_timeline);
+	return err;
 }
 
 /**
@@ -148,6 +164,34 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
 	kfree(timeline->name);
 }
 
+struct i915_gem_timeline *
+i915_gem_timeline_create(struct drm_i915_private *i915, const char *name)
+{
+	struct i915_gem_timeline *timeline;
+	int err;
+
+	timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
+	if (!timeline)
+		return ERR_PTR(-ENOMEM);
+
+	err = i915_gem_timeline_init(i915, timeline, name);
+	if (err) {
+		kfree(timeline);
+		return ERR_PTR(err);
+	}
+
+	return timeline;
+}
+
+void i915_gem_timeline_free(struct i915_gem_timeline *timeline)
+{
+	if (!timeline)
+		return;
+
+	i915_gem_timeline_fini(timeline);
+	kfree(timeline);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/mock_timeline.c"
 #include "selftests/i915_gem_timeline.c"
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 6e82119e2cd8..780ed465c4fc 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -90,6 +90,10 @@ int i915_gem_timeline_init__global(struct drm_i915_private *i915);
 void i915_gem_timelines_park(struct drm_i915_private *i915);
 void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
 
+struct i915_gem_timeline *
+i915_gem_timeline_create(struct drm_i915_private *i915, const char *name);
+void i915_gem_timeline_free(struct i915_gem_timeline *timeline);
+
 static inline int __intel_timeline_sync_set(struct intel_timeline *tl,
 					    u64 context, u32 seqno)
 {
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index f13b7a1a0aa9..1682daf772e6 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -745,8 +745,13 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 		}
 	}
 
-	rq->timeline = i915_gem_context_lookup_timeline(ctx, engine);
-	GEM_BUG_ON(rq->timeline == engine->timeline);
+	INIT_LIST_HEAD(&rq->active_list);
+	rq->i915 = i915;
+	rq->engine = engine;
+	rq->ctx = i915_gem_context_get(ctx);
+	rq->ring = ring;
+	rq->timeline = ring->timeline;
+	GEM_BUG_ON(rq->timeline == &engine->timeline);
 
 	spin_lock_init(&rq->lock);
 	dma_fence_init(&rq->fence,
@@ -761,12 +766,6 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
 
 	i915_sched_node_init(&rq->sched);
 
-	INIT_LIST_HEAD(&rq->active_list);
-	rq->i915 = i915;
-	rq->engine = engine;
-	rq->ctx = i915_gem_context_get(ctx);
-	rq->ring = ring;
-
 	/* No zalloc, must clear what we need by hand */
 	rq->global_seqno = 0;
 	rq->signaling.wait.seqno = 0;
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index a55a849b81b6..d44a8eb83379 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -453,7 +453,8 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
 
 static void intel_engine_init_timeline(struct intel_engine_cs *engine)
 {
-	engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id];
+	engine->timeline =
+		&engine->i915->gt.execution_timeline.engine[engine->id];
 }
 
 static void intel_engine_init_batch_pool(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 029901a8fa38..fd3539034665 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2584,7 +2584,7 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 		goto error_deref_obj;
 	}
 
-	ring = intel_engine_create_ring(engine, ctx->ring_size);
+	ring = intel_engine_create_ring(engine, ctx->timeline, ctx->ring_size);
 	if (IS_ERR(ring)) {
 		ret = PTR_ERR(ring);
 		goto error_deref_obj;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3d02b2c779e7..47009695b378 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1116,13 +1116,16 @@ intel_ring_create_vma(struct drm_i915_private *dev_priv, int size)
 }
 
 struct intel_ring *
-intel_engine_create_ring(struct intel_engine_cs *engine, int size)
+intel_engine_create_ring(struct intel_engine_cs *engine,
+			 struct i915_gem_timeline *timeline,
+			 int size)
 {
 	struct intel_ring *ring;
 	struct i915_vma *vma;
 
 	GEM_BUG_ON(!is_power_of_2(size));
 	GEM_BUG_ON(RING_CTL_SIZE(size) & ~RING_NR_PAGES);
+	GEM_BUG_ON(timeline == &engine->timeline);
 	lockdep_assert_held(&engine->i915->drm.struct_mutex);
 
 	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
@@ -1130,6 +1133,7 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
 		return ERR_PTR(-ENOMEM);
 
 	INIT_LIST_HEAD(&ring->request_list);
+	ring->timeline = &timeline->engine[engine->id];
 
 	ring->size = size;
 	/* Workaround an erratum on the i830 which causes a hang if
@@ -1326,7 +1330,9 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
 	if (err)
 		goto err;
 
-	ring = intel_engine_create_ring(engine, 32 * PAGE_SIZE);
+	ring = intel_engine_create_ring(engine,
+					&engine->i915->gt.legacy_timeline,
+					32 * PAGE_SIZE);
 	if (IS_ERR(ring)) {
 		err = PTR_ERR(ring);
 		goto err;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index e8d17bcd9bee..b3c3f8f47f38 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -128,6 +128,7 @@ struct intel_ring {
 	struct i915_vma *vma;
 	void *vaddr;
 
+	struct intel_timeline *timeline;
 	struct list_head request_list;
 	struct list_head active_link;
 
@@ -767,7 +768,9 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 #define CNL_HWS_CSB_WRITE_INDEX		0x2f
 
 struct intel_ring *
-intel_engine_create_ring(struct intel_engine_cs *engine, int size);
+intel_engine_create_ring(struct intel_engine_cs *engine,
+			 struct i915_gem_timeline *timeline,
+			 int size);
 int intel_ring_pin(struct intel_ring *ring,
 		   struct drm_i915_private *i915,
 		   unsigned int offset_bias);
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 74a88913623f..6a10cb734c35 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -173,8 +173,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 	engine->base.emit_breadcrumb = mock_emit_breadcrumb;
 	engine->base.submit_request = mock_submit_request;
 
-	engine->base.timeline =
-		&i915->gt.global_timeline.engine[engine->base.id];
+	intel_engine_init_timeline(&engine->base);
 
 	intel_engine_init_breadcrumbs(&engine->base);
 	engine->base.breadcrumbs.mock = true; /* prevent touching HW for irqs */
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index f22a2b35a283..f11c83e8ff32 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -73,7 +73,9 @@ static void mock_device_release(struct drm_device *dev)
 
 	mutex_lock(&i915->drm.struct_mutex);
 	mock_fini_ggtt(i915);
-	i915_gem_timeline_fini(&i915->gt.global_timeline);
+	i915_gem_timeline_fini(&i915->gt.legacy_timeline);
+	i915_gem_timeline_fini(&i915->gt.execution_timeline);
+	WARN_ON(!list_empty(&i915->gt.timelines));
 	mutex_unlock(&i915->drm.struct_mutex);
 
 	destroy_workqueue(i915->wq);
diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c
index e96873f96116..36c112088940 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gtt.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c
@@ -76,7 +76,6 @@ mock_ppgtt(struct drm_i915_private *i915,
 
 	INIT_LIST_HEAD(&ppgtt->base.global_link);
 	drm_mm_init(&ppgtt->base.mm, 0, ppgtt->base.total);
-	i915_gem_timeline_init(i915, &ppgtt->base.timeline, name);
 
 	ppgtt->base.clear_range = nop_clear_range;
 	ppgtt->base.insert_page = mock_insert_page;
-- 
2.17.0

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

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

* [PATCH v2 5/6] drm/i915: Split i915_gem_timeline into individual timelines
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (2 preceding siblings ...)
  2018-04-23 18:08 ` [PATCH v2 4/6] drm/i915: Move timeline from GTT to ring Chris Wilson
@ 2018-04-23 18:08 ` Chris Wilson
  2018-04-23 23:11   ` [PATCH] " Chris Wilson
  2018-04-23 18:08 ` [PATCH v2 6/6] drm/i915: Lazily unbind vma on close Chris Wilson
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 18:08 UTC (permalink / raw)
  To: intel-gfx

We need to move to a more flexible timeline that doesn't assume one
fence context per engine, and so allow for a single timeline to be used
across a combination of engines. This means that preallocating a fence
context per engine is now a hindrance, and so we want to introduce the
singular timeline. From the code perspective, this has the notable
advantage of clearing up a lot of mirky semantics and some clumsy
pointer chasing.

By splitting the timeline up into a single entity rather than an array
of per-engine timelines, we can realise the goal of the previous patch
of tracking the timeline alongside the ring.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   2 +-
 drivers/gpu/drm/i915/i915_drv.h               |   4 +-
 drivers/gpu/drm/i915/i915_gem.c               | 118 +++++------
 drivers/gpu/drm/i915/i915_gem_context.c       |  49 ++---
 drivers/gpu/drm/i915/i915_gem_context.h       |   2 -
 drivers/gpu/drm/i915/i915_gem_gtt.h           |   3 +-
 drivers/gpu/drm/i915/i915_gem_timeline.c      | 198 ------------------
 drivers/gpu/drm/i915/i915_gpu_error.c         |   4 +-
 drivers/gpu/drm/i915/i915_perf.c              |  10 +-
 drivers/gpu/drm/i915/i915_request.c           |  66 +++---
 drivers/gpu/drm/i915/i915_request.h           |   3 +-
 drivers/gpu/drm/i915/i915_timeline.c          | 105 ++++++++++
 .../{i915_gem_timeline.h => i915_timeline.h}  |  67 +++---
 drivers/gpu/drm/i915/intel_engine_cs.c        |  27 ++-
 drivers/gpu/drm/i915/intel_guc_submission.c   |   4 +-
 drivers/gpu/drm/i915/intel_lrc.c              |  48 +++--
 drivers/gpu/drm/i915/intel_ringbuffer.c       |  23 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h       |  11 +-
 .../{i915_gem_timeline.c => i915_timeline.c}  |  94 +++------
 drivers/gpu/drm/i915/selftests/mock_engine.c  |  32 ++-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  10 +-
 .../gpu/drm/i915/selftests/mock_timeline.c    |  45 ++--
 .../gpu/drm/i915/selftests/mock_timeline.h    |  28 +--
 23 files changed, 389 insertions(+), 564 deletions(-)
 delete mode 100644 drivers/gpu/drm/i915/i915_gem_timeline.c
 create mode 100644 drivers/gpu/drm/i915/i915_timeline.c
 rename drivers/gpu/drm/i915/{i915_gem_timeline.h => i915_timeline.h} (68%)
 rename drivers/gpu/drm/i915/selftests/{i915_gem_timeline.c => i915_timeline.c} (70%)

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9bee52a949a9..120db21fcd50 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -67,11 +67,11 @@ i915-y += i915_cmd_parser.o \
 	  i915_gem_shrinker.o \
 	  i915_gem_stolen.o \
 	  i915_gem_tiling.o \
-	  i915_gem_timeline.o \
 	  i915_gem_userptr.o \
 	  i915_gemfs.o \
 	  i915_query.o \
 	  i915_request.o \
+	  i915_timeline.o \
 	  i915_trace_points.o \
 	  i915_vma.o \
 	  intel_breadcrumbs.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b9bd8328f501..dab15b6abc3c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -72,10 +72,10 @@
 #include "i915_gem_fence_reg.h"
 #include "i915_gem_object.h"
 #include "i915_gem_gtt.h"
-#include "i915_gem_timeline.h"
 #include "i915_gpu_error.h"
 #include "i915_request.h"
 #include "i915_scheduler.h"
+#include "i915_timeline.h"
 #include "i915_vma.h"
 
 #include "intel_gvt.h"
@@ -2058,8 +2058,6 @@ struct drm_i915_private {
 		void (*resume)(struct drm_i915_private *);
 		void (*cleanup_engine)(struct intel_engine_cs *engine);
 
-		struct i915_gem_timeline execution_timeline;
-		struct i915_gem_timeline legacy_timeline;
 		struct list_head timelines;
 
 		struct list_head active_rings;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d60f3bd4bc66..d36778518cdf 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -162,7 +162,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 	synchronize_irq(i915->drm.irq);
 
 	intel_engines_park(i915);
-	i915_gem_timelines_park(i915);
+	i915_timelines_park(i915);
 
 	i915_pmu_gt_parked(i915);
 
@@ -2977,8 +2977,8 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
 	 * extra delay for a recent interrupt is pointless. Hence, we do
 	 * not need an engine->irq_seqno_barrier() before the seqno reads.
 	 */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
-	list_for_each_entry(request, &engine->timeline->requests, link) {
+	spin_lock_irqsave(&engine->timeline.lock, flags);
+	list_for_each_entry(request, &engine->timeline.requests, link) {
 		if (__i915_request_completed(request, request->global_seqno))
 			continue;
 
@@ -2989,7 +2989,7 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
 		active = request;
 		break;
 	}
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 
 	return active;
 }
@@ -3110,15 +3110,15 @@ static void engine_skip_context(struct i915_request *request)
 {
 	struct intel_engine_cs *engine = request->engine;
 	struct i915_gem_context *hung_ctx = request->ctx;
-	struct intel_timeline *timeline = request->timeline;
+	struct i915_timeline *timeline = request->timeline;
 	unsigned long flags;
 
-	GEM_BUG_ON(timeline == engine->timeline);
+	GEM_BUG_ON(timeline == &engine->timeline);
 
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 	spin_lock(&timeline->lock);
 
-	list_for_each_entry_continue(request, &engine->timeline->requests, link)
+	list_for_each_entry_continue(request, &engine->timeline.requests, link)
 		if (request->ctx == hung_ctx)
 			skip_request(request);
 
@@ -3126,7 +3126,7 @@ static void engine_skip_context(struct i915_request *request)
 		skip_request(request);
 
 	spin_unlock(&timeline->lock);
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 /* Returns the request if it was guilty of the hang */
@@ -3183,11 +3183,11 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
 			dma_fence_set_error(&request->fence, -EAGAIN);
 
 			/* Rewind the engine to replay the incomplete rq */
-			spin_lock_irq(&engine->timeline->lock);
+			spin_lock_irq(&engine->timeline.lock);
 			request = list_prev_entry(request, link);
-			if (&request->link == &engine->timeline->requests)
+			if (&request->link == &engine->timeline.requests)
 				request = NULL;
-			spin_unlock_irq(&engine->timeline->lock);
+			spin_unlock_irq(&engine->timeline.lock);
 		}
 	}
 
@@ -3300,10 +3300,10 @@ static void nop_complete_submit_request(struct i915_request *request)
 		  request->fence.context, request->fence.seqno);
 	dma_fence_set_error(&request->fence, -EIO);
 
-	spin_lock_irqsave(&request->engine->timeline->lock, flags);
+	spin_lock_irqsave(&request->engine->timeline.lock, flags);
 	__i915_request_submit(request);
 	intel_engine_init_global_seqno(request->engine, request->global_seqno);
-	spin_unlock_irqrestore(&request->engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&request->engine->timeline.lock, flags);
 }
 
 void i915_gem_set_wedged(struct drm_i915_private *i915)
@@ -3372,10 +3372,10 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
 		 * (lockless) lookup doesn't try and wait upon the request as we
 		 * reset it.
 		 */
-		spin_lock_irqsave(&engine->timeline->lock, flags);
+		spin_lock_irqsave(&engine->timeline.lock, flags);
 		intel_engine_init_global_seqno(engine,
 					       intel_engine_last_submit(engine));
-		spin_unlock_irqrestore(&engine->timeline->lock, flags);
+		spin_unlock_irqrestore(&engine->timeline.lock, flags);
 
 		i915_gem_reset_finish_engine(engine);
 	}
@@ -3387,8 +3387,7 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
 
 bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 {
-	struct i915_gem_timeline *tl;
-	int i;
+	struct i915_timeline *tl;
 
 	lockdep_assert_held(&i915->drm.struct_mutex);
 	if (!test_bit(I915_WEDGED, &i915->gpu_error.flags))
@@ -3407,29 +3406,27 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 	 * No more can be submitted until we reset the wedged bit.
 	 */
 	list_for_each_entry(tl, &i915->gt.timelines, link) {
-		for (i = 0; i < ARRAY_SIZE(tl->engine); i++) {
-			struct i915_request *rq;
+		struct i915_request *rq;
 
-			rq = i915_gem_active_peek(&tl->engine[i].last_request,
-						  &i915->drm.struct_mutex);
-			if (!rq)
-				continue;
+		rq = i915_gem_active_peek(&tl->last_request,
+					  &i915->drm.struct_mutex);
+		if (!rq)
+			continue;
 
-			/*
-			 * We can't use our normal waiter as we want to
-			 * avoid recursively trying to handle the current
-			 * reset. The basic dma_fence_default_wait() installs
-			 * a callback for dma_fence_signal(), which is
-			 * triggered by our nop handler (indirectly, the
-			 * callback enables the signaler thread which is
-			 * woken by the nop_submit_request() advancing the seqno
-			 * and when the seqno passes the fence, the signaler
-			 * then signals the fence waking us up).
-			 */
-			if (dma_fence_default_wait(&rq->fence, true,
-						   MAX_SCHEDULE_TIMEOUT) < 0)
-				return false;
-		}
+		/*
+		 * We can't use our normal waiter as we want to
+		 * avoid recursively trying to handle the current
+		 * reset. The basic dma_fence_default_wait() installs
+		 * a callback for dma_fence_signal(), which is
+		 * triggered by our nop handler (indirectly, the
+		 * callback enables the signaler thread which is
+		 * woken by the nop_submit_request() advancing the seqno
+		 * and when the seqno passes the fence, the signaler
+		 * then signals the fence waking us up).
+		 */
+		if (dma_fence_default_wait(&rq->fence, true,
+					   MAX_SCHEDULE_TIMEOUT) < 0)
+			return false;
 	}
 	i915_retire_requests(i915);
 	GEM_BUG_ON(i915->gt.active_requests);
@@ -3734,19 +3731,6 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	return ret;
 }
 
-static int wait_for_timeline(struct i915_gem_timeline *tl, unsigned int flags)
-{
-	int ret, i;
-
-	for (i = 0; i < ARRAY_SIZE(tl->engine); i++) {
-		ret = i915_gem_active_wait(&tl->engine[i].last_request, flags);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 static int wait_for_engines(struct drm_i915_private *i915)
 {
 	if (wait_for(intel_engines_are_idle(i915), I915_IDLE_ENGINES_TIMEOUT)) {
@@ -3769,12 +3753,12 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
 		return 0;
 
 	if (flags & I915_WAIT_LOCKED) {
-		struct i915_gem_timeline *tl;
+		struct i915_timeline *tl;
 
 		lockdep_assert_held(&i915->drm.struct_mutex);
 
 		list_for_each_entry(tl, &i915->gt.timelines, link) {
-			ret = wait_for_timeline(tl, flags);
+			ret = i915_gem_active_wait(&tl->last_request, flags);
 			if (ret)
 				return ret;
 		}
@@ -3782,7 +3766,16 @@ int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
 
 		ret = wait_for_engines(i915);
 	} else {
-		ret = wait_for_timeline(&i915->gt.execution_timeline, flags);
+		struct intel_engine_cs *engine;
+		enum intel_engine_id id;
+
+		for_each_engine(engine, i915, id) {
+			struct i915_timeline *tl = &engine->timeline;
+
+			ret = i915_gem_active_wait(&tl->last_request, flags);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return ret;
@@ -4954,7 +4947,7 @@ static void assert_kernel_context_is_current(struct drm_i915_private *i915)
 	enum intel_engine_id id;
 
 	for_each_engine(engine, i915, id) {
-		GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline->last_request));
+		GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline.last_request));
 		GEM_BUG_ON(engine->last_retired_context != kernel_context);
 	}
 }
@@ -5603,12 +5596,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
 	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
 
-	mutex_lock(&dev_priv->drm.struct_mutex);
-	err = i915_gem_timeline_init__global(dev_priv);
-	mutex_unlock(&dev_priv->drm.struct_mutex);
-	if (err)
-		goto err_priorities;
-
 	i915_gem_init__mm(dev_priv);
 
 	INIT_DELAYED_WORK(&dev_priv->gt.retire_work,
@@ -5628,8 +5615,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 
 	return 0;
 
-err_priorities:
-	kmem_cache_destroy(dev_priv->priorities);
 err_dependencies:
 	kmem_cache_destroy(dev_priv->dependencies);
 err_requests:
@@ -5650,12 +5635,7 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
 	GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
 	GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
 	WARN_ON(dev_priv->mm.object_count);
-
-	mutex_lock(&dev_priv->drm.struct_mutex);
-	i915_gem_timeline_fini(&dev_priv->gt.legacy_timeline);
-	i915_gem_timeline_fini(&dev_priv->gt.execution_timeline);
 	WARN_ON(!list_empty(&dev_priv->gt.timelines));
-	mutex_unlock(&dev_priv->drm.struct_mutex);
 
 	kmem_cache_destroy(dev_priv->priorities);
 	kmem_cache_destroy(dev_priv->dependencies);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 58b185abe652..027b7ddae1d3 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -122,7 +122,6 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
 	lockdep_assert_held(&ctx->i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
 
-	i915_gem_timeline_free(ctx->timeline);
 	i915_ppgtt_put(ctx->ppgtt);
 
 	for (i = 0; i < I915_NUM_ENGINES; i++) {
@@ -377,18 +376,6 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
 		ctx->desc_template = default_desc_template(dev_priv, ppgtt);
 	}
 
-	if (HAS_EXECLISTS(dev_priv)) {
-		struct i915_gem_timeline *timeline;
-
-		timeline = i915_gem_timeline_create(dev_priv, ctx->name);
-		if (IS_ERR(timeline)) {
-			__destroy_hw_context(ctx, file_priv);
-			return ERR_CAST(timeline);
-		}
-
-		ctx->timeline = timeline;
-	}
-
 	trace_i915_context_create(ctx);
 
 	return ctx;
@@ -590,21 +577,30 @@ void i915_gem_context_close(struct drm_file *file)
 	idr_destroy(&file_priv->context_idr);
 }
 
-static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
+static struct i915_request *
+last_timeline_request(struct i915_timeline *timeline,
+		      struct intel_engine_cs *engine)
 {
-	struct i915_gem_timeline *timeline;
+	struct i915_request *rq;
 
-	list_for_each_entry(timeline, &engine->i915->gt.timelines, link) {
-		struct intel_timeline *tl;
+	if (timeline == &engine->timeline)
+		return NULL;
 
-		if (timeline == &engine->i915->gt.execution_timeline)
-			continue;
+	rq = i915_gem_active_raw(&timeline->last_request,
+				 &engine->i915->drm.struct_mutex);
+	if (rq && rq->engine == engine)
+		return rq;
+
+	return NULL;
+}
 
-		tl = &timeline->engine[engine->id];
-		if (i915_gem_active_peek(&tl->last_request,
-					 &engine->i915->drm.struct_mutex))
+static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
+{
+	struct i915_timeline *timeline;
+
+	list_for_each_entry(timeline, &engine->i915->gt.timelines, link)
+		if (last_timeline_request(timeline, engine))
 			return false;
-	}
 
 	return intel_engine_has_kernel_context(engine);
 }
@@ -612,7 +608,7 @@ static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
 int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
-	struct i915_gem_timeline *timeline;
+	struct i915_timeline *timeline;
 	enum intel_engine_id id;
 
 	lockdep_assert_held(&dev_priv->drm.struct_mutex);
@@ -632,11 +628,8 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
 		/* Queue this switch after all other activity */
 		list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
 			struct i915_request *prev;
-			struct intel_timeline *tl;
 
-			tl = &timeline->engine[engine->id];
-			prev = i915_gem_active_raw(&tl->last_request,
-						   &dev_priv->drm.struct_mutex);
+			prev = last_timeline_request(timeline, engine);
 			if (prev)
 				i915_sw_fence_await_sw_fence_gfp(&rq->submit,
 								 &prev->submit,
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 140edcb424df..b12a8a8c5af9 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -58,8 +58,6 @@ struct i915_gem_context {
 	/** file_priv: owning file descriptor */
 	struct drm_i915_file_private *file_priv;
 
-	struct i915_gem_timeline *timeline;
-
 	/**
 	 * @ppgtt: unique address space (GTT)
 	 *
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 98107925de48..1db0dedb4059 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -38,10 +38,9 @@
 #include <linux/mm.h>
 #include <linux/pagevec.h>
 
-#include "i915_gem_timeline.h"
-
 #include "i915_request.h"
 #include "i915_selftest.h"
+#include "i915_timeline.h"
 
 #define I915_GTT_PAGE_SIZE_4K BIT(12)
 #define I915_GTT_PAGE_SIZE_64K BIT(16)
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
deleted file mode 100644
index 24f4068cc137..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright © 2016 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_drv.h"
-#include "i915_syncmap.h"
-
-static void __intel_timeline_init(struct intel_timeline *tl,
-				  struct i915_gem_timeline *parent,
-				  u64 context,
-				  struct lock_class_key *lockclass,
-				  const char *lockname)
-{
-	tl->fence_context = context;
-	tl->common = parent;
-	spin_lock_init(&tl->lock);
-	lockdep_set_class_and_name(&tl->lock, lockclass, lockname);
-	init_request_active(&tl->last_request, NULL);
-	INIT_LIST_HEAD(&tl->requests);
-	i915_syncmap_init(&tl->sync);
-}
-
-static void __intel_timeline_fini(struct intel_timeline *tl)
-{
-	GEM_BUG_ON(!list_empty(&tl->requests));
-
-	i915_syncmap_free(&tl->sync);
-}
-
-static int __i915_gem_timeline_init(struct drm_i915_private *i915,
-				    struct i915_gem_timeline *timeline,
-				    const char *name,
-				    struct lock_class_key *lockclass,
-				    const char *lockname)
-{
-	unsigned int i;
-	u64 fences;
-
-	lockdep_assert_held(&i915->drm.struct_mutex);
-
-	/*
-	 * Ideally we want a set of engines on a single leaf as we expect
-	 * to mostly be tracking synchronisation between engines. It is not
-	 * a huge issue if this is not the case, but we may want to mitigate
-	 * any page crossing penalties if they become an issue.
-	 */
-	BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
-
-	timeline->i915 = i915;
-	timeline->name = kstrdup(name ?: "[kernel]", GFP_KERNEL);
-	if (!timeline->name)
-		return -ENOMEM;
-
-	list_add(&timeline->link, &i915->gt.timelines);
-
-	/* Called during early_init before we know how many engines there are */
-	fences = dma_fence_context_alloc(ARRAY_SIZE(timeline->engine));
-	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
-		__intel_timeline_init(&timeline->engine[i],
-				      timeline, fences++,
-				      lockclass, lockname);
-
-	return 0;
-}
-
-int i915_gem_timeline_init(struct drm_i915_private *i915,
-			   struct i915_gem_timeline *timeline,
-			   const char *name)
-{
-	static struct lock_class_key class;
-
-	return __i915_gem_timeline_init(i915, timeline, name,
-					&class, "&timeline->lock");
-}
-
-int i915_gem_timeline_init__global(struct drm_i915_private *i915)
-{
-	static struct lock_class_key class1, class2;
-	int err;
-
-	err = __i915_gem_timeline_init(i915,
-				       &i915->gt.execution_timeline,
-				       "[execution]", &class1,
-				       "i915_execution_timeline");
-	if (err)
-		return err;
-
-	err = __i915_gem_timeline_init(i915,
-				       &i915->gt.legacy_timeline,
-				       "[global]", &class2,
-				       "i915_global_timeline");
-	if (err)
-		goto err_exec_timeline;
-
-	return 0;
-
-err_exec_timeline:
-	i915_gem_timeline_fini(&i915->gt.execution_timeline);
-	return err;
-}
-
-/**
- * i915_gem_timelines_park - called when the driver idles
- * @i915: the drm_i915_private device
- *
- * When the driver is completely idle, we know that all of our sync points
- * have been signaled and our tracking is then entirely redundant. Any request
- * to wait upon an older sync point will be completed instantly as we know
- * the fence is signaled and therefore we will not even look them up in the
- * sync point map.
- */
-void i915_gem_timelines_park(struct drm_i915_private *i915)
-{
-	struct i915_gem_timeline *timeline;
-	int i;
-
-	lockdep_assert_held(&i915->drm.struct_mutex);
-
-	list_for_each_entry(timeline, &i915->gt.timelines, link) {
-		for (i = 0; i < ARRAY_SIZE(timeline->engine); i++) {
-			struct intel_timeline *tl = &timeline->engine[i];
-
-			/*
-			 * All known fences are completed so we can scrap
-			 * the current sync point tracking and start afresh,
-			 * any attempt to wait upon a previous sync point
-			 * will be skipped as the fence was signaled.
-			 */
-			i915_syncmap_free(&tl->sync);
-		}
-	}
-}
-
-void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
-{
-	int i;
-
-	lockdep_assert_held(&timeline->i915->drm.struct_mutex);
-
-	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
-		__intel_timeline_fini(&timeline->engine[i]);
-
-	list_del(&timeline->link);
-	kfree(timeline->name);
-}
-
-struct i915_gem_timeline *
-i915_gem_timeline_create(struct drm_i915_private *i915, const char *name)
-{
-	struct i915_gem_timeline *timeline;
-	int err;
-
-	timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
-	if (!timeline)
-		return ERR_PTR(-ENOMEM);
-
-	err = i915_gem_timeline_init(i915, timeline, name);
-	if (err) {
-		kfree(timeline);
-		return ERR_PTR(err);
-	}
-
-	return timeline;
-}
-
-void i915_gem_timeline_free(struct i915_gem_timeline *timeline)
-{
-	if (!timeline)
-		return;
-
-	i915_gem_timeline_fini(timeline);
-	kfree(timeline);
-}
-
-#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
-#include "selftests/mock_timeline.c"
-#include "selftests/i915_gem_timeline.c"
-#endif
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 671ffa37614e..71bb8230cb97 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1299,7 +1299,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
 
 	count = 0;
 	request = first;
-	list_for_each_entry_from(request, &engine->timeline->requests, link)
+	list_for_each_entry_from(request, &engine->timeline.requests, link)
 		count++;
 	if (!count)
 		return;
@@ -1312,7 +1312,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
 
 	count = 0;
 	request = first;
-	list_for_each_entry_from(request, &engine->timeline->requests, link) {
+	list_for_each_entry_from(request, &engine->timeline.requests, link) {
 		if (count >= ee->num_requests) {
 			/*
 			 * If the ring request list was changed in
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index bfc906cd4e5e..5dcd76e27c68 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -1695,7 +1695,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
 						 const struct i915_oa_config *oa_config)
 {
 	struct intel_engine_cs *engine = dev_priv->engine[RCS];
-	struct i915_gem_timeline *timeline;
+	struct i915_timeline *timeline;
 	struct i915_request *rq;
 	int ret;
 
@@ -1716,15 +1716,11 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
 	/* Queue this switch after all other activity */
 	list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
 		struct i915_request *prev;
-		struct intel_timeline *tl;
 
-		tl = &timeline->engine[engine->id];
-		prev = i915_gem_active_raw(&tl->last_request,
+		prev = i915_gem_active_raw(&timeline->last_request,
 					   &dev_priv->drm.struct_mutex);
 		if (prev)
-			i915_sw_fence_await_sw_fence_gfp(&rq->submit,
-							 &prev->submit,
-							 GFP_KERNEL);
+			i915_request_await_dma_fence(rq, &prev->fence);
 	}
 
 	i915_request_add(rq);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 1682daf772e6..79a34c06922a 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -49,7 +49,7 @@ static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return "signaled";
 
-	return to_request(fence)->timeline->common->name;
+	return to_request(fence)->timeline->name;
 }
 
 static bool i915_fence_signaled(struct dma_fence *fence)
@@ -199,6 +199,7 @@ i915_sched_node_init(struct i915_sched_node *node)
 static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 {
 	struct intel_engine_cs *engine;
+	struct i915_timeline *timeline;
 	enum intel_engine_id id;
 	int ret;
 
@@ -213,16 +214,13 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 
 	/* If the seqno wraps around, we need to clear the breadcrumb rbtree */
 	for_each_engine(engine, i915, id) {
-		struct i915_gem_timeline *timeline;
-		struct intel_timeline *tl = engine->timeline;
-
 		GEM_TRACE("%s seqno %d (current %d) -> %d\n",
 			  engine->name,
-			  tl->seqno,
+			  engine->timeline.seqno,
 			  intel_engine_get_seqno(engine),
 			  seqno);
 
-		if (!i915_seqno_passed(seqno, tl->seqno)) {
+		if (!i915_seqno_passed(seqno, engine->timeline.seqno)) {
 			/* Flush any waiters before we reuse the seqno */
 			intel_engine_disarm_breadcrumbs(engine);
 			GEM_BUG_ON(!list_empty(&engine->breadcrumbs.signals));
@@ -230,18 +228,18 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 
 		/* Check we are idle before we fiddle with hw state! */
 		GEM_BUG_ON(!intel_engine_is_idle(engine));
-		GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
+		GEM_BUG_ON(i915_gem_active_isset(&engine->timeline.last_request));
 
 		/* Finally reset hw state */
 		intel_engine_init_global_seqno(engine, seqno);
-		tl->seqno = seqno;
-
-		list_for_each_entry(timeline, &i915->gt.timelines, link)
-			memset(timeline->engine[id].global_sync, 0,
-			       sizeof(timeline->engine[id].global_sync));
+		engine->timeline.seqno = seqno;
 	}
 
+	list_for_each_entry(timeline, &i915->gt.timelines, link)
+		memset(timeline->global_sync, 0, sizeof(timeline->global_sync));
+
 	i915->gt.request_serial = seqno;
+
 	return 0;
 }
 
@@ -349,10 +347,10 @@ static void __request_retire__engine(struct i915_request *request)
 
 	local_irq_disable();
 
-	spin_lock(&engine->timeline->lock);
-	GEM_BUG_ON(!list_is_first(&request->link, &engine->timeline->requests));
+	spin_lock(&engine->timeline.lock);
+	GEM_BUG_ON(!list_is_first(&request->link, &engine->timeline.requests));
 	list_del_init(&request->link);
-	spin_unlock(&engine->timeline->lock);
+	spin_unlock(&engine->timeline.lock);
 
 	spin_lock(&request->lock);
 	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags))
@@ -389,7 +387,7 @@ static void __retire_engine_upto(struct intel_engine_cs *engine,
 		return;
 
 	do {
-		tmp = list_first_entry(&engine->timeline->requests,
+		tmp = list_first_entry(&engine->timeline.requests,
 				       typeof(*tmp), link);
 
 		__request_retire__engine(tmp);
@@ -479,16 +477,16 @@ void i915_request_retire_upto(struct i915_request *rq)
 	} while (tmp != rq);
 }
 
-static u32 timeline_get_seqno(struct intel_timeline *tl)
+static u32 timeline_get_seqno(struct i915_timeline *tl)
 {
 	return ++tl->seqno;
 }
 
 static void move_to_timeline(struct i915_request *request,
-			     struct intel_timeline *timeline)
+			     struct i915_timeline *timeline)
 {
-	GEM_BUG_ON(request->timeline == request->engine->timeline);
-	lockdep_assert_held(&request->engine->timeline->lock);
+	GEM_BUG_ON(request->timeline == &request->engine->timeline);
+	lockdep_assert_held(&request->engine->timeline.lock);
 
 	spin_lock(&request->timeline->lock);
 	list_move_tail(&request->link, &timeline->requests);
@@ -503,15 +501,15 @@ void __i915_request_submit(struct i915_request *request)
 	GEM_TRACE("%s fence %llx:%d -> global=%d, current %d\n",
 		  engine->name,
 		  request->fence.context, request->fence.seqno,
-		  engine->timeline->seqno + 1,
+		  engine->timeline.seqno + 1,
 		  intel_engine_get_seqno(engine));
 
 	GEM_BUG_ON(!irqs_disabled());
-	lockdep_assert_held(&engine->timeline->lock);
+	lockdep_assert_held(&engine->timeline.lock);
 
 	GEM_BUG_ON(request->global_seqno);
 
-	seqno = timeline_get_seqno(engine->timeline);
+	seqno = timeline_get_seqno(&engine->timeline);
 	GEM_BUG_ON(!seqno);
 	GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno));
 
@@ -526,7 +524,7 @@ void __i915_request_submit(struct i915_request *request)
 				request->ring->vaddr + request->postfix);
 
 	/* Transfer from per-context onto the global per-engine timeline */
-	move_to_timeline(request, engine->timeline);
+	move_to_timeline(request, &engine->timeline);
 
 	trace_i915_request_execute(request);
 
@@ -539,11 +537,11 @@ void i915_request_submit(struct i915_request *request)
 	unsigned long flags;
 
 	/* Will be called from irq-context when using foreign fences. */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	__i915_request_submit(request);
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 void __i915_request_unsubmit(struct i915_request *request)
@@ -557,17 +555,17 @@ void __i915_request_unsubmit(struct i915_request *request)
 		  intel_engine_get_seqno(engine));
 
 	GEM_BUG_ON(!irqs_disabled());
-	lockdep_assert_held(&engine->timeline->lock);
+	lockdep_assert_held(&engine->timeline.lock);
 
 	/*
 	 * Only unwind in reverse order, required so that the per-context list
 	 * is kept in seqno/ring order.
 	 */
 	GEM_BUG_ON(!request->global_seqno);
-	GEM_BUG_ON(request->global_seqno != engine->timeline->seqno);
+	GEM_BUG_ON(request->global_seqno != engine->timeline.seqno);
 	GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine),
 				     request->global_seqno));
-	engine->timeline->seqno--;
+	engine->timeline.seqno--;
 
 	/* We may be recursing from the signal callback of another i915 fence */
 	spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
@@ -594,11 +592,11 @@ void i915_request_unsubmit(struct i915_request *request)
 	unsigned long flags;
 
 	/* Will be called from irq-context when using foreign fences. */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	__i915_request_unsubmit(request);
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 static int __i915_sw_fence_call
@@ -914,7 +912,7 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
 
 		/* Squash repeated waits to the same timelines */
 		if (fence->context != rq->i915->mm.unordered_timeline &&
-		    intel_timeline_sync_is_later(rq->timeline, fence))
+		    i915_timeline_sync_is_later(rq->timeline, fence))
 			continue;
 
 		if (dma_fence_is_i915(fence))
@@ -928,7 +926,7 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
 
 		/* Record the latest fence used against each timeline */
 		if (fence->context != rq->i915->mm.unordered_timeline)
-			intel_timeline_sync_set(rq->timeline, fence);
+			i915_timeline_sync_set(rq->timeline, fence);
 	} while (--nchild);
 
 	return 0;
@@ -1005,7 +1003,7 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
 {
 	struct intel_engine_cs *engine = request->engine;
 	struct intel_ring *ring = request->ring;
-	struct intel_timeline *timeline = request->timeline;
+	struct i915_timeline *timeline = request->timeline;
 	struct i915_request *prev;
 	u32 *cs;
 	int err;
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 8f31ca8272f8..eddbd4245cb3 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -37,6 +37,7 @@
 struct drm_file;
 struct drm_i915_gem_object;
 struct i915_request;
+struct i915_timeline;
 
 struct intel_wait {
 	struct rb_node node;
@@ -95,7 +96,7 @@ struct i915_request {
 	struct i915_gem_context *ctx;
 	struct intel_engine_cs *engine;
 	struct intel_ring *ring;
-	struct intel_timeline *timeline;
+	struct i915_timeline *timeline;
 	struct intel_signal_node signaling;
 
 	/*
diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c
new file mode 100644
index 000000000000..4667cc08c416
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_timeline.c
@@ -0,0 +1,105 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2016-2018 Intel Corporation
+ */
+
+#include "i915_drv.h"
+
+#include "i915_timeline.h"
+#include "i915_syncmap.h"
+
+void i915_timeline_init(struct drm_i915_private *i915,
+			struct i915_timeline *timeline,
+			const char *name)
+{
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	/*
+	 * Ideally we want a set of engines on a single leaf as we expect
+	 * to mostly be tracking synchronisation between engines. It is not
+	 * a huge issue if this is not the case, but we may want to mitigate
+	 * any page crossing penalties if they become an issue.
+	 */
+	BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
+
+	timeline->name = name;
+
+	list_add(&timeline->link, &i915->gt.timelines);
+
+	/* Called during early_init before we know how many engines there are */
+
+	timeline->fence_context = dma_fence_context_alloc(1);
+
+	spin_lock_init(&timeline->lock);
+
+	init_request_active(&timeline->last_request, NULL);
+	INIT_LIST_HEAD(&timeline->requests);
+
+	i915_syncmap_init(&timeline->sync);
+}
+
+/**
+ * i915_timelines_park - called when the driver idles
+ * @i915: the drm_i915_private device
+ *
+ * When the driver is completely idle, we know that all of our sync points
+ * have been signaled and our tracking is then entirely redundant. Any request
+ * to wait upon an older sync point will be completed instantly as we know
+ * the fence is signaled and therefore we will not even look them up in the
+ * sync point map.
+ */
+void i915_timelines_park(struct drm_i915_private *i915)
+{
+	struct i915_timeline *timeline;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	list_for_each_entry(timeline, &i915->gt.timelines, link) {
+		/*
+		 * All known fences are completed so we can scrap
+		 * the current sync point tracking and start afresh,
+		 * any attempt to wait upon a previous sync point
+		 * will be skipped as the fence was signaled.
+		 */
+		i915_syncmap_free(&timeline->sync);
+	}
+}
+
+void i915_timeline_fini(struct i915_timeline *timeline)
+{
+	GEM_BUG_ON(!list_empty(&timeline->requests));
+
+	i915_syncmap_free(&timeline->sync);
+
+	list_del(&timeline->link);
+}
+
+struct i915_timeline *
+i915_timeline_create(struct drm_i915_private *i915, const char *name)
+{
+	struct i915_timeline *timeline;
+
+	timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
+	if (!timeline)
+		return ERR_PTR(-ENOMEM);
+
+	i915_timeline_init(i915, timeline, name);
+	kref_init(&timeline->kref);
+
+	return timeline;
+}
+
+void __i915_timeline_free(struct kref *kref)
+{
+	struct i915_timeline *timeline =
+		container_of(kref, typeof(*timeline), kref);
+
+	i915_timeline_fini(timeline);
+	kfree(timeline);
+}
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_timeline.c"
+#include "selftests/i915_timeline.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h
similarity index 68%
rename from drivers/gpu/drm/i915/i915_gem_timeline.h
rename to drivers/gpu/drm/i915/i915_timeline.h
index 780ed465c4fc..dc2a4632faa7 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_timeline.h
@@ -22,18 +22,17 @@
  *
  */
 
-#ifndef I915_GEM_TIMELINE_H
-#define I915_GEM_TIMELINE_H
+#ifndef I915_TIMELINE_H
+#define I915_TIMELINE_H
 
 #include <linux/list.h>
+#include <linux/kref.h>
 
 #include "i915_request.h"
 #include "i915_syncmap.h"
 #include "i915_utils.h"
 
-struct i915_gem_timeline;
-
-struct intel_timeline {
+struct i915_timeline {
 	u64 fence_context;
 	u32 seqno;
 
@@ -71,51 +70,57 @@ struct intel_timeline {
 	 */
 	u32 global_sync[I915_NUM_ENGINES];
 
-	struct i915_gem_timeline *common;
-};
-
-struct i915_gem_timeline {
 	struct list_head link;
-
-	struct drm_i915_private *i915;
 	const char *name;
 
-	struct intel_timeline engine[I915_NUM_ENGINES];
+	struct kref kref;
 };
 
-int i915_gem_timeline_init(struct drm_i915_private *i915,
-			   struct i915_gem_timeline *tl,
-			   const char *name);
-int i915_gem_timeline_init__global(struct drm_i915_private *i915);
-void i915_gem_timelines_park(struct drm_i915_private *i915);
-void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
+void i915_timeline_init(struct drm_i915_private *i915,
+			struct i915_timeline *tl,
+			const char *name);
+void i915_timeline_fini(struct i915_timeline *tl);
 
-struct i915_gem_timeline *
-i915_gem_timeline_create(struct drm_i915_private *i915, const char *name);
-void i915_gem_timeline_free(struct i915_gem_timeline *timeline);
+struct i915_timeline *
+i915_timeline_create(struct drm_i915_private *i915, const char *name);
 
-static inline int __intel_timeline_sync_set(struct intel_timeline *tl,
-					    u64 context, u32 seqno)
+static inline struct i915_timeline *
+i915_timeline_get(struct i915_timeline *timeline)
+{
+	kref_get(&timeline->kref);
+	return timeline;
+}
+
+void __i915_timeline_free(struct kref *kref);
+static inline void i915_timeline_put(struct i915_timeline *timeline)
+{
+	kref_put(&timeline->kref, __i915_timeline_free);
+}
+
+static inline int __i915_timeline_sync_set(struct i915_timeline *tl,
+					   u64 context, u32 seqno)
 {
 	return i915_syncmap_set(&tl->sync, context, seqno);
 }
 
-static inline int intel_timeline_sync_set(struct intel_timeline *tl,
-					  const struct dma_fence *fence)
+static inline int i915_timeline_sync_set(struct i915_timeline *tl,
+					 const struct dma_fence *fence)
 {
-	return __intel_timeline_sync_set(tl, fence->context, fence->seqno);
+	return __i915_timeline_sync_set(tl, fence->context, fence->seqno);
 }
 
-static inline bool __intel_timeline_sync_is_later(struct intel_timeline *tl,
-						  u64 context, u32 seqno)
+static inline bool __i915_timeline_sync_is_later(struct i915_timeline *tl,
+						 u64 context, u32 seqno)
 {
 	return i915_syncmap_is_later(&tl->sync, context, seqno);
 }
 
-static inline bool intel_timeline_sync_is_later(struct intel_timeline *tl,
-						const struct dma_fence *fence)
+static inline bool i915_timeline_sync_is_later(struct i915_timeline *tl,
+					       const struct dma_fence *fence)
 {
-	return __intel_timeline_sync_is_later(tl, fence->context, fence->seqno);
+	return __i915_timeline_sync_is_later(tl, fence->context, fence->seqno);
 }
 
+void i915_timelines_park(struct drm_i915_private *i915);
+
 #endif
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index d44a8eb83379..dcfdd4439935 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -451,12 +451,6 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
 	GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno);
 }
 
-static void intel_engine_init_timeline(struct intel_engine_cs *engine)
-{
-	engine->timeline =
-		&engine->i915->gt.execution_timeline.engine[engine->id];
-}
-
 static void intel_engine_init_batch_pool(struct intel_engine_cs *engine)
 {
 	i915_gem_batch_pool_init(&engine->batch_pool, engine);
@@ -508,8 +502,9 @@ static void intel_engine_init_execlist(struct intel_engine_cs *engine)
  */
 void intel_engine_setup_common(struct intel_engine_cs *engine)
 {
+	i915_timeline_init(engine->i915, &engine->timeline, engine->name);
+
 	intel_engine_init_execlist(engine);
-	intel_engine_init_timeline(engine);
 	intel_engine_init_hangcheck(engine);
 	intel_engine_init_batch_pool(engine);
 	intel_engine_init_cmd_parser(engine);
@@ -757,6 +752,8 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
 	if (engine->i915->preempt_context)
 		engine->context_unpin(engine, engine->i915->preempt_context);
 	engine->context_unpin(engine, engine->i915->kernel_context);
+
+	i915_timeline_fini(&engine->timeline);
 }
 
 u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
@@ -1009,7 +1006,7 @@ bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine)
 	 * the last request that remains in the timeline. When idle, it is
 	 * the last executed context as tracked by retirement.
 	 */
-	rq = __i915_gem_active_peek(&engine->timeline->last_request);
+	rq = __i915_gem_active_peek(&engine->timeline.last_request);
 	if (rq)
 		return rq->ctx == kernel_context;
 	else
@@ -1332,14 +1329,14 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 
 	drm_printf(m, "\tRequests:\n");
 
-	rq = list_first_entry(&engine->timeline->requests,
+	rq = list_first_entry(&engine->timeline.requests,
 			      struct i915_request, link);
-	if (&rq->link != &engine->timeline->requests)
+	if (&rq->link != &engine->timeline.requests)
 		print_request(m, rq, "\t\tfirst  ");
 
-	rq = list_last_entry(&engine->timeline->requests,
+	rq = list_last_entry(&engine->timeline.requests,
 			     struct i915_request, link);
-	if (&rq->link != &engine->timeline->requests)
+	if (&rq->link != &engine->timeline.requests)
 		print_request(m, rq, "\t\tlast   ");
 
 	rq = i915_gem_find_active_request(engine);
@@ -1371,8 +1368,8 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 		drm_printf(m, "\tDevice is asleep; skipping register dump\n");
 	}
 
-	spin_lock_irq(&engine->timeline->lock);
-	list_for_each_entry(rq, &engine->timeline->requests, link)
+	spin_lock_irq(&engine->timeline.lock);
+	list_for_each_entry(rq, &engine->timeline.requests, link)
 		print_request(m, rq, "\t\tE ");
 	drm_printf(m, "\t\tQueue priority: %d\n", execlists->queue_priority);
 	for (rb = execlists->first; rb; rb = rb_next(rb)) {
@@ -1382,7 +1379,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 		list_for_each_entry(rq, &p->requests, sched.link)
 			print_request(m, rq, "\t\tQ ");
 	}
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 
 	spin_lock_irq(&b->rb_lock);
 	for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index 02da05875aa7..cb4fcde1ffdc 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -677,7 +677,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
 	bool submit = false;
 	struct rb_node *rb;
 
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 	rb = execlists->first;
 	GEM_BUG_ON(rb_first(&execlists->queue) != rb);
 
@@ -748,7 +748,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
 	GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
 
 unlock:
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 }
 
 static void guc_submission_tasklet(unsigned long data)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index fd3539034665..fa802d791804 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -330,10 +330,10 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
 	struct i915_priolist *uninitialized_var(p);
 	int last_prio = I915_PRIORITY_INVALID;
 
-	lockdep_assert_held(&engine->timeline->lock);
+	lockdep_assert_held(&engine->timeline.lock);
 
 	list_for_each_entry_safe_reverse(rq, rn,
-					 &engine->timeline->requests,
+					 &engine->timeline.requests,
 					 link) {
 		if (i915_request_completed(rq))
 			return;
@@ -357,9 +357,9 @@ execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists)
 	struct intel_engine_cs *engine =
 		container_of(execlists, typeof(*engine), execlists);
 
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 	__unwind_incomplete_requests(engine);
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 }
 
 static inline void
@@ -583,7 +583,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 	 * and context switches) submission.
 	 */
 
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 	rb = execlists->first;
 	GEM_BUG_ON(rb_first(&execlists->queue) != rb);
 
@@ -743,7 +743,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 	GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
 
 unlock:
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 
 	if (submit) {
 		execlists_user_begin(execlists, execlists->port);
@@ -868,10 +868,10 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
 	execlists_cancel_port_requests(execlists);
 	reset_irq(engine);
 
-	spin_lock(&engine->timeline->lock);
+	spin_lock(&engine->timeline.lock);
 
 	/* Mark all executing requests as skipped. */
-	list_for_each_entry(rq, &engine->timeline->requests, link) {
+	list_for_each_entry(rq, &engine->timeline.requests, link) {
 		GEM_BUG_ON(!rq->global_seqno);
 		if (!i915_request_completed(rq))
 			dma_fence_set_error(&rq->fence, -EIO);
@@ -903,7 +903,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
 	execlists->first = NULL;
 	GEM_BUG_ON(port_isset(execlists->port));
 
-	spin_unlock(&engine->timeline->lock);
+	spin_unlock(&engine->timeline.lock);
 
 	local_irq_restore(flags);
 }
@@ -1141,7 +1141,7 @@ static void execlists_submit_request(struct i915_request *request)
 	unsigned long flags;
 
 	/* Will be called from irq-context when using foreign fences. */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	queue_request(engine, &request->sched, rq_prio(request));
 	submit_queue(engine, rq_prio(request));
@@ -1149,7 +1149,7 @@ static void execlists_submit_request(struct i915_request *request)
 	GEM_BUG_ON(!engine->execlists.first);
 	GEM_BUG_ON(list_empty(&request->sched.link));
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 static struct i915_request *sched_to_request(struct i915_sched_node *node)
@@ -1165,8 +1165,8 @@ sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
 	GEM_BUG_ON(!locked);
 
 	if (engine != locked) {
-		spin_unlock(&locked->timeline->lock);
-		spin_lock(&engine->timeline->lock);
+		spin_unlock(&locked->timeline.lock);
+		spin_lock(&engine->timeline.lock);
 	}
 
 	return engine;
@@ -1249,7 +1249,7 @@ static void execlists_schedule(struct i915_request *request,
 	}
 
 	engine = request->engine;
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 
 	/* Fifo and depth-first replacement ensure our deps execute before us */
 	list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) {
@@ -1273,7 +1273,7 @@ static void execlists_schedule(struct i915_request *request,
 			__submit_queue(engine, prio);
 	}
 
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 }
 
 static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma)
@@ -1802,9 +1802,9 @@ static void reset_common_ring(struct intel_engine_cs *engine,
 	reset_irq(engine);
 
 	/* Push back any incomplete requests for replay after the reset. */
-	spin_lock(&engine->timeline->lock);
+	spin_lock(&engine->timeline.lock);
 	__unwind_incomplete_requests(engine);
-	spin_unlock(&engine->timeline->lock);
+	spin_unlock(&engine->timeline.lock);
 
 	local_irq_restore(flags);
 
@@ -2559,6 +2559,7 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 	struct i915_vma *vma;
 	uint32_t context_size;
 	struct intel_ring *ring;
+	struct i915_timeline *timeline;
 	int ret;
 
 	if (ce->state)
@@ -2574,8 +2575,8 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 
 	ctx_obj = i915_gem_object_create(ctx->i915, context_size);
 	if (IS_ERR(ctx_obj)) {
-		DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n");
-		return PTR_ERR(ctx_obj);
+		ret = PTR_ERR(ctx_obj);
+		goto error_deref_obj;
 	}
 
 	vma = i915_vma_instance(ctx_obj, &ctx->i915->ggtt.base, NULL);
@@ -2584,7 +2585,14 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 		goto error_deref_obj;
 	}
 
-	ring = intel_engine_create_ring(engine, ctx->timeline, ctx->ring_size);
+	timeline = i915_timeline_create(ctx->i915, ctx->name);
+	if (IS_ERR(timeline)) {
+		ret = PTR_ERR(timeline);
+		goto error_deref_obj;
+	}
+
+	ring = intel_engine_create_ring(engine, timeline, ctx->ring_size);
+	i915_timeline_put(timeline);
 	if (IS_ERR(ring)) {
 		ret = PTR_ERR(ring);
 		goto error_deref_obj;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 47009695b378..823cf49f1887 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -696,17 +696,17 @@ static void cancel_requests(struct intel_engine_cs *engine)
 	struct i915_request *request;
 	unsigned long flags;
 
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	/* Mark all submitted requests as skipped. */
-	list_for_each_entry(request, &engine->timeline->requests, link) {
+	list_for_each_entry(request, &engine->timeline.requests, link) {
 		GEM_BUG_ON(!request->global_seqno);
 		if (!i915_request_completed(request))
 			dma_fence_set_error(&request->fence, -EIO);
 	}
 	/* Remaining _unready_ requests will be nop'ed when submitted */
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 static void i9xx_submit_request(struct i915_request *request)
@@ -1117,7 +1117,7 @@ intel_ring_create_vma(struct drm_i915_private *dev_priv, int size)
 
 struct intel_ring *
 intel_engine_create_ring(struct intel_engine_cs *engine,
-			 struct i915_gem_timeline *timeline,
+			 struct i915_timeline *timeline,
 			 int size)
 {
 	struct intel_ring *ring;
@@ -1133,7 +1133,7 @@ intel_engine_create_ring(struct intel_engine_cs *engine,
 		return ERR_PTR(-ENOMEM);
 
 	INIT_LIST_HEAD(&ring->request_list);
-	ring->timeline = &timeline->engine[engine->id];
+	ring->timeline = i915_timeline_get(timeline);
 
 	ring->size = size;
 	/* Workaround an erratum on the i830 which causes a hang if
@@ -1164,6 +1164,7 @@ intel_ring_free(struct intel_ring *ring)
 	i915_vma_close(ring->vma);
 	__i915_gem_object_release_unless_active(obj);
 
+	i915_timeline_put(ring->timeline);
 	kfree(ring);
 }
 
@@ -1322,6 +1323,7 @@ static void intel_ring_context_unpin(struct intel_engine_cs *engine,
 static int intel_init_ring_buffer(struct intel_engine_cs *engine)
 {
 	struct intel_ring *ring;
+	struct i915_timeline *timeline;
 	int err;
 
 	intel_engine_setup_common(engine);
@@ -1330,9 +1332,14 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
 	if (err)
 		goto err;
 
-	ring = intel_engine_create_ring(engine,
-					&engine->i915->gt.legacy_timeline,
-					32 * PAGE_SIZE);
+	timeline = i915_timeline_create(engine->i915, engine->name);
+	if (IS_ERR(timeline)) {
+		err = PTR_ERR(timeline);
+		goto err;
+	}
+
+	ring = intel_engine_create_ring(engine, timeline, 32 * PAGE_SIZE);
+	i915_timeline_put(timeline);
 	if (IS_ERR(ring)) {
 		err = PTR_ERR(ring);
 		goto err;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index b3c3f8f47f38..569b3203e123 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -5,12 +5,12 @@
 #include <linux/hashtable.h>
 
 #include "i915_gem_batch_pool.h"
-#include "i915_gem_timeline.h"
 
 #include "i915_reg.h"
 #include "i915_pmu.h"
 #include "i915_request.h"
 #include "i915_selftest.h"
+#include "i915_timeline.h"
 #include "intel_gpu_commands.h"
 
 struct drm_printer;
@@ -128,7 +128,7 @@ struct intel_ring {
 	struct i915_vma *vma;
 	void *vaddr;
 
-	struct intel_timeline *timeline;
+	struct i915_timeline *timeline;
 	struct list_head request_list;
 	struct list_head active_link;
 
@@ -337,7 +337,8 @@ struct intel_engine_cs {
 	u32 mmio_base;
 
 	struct intel_ring *buffer;
-	struct intel_timeline *timeline;
+
+	struct i915_timeline timeline;
 
 	struct drm_i915_gem_object *default_state;
 
@@ -769,7 +770,7 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 
 struct intel_ring *
 intel_engine_create_ring(struct intel_engine_cs *engine,
-			 struct i915_gem_timeline *timeline,
+			 struct i915_timeline *timeline,
 			 int size);
 int intel_ring_pin(struct intel_ring *ring,
 		   struct drm_i915_private *i915,
@@ -888,7 +889,7 @@ static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine)
 	 * wtih serialising this hint with anything, so document it as
 	 * a hint and nothing more.
 	 */
-	return READ_ONCE(engine->timeline->seqno);
+	return READ_ONCE(engine->timeline.seqno);
 }
 
 void intel_engine_get_instdone(struct intel_engine_cs *engine,
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_timeline.c
similarity index 70%
rename from drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
rename to drivers/gpu/drm/i915/selftests/i915_timeline.c
index 3000e6a7d82d..19f1c6a5c8fb 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/selftests/i915_timeline.c
@@ -1,25 +1,7 @@
 /*
- * 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.
+ * SPDX-License-Identifier: MIT
  *
+ * Copyright © 2017-2018 Intel Corporation
  */
 
 #include "../i915_selftest.h"
@@ -35,21 +17,21 @@ struct __igt_sync {
 	bool set;
 };
 
-static int __igt_sync(struct intel_timeline *tl,
+static int __igt_sync(struct i915_timeline *tl,
 		      u64 ctx,
 		      const struct __igt_sync *p,
 		      const char *name)
 {
 	int ret;
 
-	if (__intel_timeline_sync_is_later(tl, ctx, p->seqno) != p->expected) {
+	if (__i915_timeline_sync_is_later(tl, ctx, p->seqno) != p->expected) {
 		pr_err("%s: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
 		       name, p->name, ctx, p->seqno, yesno(p->expected));
 		return -EINVAL;
 	}
 
 	if (p->set) {
-		ret = __intel_timeline_sync_set(tl, ctx, p->seqno);
+		ret = __i915_timeline_sync_set(tl, ctx, p->seqno);
 		if (ret)
 			return ret;
 	}
@@ -77,37 +59,31 @@ static int igt_sync(void *arg)
 		{ "unwrap", UINT_MAX, true, false },
 		{},
 	}, *p;
-	struct intel_timeline *tl;
+	struct i915_timeline tl;
 	int order, offset;
 	int ret = -ENODEV;
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
-
+	mock_timeline_init(&tl, 0);
 	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;
 
-				ret = __igt_sync(tl, ctx, p, "1");
+				ret = __igt_sync(&tl, ctx, p, "1");
 				if (ret)
 					goto out;
 			}
 		}
 	}
-	mock_timeline_destroy(tl);
-
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_fini(&tl);
 
+	mock_timeline_init(&tl, 0);
 	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++) {
-				ret = __igt_sync(tl, ctx, p, "2");
+				ret = __igt_sync(&tl, ctx, p, "2");
 				if (ret)
 					goto out;
 			}
@@ -115,7 +91,7 @@ static int igt_sync(void *arg)
 	}
 
 out:
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	return ret;
 }
 
@@ -127,15 +103,13 @@ static unsigned int random_engine(struct rnd_state *rnd)
 static int bench_sync(void *arg)
 {
 	struct rnd_state prng;
-	struct intel_timeline *tl;
+	struct i915_timeline tl;
 	unsigned long end_time, count;
 	u64 prng32_1M;
 	ktime_t kt;
 	int order, last_order;
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_init(&tl, 0);
 
 	/* Lookups from cache are very fast and so the random number generation
 	 * and the loop itself becomes a significant factor in the per-iteration
@@ -167,7 +141,7 @@ static int bench_sync(void *arg)
 	do {
 		u64 id = i915_prandom_u64_state(&prng);
 
-		__intel_timeline_sync_set(tl, id, 0);
+		__i915_timeline_sync_set(&tl, id, 0);
 		count++;
 	} while (!time_after(jiffies, end_time));
 	kt = ktime_sub(ktime_get(), kt);
@@ -182,8 +156,8 @@ static int bench_sync(void *arg)
 	while (end_time--) {
 		u64 id = i915_prandom_u64_state(&prng);
 
-		if (!__intel_timeline_sync_is_later(tl, id, 0)) {
-			mock_timeline_destroy(tl);
+		if (!__i915_timeline_sync_is_later(&tl, id, 0)) {
+			mock_timeline_fini(&tl);
 			pr_err("Lookup of %llu failed\n", id);
 			return -EINVAL;
 		}
@@ -193,19 +167,17 @@ static int bench_sync(void *arg)
 	pr_info("%s: %lu random lookups, %lluns/lookup\n",
 		__func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
 
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	cond_resched();
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_init(&tl, 0);
 
 	/* Benchmark setting the first N (in order) contexts */
 	count = 0;
 	kt = ktime_get();
 	end_time = jiffies + HZ/10;
 	do {
-		__intel_timeline_sync_set(tl, count++, 0);
+		__i915_timeline_sync_set(&tl, count++, 0);
 	} while (!time_after(jiffies, end_time));
 	kt = ktime_sub(ktime_get(), kt);
 	pr_info("%s: %lu in-order insertions, %lluns/insert\n",
@@ -215,9 +187,9 @@ static int bench_sync(void *arg)
 	end_time = count;
 	kt = ktime_get();
 	while (end_time--) {
-		if (!__intel_timeline_sync_is_later(tl, end_time, 0)) {
+		if (!__i915_timeline_sync_is_later(&tl, end_time, 0)) {
 			pr_err("Lookup of %lu failed\n", end_time);
-			mock_timeline_destroy(tl);
+			mock_timeline_fini(&tl);
 			return -EINVAL;
 		}
 	}
@@ -225,12 +197,10 @@ static int bench_sync(void *arg)
 	pr_info("%s: %lu in-order lookups, %lluns/lookup\n",
 		__func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
 
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	cond_resched();
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_init(&tl, 0);
 
 	/* Benchmark searching for a random context id and maybe changing it */
 	prandom_seed_state(&prng, i915_selftest.random_seed);
@@ -241,8 +211,8 @@ static int bench_sync(void *arg)
 		u32 id = random_engine(&prng);
 		u32 seqno = prandom_u32_state(&prng);
 
-		if (!__intel_timeline_sync_is_later(tl, id, seqno))
-			__intel_timeline_sync_set(tl, id, seqno);
+		if (!__i915_timeline_sync_is_later(&tl, id, seqno))
+			__i915_timeline_sync_set(&tl, id, seqno);
 
 		count++;
 	} while (!time_after(jiffies, end_time));
@@ -250,7 +220,7 @@ static int bench_sync(void *arg)
 	kt = ktime_sub_ns(kt, (count * prng32_1M * 2) >> 20);
 	pr_info("%s: %lu repeated insert/lookups, %lluns/op\n",
 		__func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	cond_resched();
 
 	/* Benchmark searching for a known context id and changing the seqno */
@@ -258,9 +228,7 @@ static int bench_sync(void *arg)
 	     ({ int tmp = last_order; last_order = order; order += tmp; })) {
 		unsigned int mask = BIT(order) - 1;
 
-		tl = mock_timeline(0);
-		if (!tl)
-			return -ENOMEM;
+		mock_timeline_init(&tl, 0);
 
 		count = 0;
 		kt = ktime_get();
@@ -272,8 +240,8 @@ static int bench_sync(void *arg)
 			 */
 			u64 id = (u64)(count & mask) << order;
 
-			__intel_timeline_sync_is_later(tl, id, 0);
-			__intel_timeline_sync_set(tl, id, 0);
+			__i915_timeline_sync_is_later(&tl, id, 0);
+			__i915_timeline_sync_set(&tl, id, 0);
 
 			count++;
 		} while (!time_after(jiffies, end_time));
@@ -281,7 +249,7 @@ static int bench_sync(void *arg)
 		pr_info("%s: %lu cyclic/%d insert/lookups, %lluns/op\n",
 			__func__, count, order,
 			(long long)div64_ul(ktime_to_ns(kt), count));
-		mock_timeline_destroy(tl);
+		mock_timeline_fini(&tl);
 		cond_resched();
 	}
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 6a10cb734c35..31cc210d51e9 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -25,6 +25,11 @@
 #include "mock_engine.h"
 #include "mock_request.h"
 
+struct mock_ring {
+	struct intel_ring base;
+	struct i915_timeline timeline;
+};
+
 static struct mock_request *first_request(struct mock_engine *engine)
 {
 	return list_first_entry_or_null(&engine->hw_queue,
@@ -125,7 +130,7 @@ static void mock_submit_request(struct i915_request *request)
 static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 {
 	const unsigned long sz = PAGE_SIZE / 2;
-	struct intel_ring *ring;
+	struct mock_ring *ring;
 
 	BUILD_BUG_ON(MIN_SPACE_FOR_ADD_REQUEST > sz);
 
@@ -133,18 +138,24 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	if (!ring)
 		return NULL;
 
-	ring->size = sz;
-	ring->effective_size = sz;
-	ring->vaddr = (void *)(ring + 1);
+	i915_timeline_init(engine->i915, &ring->timeline, engine->name);
+
+	ring->base.size = sz;
+	ring->base.effective_size = sz;
+	ring->base.vaddr = (void *)(ring + 1);
+	ring->base.timeline = &ring->timeline;
 
-	INIT_LIST_HEAD(&ring->request_list);
-	intel_ring_update_space(ring);
+	INIT_LIST_HEAD(&ring->base.request_list);
+	intel_ring_update_space(&ring->base);
 
-	return ring;
+	return &ring->base;
 }
 
-static void mock_ring_free(struct intel_ring *ring)
+static void mock_ring_free(struct intel_ring *base)
 {
+	struct mock_ring *ring = container_of(base, typeof(*ring), base);
+
+	i915_timeline_fini(&ring->timeline);
 	kfree(ring);
 }
 
@@ -173,8 +184,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 	engine->base.emit_breadcrumb = mock_emit_breadcrumb;
 	engine->base.submit_request = mock_submit_request;
 
-	intel_engine_init_timeline(&engine->base);
-
+	i915_timeline_init(i915, &engine->base.timeline, engine->base.name);
 	intel_engine_init_breadcrumbs(&engine->base);
 	engine->base.breadcrumbs.mock = true; /* prevent touching HW for irqs */
 
@@ -191,6 +201,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 
 err_breadcrumbs:
 	intel_engine_fini_breadcrumbs(&engine->base);
+	i915_timeline_fini(&engine->base.timeline);
 	kfree(engine);
 	return NULL;
 }
@@ -229,6 +240,7 @@ void mock_engine_free(struct intel_engine_cs *engine)
 	mock_ring_free(engine->buffer);
 
 	intel_engine_fini_breadcrumbs(engine);
+	i915_timeline_fini(&engine->timeline);
 
 	kfree(engine);
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index f11c83e8ff32..a662c0450e77 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -73,10 +73,8 @@ static void mock_device_release(struct drm_device *dev)
 
 	mutex_lock(&i915->drm.struct_mutex);
 	mock_fini_ggtt(i915);
-	i915_gem_timeline_fini(&i915->gt.legacy_timeline);
-	i915_gem_timeline_fini(&i915->gt.execution_timeline);
-	WARN_ON(!list_empty(&i915->gt.timelines));
 	mutex_unlock(&i915->drm.struct_mutex);
+	WARN_ON(!list_empty(&i915->gt.timelines));
 
 	destroy_workqueue(i915->wq);
 
@@ -230,12 +228,6 @@ struct drm_i915_private *mock_gem_device(void)
 	INIT_LIST_HEAD(&i915->gt.active_rings);
 
 	mutex_lock(&i915->drm.struct_mutex);
-	err = i915_gem_timeline_init__global(i915);
-	if (err) {
-		mutex_unlock(&i915->drm.struct_mutex);
-		goto err_priorities;
-	}
-
 	mock_init_ggtt(i915);
 	mutex_unlock(&i915->drm.struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.c b/drivers/gpu/drm/i915/selftests/mock_timeline.c
index 47b1f47c5812..dcf3b16f5a07 100644
--- a/drivers/gpu/drm/i915/selftests/mock_timeline.c
+++ b/drivers/gpu/drm/i915/selftests/mock_timeline.c
@@ -1,45 +1,28 @@
 /*
- * 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.
+ * SPDX-License-Identifier: MIT
  *
+ * Copyright © 2017-2018 Intel Corporation
  */
 
+#include "../i915_timeline.h"
+
 #include "mock_timeline.h"
 
-struct intel_timeline *mock_timeline(u64 context)
+void mock_timeline_init(struct i915_timeline *timeline, u64 context)
 {
-	static struct lock_class_key class;
-	struct intel_timeline *tl;
+	timeline->fence_context = context;
+
+	spin_lock_init(&timeline->lock);
 
-	tl = kzalloc(sizeof(*tl), GFP_KERNEL);
-	if (!tl)
-		return NULL;
+	init_request_active(&timeline->last_request, NULL);
+	INIT_LIST_HEAD(&timeline->requests);
 
-	__intel_timeline_init(tl, NULL, context, &class, "mock");
+	i915_syncmap_init(&timeline->sync);
 
-	return tl;
+	INIT_LIST_HEAD(&timeline->link);
 }
 
-void mock_timeline_destroy(struct intel_timeline *tl)
+void mock_timeline_fini(struct i915_timeline *timeline)
 {
-	__intel_timeline_fini(tl);
-	kfree(tl);
+	i915_timeline_fini(timeline);
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.h b/drivers/gpu/drm/i915/selftests/mock_timeline.h
index c27ff4639b8b..b6deaa61110d 100644
--- a/drivers/gpu/drm/i915/selftests/mock_timeline.h
+++ b/drivers/gpu/drm/i915/selftests/mock_timeline.h
@@ -1,33 +1,15 @@
 /*
- * 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.
+ * SPDX-License-Identifier: MIT
  *
+ * Copyright © 2017-2018 Intel Corporation
  */
 
 #ifndef __MOCK_TIMELINE__
 #define __MOCK_TIMELINE__
 
-#include "../i915_gem_timeline.h"
+struct i915_timeline;
 
-struct intel_timeline *mock_timeline(u64 context);
-void mock_timeline_destroy(struct intel_timeline *tl);
+void mock_timeline_init(struct i915_timeline *timeline, u64 context);
+void mock_timeline_fini(struct i915_timeline *timeline);
 
 #endif /* !__MOCK_TIMELINE__ */
-- 
2.17.0

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

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

* [PATCH v2 6/6] drm/i915: Lazily unbind vma on close
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (3 preceding siblings ...)
  2018-04-23 18:08 ` [PATCH v2 5/6] drm/i915: Split i915_gem_timeline into individual timelines Chris Wilson
@ 2018-04-23 18:08 ` Chris Wilson
  2018-04-23 18:17 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos Patchwork
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 18:08 UTC (permalink / raw)
  To: intel-gfx

When userspace is passing around swapbuffers using DRI, we frequently
have to open and close the same object in the foreign address space.
This shows itself as the same object being rebound at roughly 30fps
(with a second object also being rebound at 30fps), which involves us
having to rewrite the page tables and maintain the drm_mm range manager
every time.

However, since the object still exists and it is only the local handle
that disappears, if we are lazy and do not unbind the VMA immediately
when the local user closes the object but defer it until the GPU is
idle, then we can reuse the same VMA binding. We still have to be
careful to mark the handle and lookup tables as closed to maintain the
uABI, just allowing the underlying VMA to be resurrected if the user is
able to access the same object from the same context again.

If the object itself is destroyed (neither userspace keeping a handle to
it), the VMA will be reaped immediately as usual.

In the future, this will be even more useful as instantiating a new VMA
for use on the GPU will become heavier. A nuisance indeed, so nip it in
the bud.

v2: s/__i915_vma_final_close/i915_vma_destroy/ etc.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h               |  1 +
 drivers/gpu/drm/i915/i915_gem.c               |  4 +-
 drivers/gpu/drm/i915/i915_gem_execbuffer.c    |  3 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c           | 14 +++--
 drivers/gpu/drm/i915/i915_vma.c               | 61 +++++++++++++------
 drivers/gpu/drm/i915/i915_vma.h               |  6 ++
 drivers/gpu/drm/i915/selftests/huge_pages.c   |  2 +-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  1 +
 8 files changed, 67 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index dab15b6abc3c..d4da9f941d04 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2061,6 +2061,7 @@ struct drm_i915_private {
 		struct list_head timelines;
 
 		struct list_head active_rings;
+		struct list_head closed_vma;
 		u32 active_requests;
 		u32 request_serial;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d36778518cdf..0dc1658393df 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -165,6 +165,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 	i915_timelines_park(i915);
 
 	i915_pmu_gt_parked(i915);
+	i915_vma_parked(i915);
 
 	i915->gt.awake = false;
 
@@ -4792,7 +4793,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
 					 &obj->vma_list, obj_link) {
 			GEM_BUG_ON(i915_vma_is_active(vma));
 			vma->flags &= ~I915_VMA_PIN_MASK;
-			i915_vma_close(vma);
+			i915_vma_destroy(vma);
 		}
 		GEM_BUG_ON(!list_empty(&obj->vma_list));
 		GEM_BUG_ON(!RB_EMPTY_ROOT(&obj->vma_tree));
@@ -5595,6 +5596,7 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
 	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
+	INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
 
 	i915_gem_init__mm(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index c74f5df3fb5a..f627a8c47c58 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -762,7 +762,8 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 		}
 
 		/* transfer ref to ctx */
-		vma->open_count++;
+		if (!vma->open_count++)
+			i915_vma_reopen(vma);
 		list_add(&lut->obj_link, &obj->lut_list);
 		list_add(&lut->ctx_link, &eb->ctx->handles_list);
 		lut->ctx = eb->ctx;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index e9d828324f67..272d6bb407cc 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2218,6 +2218,12 @@ i915_ppgtt_create(struct drm_i915_private *dev_priv,
 }
 
 void i915_ppgtt_close(struct i915_address_space *vm)
+{
+	GEM_BUG_ON(vm->closed);
+	vm->closed = true;
+}
+
+static void ppgtt_destroy_vma(struct i915_address_space *vm)
 {
 	struct list_head *phases[] = {
 		&vm->active_list,
@@ -2226,15 +2232,12 @@ void i915_ppgtt_close(struct i915_address_space *vm)
 		NULL,
 	}, **phase;
 
-	GEM_BUG_ON(vm->closed);
 	vm->closed = true;
-
 	for (phase = phases; *phase; phase++) {
 		struct i915_vma *vma, *vn;
 
 		list_for_each_entry_safe(vma, vn, *phase, vm_link)
-			if (!i915_vma_is_closed(vma))
-				i915_vma_close(vma);
+			i915_vma_destroy(vma);
 	}
 }
 
@@ -2245,7 +2248,8 @@ void i915_ppgtt_release(struct kref *kref)
 
 	trace_i915_ppgtt_release(&ppgtt->base);
 
-	/* vmas should already be unbound and destroyed */
+	ppgtt_destroy_vma(&ppgtt->base);
+
 	GEM_BUG_ON(!list_empty(&ppgtt->base.active_list));
 	GEM_BUG_ON(!list_empty(&ppgtt->base.inactive_list));
 	GEM_BUG_ON(!list_empty(&ppgtt->base.unbound_list));
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 4bda3bd29bf5..81fa652ad78d 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -46,8 +46,6 @@ i915_vma_retire(struct i915_gem_active *active, struct i915_request *rq)
 
 	GEM_BUG_ON(!drm_mm_node_allocated(&vma->node));
 	list_move_tail(&vma->vm_link, &vma->vm->inactive_list);
-	if (unlikely(i915_vma_is_closed(vma) && !i915_vma_is_pinned(vma)))
-		WARN_ON(i915_vma_unbind(vma));
 
 	GEM_BUG_ON(!i915_gem_object_is_active(obj));
 	if (--obj->active_count)
@@ -232,7 +230,6 @@ i915_vma_instance(struct drm_i915_gem_object *obj,
 	if (!vma)
 		vma = vma_create(obj, vm, view);
 
-	GEM_BUG_ON(!IS_ERR(vma) && i915_vma_is_closed(vma));
 	GEM_BUG_ON(!IS_ERR(vma) && i915_vma_compare(vma, vm, view));
 	GEM_BUG_ON(!IS_ERR(vma) && vma_lookup(obj, vm, view) != vma);
 	return vma;
@@ -684,13 +681,31 @@ int __i915_vma_do_pin(struct i915_vma *vma,
 	return ret;
 }
 
-static void i915_vma_destroy(struct i915_vma *vma)
+void i915_vma_close(struct i915_vma *vma)
+{
+	lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+
+	GEM_BUG_ON(i915_vma_is_closed(vma));
+	vma->flags |= I915_VMA_CLOSED;
+
+	list_add_tail(&vma->closed_link, &vma->vm->i915->gt.closed_vma);
+}
+
+void i915_vma_reopen(struct i915_vma *vma)
+{
+	lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
+
+	if (vma->flags & I915_VMA_CLOSED) {
+		vma->flags &= ~I915_VMA_CLOSED;
+		list_del(&vma->closed_link);
+	}
+}
+
+static void __i915_vma_destroy(struct i915_vma *vma)
 {
 	int i;
 
 	GEM_BUG_ON(vma->node.allocated);
-	GEM_BUG_ON(i915_vma_is_active(vma));
-	GEM_BUG_ON(!i915_vma_is_closed(vma));
 	GEM_BUG_ON(vma->fence);
 
 	for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
@@ -699,6 +714,7 @@ static void i915_vma_destroy(struct i915_vma *vma)
 
 	list_del(&vma->obj_link);
 	list_del(&vma->vm_link);
+	rb_erase(&vma->obj_node, &vma->obj->vma_tree);
 
 	if (!i915_vma_is_ggtt(vma))
 		i915_ppgtt_put(i915_vm_to_ppgtt(vma->vm));
@@ -706,15 +722,30 @@ static void i915_vma_destroy(struct i915_vma *vma)
 	kmem_cache_free(to_i915(vma->obj->base.dev)->vmas, vma);
 }
 
-void i915_vma_close(struct i915_vma *vma)
+void i915_vma_destroy(struct i915_vma *vma)
 {
-	GEM_BUG_ON(i915_vma_is_closed(vma));
-	vma->flags |= I915_VMA_CLOSED;
+	lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
 
-	rb_erase(&vma->obj_node, &vma->obj->vma_tree);
+	GEM_BUG_ON(i915_vma_is_active(vma));
+	GEM_BUG_ON(i915_vma_is_pinned(vma));
+
+	if (i915_vma_is_closed(vma))
+		list_del(&vma->closed_link);
 
-	if (!i915_vma_is_active(vma) && !i915_vma_is_pinned(vma))
-		WARN_ON(i915_vma_unbind(vma));
+	WARN_ON(i915_vma_unbind(vma));
+	__i915_vma_destroy(vma);
+}
+
+void i915_vma_parked(struct drm_i915_private *i915)
+{
+	struct i915_vma *vma, *next;
+
+	list_for_each_entry_safe(vma, next, &i915->gt.closed_vma, closed_link) {
+		GEM_BUG_ON(!i915_vma_is_closed(vma));
+		i915_vma_destroy(vma);
+	}
+
+	GEM_BUG_ON(!list_empty(&i915->gt.closed_vma));
 }
 
 static void __i915_vma_iounmap(struct i915_vma *vma)
@@ -804,7 +835,7 @@ int i915_vma_unbind(struct i915_vma *vma)
 		return -EBUSY;
 
 	if (!drm_mm_node_allocated(&vma->node))
-		goto destroy;
+		return 0;
 
 	GEM_BUG_ON(obj->bind_count == 0);
 	GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj));
@@ -841,10 +872,6 @@ int i915_vma_unbind(struct i915_vma *vma)
 
 	i915_vma_remove(vma);
 
-destroy:
-	if (unlikely(i915_vma_is_closed(vma)))
-		i915_vma_destroy(vma);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 8c5022095418..fc4294cfaa91 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -119,6 +119,8 @@ struct i915_vma {
 	/** This vma's place in the eviction list */
 	struct list_head evict_link;
 
+	struct list_head closed_link;
+
 	/**
 	 * Used for performing relocations during execbuffer insertion.
 	 */
@@ -285,6 +287,8 @@ void i915_vma_revoke_mmap(struct i915_vma *vma);
 int __must_check i915_vma_unbind(struct i915_vma *vma);
 void i915_vma_unlink_ctx(struct i915_vma *vma);
 void i915_vma_close(struct i915_vma *vma);
+void i915_vma_reopen(struct i915_vma *vma);
+void i915_vma_destroy(struct i915_vma *vma);
 
 int __i915_vma_do_pin(struct i915_vma *vma,
 		      u64 size, u64 alignment, u64 flags);
@@ -408,6 +412,8 @@ i915_vma_unpin_fence(struct i915_vma *vma)
 		__i915_vma_unpin_fence(vma);
 }
 
+void i915_vma_parked(struct drm_i915_private *i915);
+
 #define for_each_until(cond) if (cond) break; else
 
 /**
diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c
index 05bbef363fff..d7c8ef8e6764 100644
--- a/drivers/gpu/drm/i915/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/selftests/huge_pages.c
@@ -1091,7 +1091,7 @@ static int __igt_write_huge(struct i915_gem_context *ctx,
 out_vma_unpin:
 	i915_vma_unpin(vma);
 out_vma_close:
-	i915_vma_close(vma);
+	i915_vma_destroy(vma);
 
 	return err;
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index a662c0450e77..4b6622c6986a 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -226,6 +226,7 @@ struct drm_i915_private *mock_gem_device(void)
 
 	INIT_LIST_HEAD(&i915->gt.timelines);
 	INIT_LIST_HEAD(&i915->gt.active_rings);
+	INIT_LIST_HEAD(&i915->gt.closed_vma);
 
 	mutex_lock(&i915->drm.struct_mutex);
 	mock_init_ggtt(i915);
-- 
2.17.0

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

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

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (4 preceding siblings ...)
  2018-04-23 18:08 ` [PATCH v2 6/6] drm/i915: Lazily unbind vma on close Chris Wilson
@ 2018-04-23 18:17 ` Patchwork
  2018-04-23 18:19 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 18:17 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
URL   : https://patchwork.freedesktop.org/series/42139/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
b1a184759165 drm/i915: Stop tracking timeline->inflight_seqnos
-:17: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")'
#17: 
References: 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")

total: 1 errors, 0 warnings, 0 checks, 128 lines checked
e982294a22bd drm/i915: Retire requests along rings
b6e3c9bab43f drm/i915: Only track live rings for retiring
9e0240db6895 drm/i915: Move timeline from GTT to ring
7d0dd099190b drm/i915: Split i915_gem_timeline into individual timelines
-:446: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#446: 
deleted file mode 100644

-:942: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#942: FILE: drivers/gpu/drm/i915/i915_timeline.c:1:
+/*

total: 0 errors, 2 warnings, 0 checks, 1603 lines checked
9c373ac32b70 drm/i915: Lazily unbind vma on close

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

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

* ✗ Fi.CI.SPARSE: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (5 preceding siblings ...)
  2018-04-23 18:17 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos Patchwork
@ 2018-04-23 18:19 ` Patchwork
  2018-04-23 18:32 ` ✗ Fi.CI.BAT: failure " Patchwork
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 18:19 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
URL   : https://patchwork.freedesktop.org/series/42139/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Commit: drm/i915: Stop tracking timeline->inflight_seqnos
-O:drivers/gpu/drm/i915/i915_request.c:268:13: error: undefined identifier '__builtin_add_overflow_p'
-O:drivers/gpu/drm/i915/i915_request.c:268:13: warning: call with no type!
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2211:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3659:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2212:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3660:16: warning: expression using sizeof(void)

Commit: drm/i915: Retire requests along rings
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2212:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3660:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2213:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3661:16: warning: expression using sizeof(void)

Commit: drm/i915: Only track live rings for retiring
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2213:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3661:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2214:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3662:16: warning: expression using sizeof(void)

Commit: drm/i915: Move timeline from GTT to ring
+  ^~~~~~~~~~
+  ^~~~~~~~~~
+                      ^
+                          ^
+                                          ^
+                                          ^
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1954:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1958:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1963:38: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2273:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2277:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2281:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:672:45:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:672:45:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:672:45: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/mmio.c:255:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/mmio.c:256:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/vgpu.c:144:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:144:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
+cc1: all warnings being treated as errors
+cc1: all warnings being treated as errors
+ # define unlikely(x) __builtin_expect(!!(x), 0)
+ # define unlikely(x) __builtin_expect(!!(x), 0)
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it

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

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

* ✗ Fi.CI.BAT: failure for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (6 preceding siblings ...)
  2018-04-23 18:19 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-04-23 18:32 ` Patchwork
  2018-04-23 20:29 ` ✗ Fi.CI.CHECKPATCH: warning " Patchwork
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 18:32 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
URL   : https://patchwork.freedesktop.org/series/42139/
State : failure

== Summary ==

= CI Bug Log - changes from CI_DRM_4079 -> Patchwork_8776 =

== Summary - FAILURE ==

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

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

== Possible new issues ==

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

  === IGT changes ===

    ==== Possible regressions ====

    igt@drv_module_reload@basic-reload:
      fi-glk-j4005:       PASS -> DMESG-WARN

    igt@gem_ctx_switch@basic-default:
      fi-bsw-n3050:       PASS -> INCOMPLETE

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@gem_ctx_switch@basic-default:
      fi-bdw-gvtdvm:      PASS -> INCOMPLETE (fdo#105600)

    igt@gem_exec_suspend@basic-s4-devices:
      fi-kbl-7500u:       PASS -> DMESG-WARN (fdo#105128)

    igt@kms_flip@basic-flip-vs-dpms:
      fi-glk-j4005:       PASS -> DMESG-WARN (fdo#106097) +1

    
    ==== Possible fixes ====

    igt@drv_module_reload@basic-no-display:
      fi-bwr-2160:        INCOMPLETE (fdo#105268) -> PASS

    
  fdo#105128 https://bugs.freedesktop.org/show_bug.cgi?id=105128
  fdo#105268 https://bugs.freedesktop.org/show_bug.cgi?id=105268
  fdo#105600 https://bugs.freedesktop.org/show_bug.cgi?id=105600
  fdo#106097 https://bugs.freedesktop.org/show_bug.cgi?id=106097


== Participating hosts (36 -> 33) ==

  Missing    (3): fi-ctg-p8600 fi-ilk-m540 fi-skl-6700hq 


== Build changes ==

    * Linux: CI_DRM_4079 -> Patchwork_8776

  CI_DRM_4079: 5b0d2878a1667b63a937eb67c1673f29ff280e8b @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4444: dcc44347494231feabc588c2a76998cbc9afdf8c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_8776: 9c373ac32b705c7a767220bc2cea59d869ca3b5e @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4444: a2f486679f467cd6e82578384f56d4aabaa8cf2e @ git://anongit.freedesktop.org/piglit


== Linux commits ==

9c373ac32b70 drm/i915: Lazily unbind vma on close
7d0dd099190b drm/i915: Split i915_gem_timeline into individual timelines
9e0240db6895 drm/i915: Move timeline from GTT to ring
b6e3c9bab43f drm/i915: Only track live rings for retiring
e982294a22bd drm/i915: Retire requests along rings
b1a184759165 drm/i915: Stop tracking timeline->inflight_seqnos


== Kernel 32bit build ==

Warning: Kernel 32bit buildtest failed:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8776/build_32bit_failure.log

== Logs ==

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

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

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (7 preceding siblings ...)
  2018-04-23 18:32 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2018-04-23 20:29 ` Patchwork
  2018-04-23 20:32 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 20:29 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
URL   : https://patchwork.freedesktop.org/series/42139/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
397f93096828 drm/i915: Stop tracking timeline->inflight_seqnos
-:17: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")'
#17: 
References: 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")

total: 1 errors, 0 warnings, 0 checks, 128 lines checked
f1d8ea9d3683 drm/i915: Retire requests along rings
1cca0fbbe09b drm/i915: Only track live rings for retiring
38d2d82de298 drm/i915: Move timeline from GTT to ring
23a6561be624 drm/i915: Split i915_gem_timeline into individual timelines
-:446: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#446: 
deleted file mode 100644

-:942: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#942: FILE: drivers/gpu/drm/i915/i915_timeline.c:1:
+/*

total: 0 errors, 2 warnings, 0 checks, 1603 lines checked
123351d9c80e drm/i915: Lazily unbind vma on close

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

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

* ✗ Fi.CI.SPARSE: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (8 preceding siblings ...)
  2018-04-23 20:29 ` ✗ Fi.CI.CHECKPATCH: warning " Patchwork
@ 2018-04-23 20:32 ` Patchwork
  2018-04-23 20:46 ` ✗ Fi.CI.BAT: failure " Patchwork
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 20:32 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
URL   : https://patchwork.freedesktop.org/series/42139/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Commit: drm/i915: Stop tracking timeline->inflight_seqnos
-O:drivers/gpu/drm/i915/i915_request.c:268:13: error: undefined identifier '__builtin_add_overflow_p'
-O:drivers/gpu/drm/i915/i915_request.c:268:13: warning: call with no type!
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2211:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3659:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2212:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3660:16: warning: expression using sizeof(void)

Commit: drm/i915: Retire requests along rings
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2212:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3660:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2213:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3661:16: warning: expression using sizeof(void)

Commit: drm/i915: Only track live rings for retiring
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2213:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3661:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2214:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3662:16: warning: expression using sizeof(void)

Commit: drm/i915: Move timeline from GTT to ring
+  ^~~~~~~~~~
+  ^~~~~~~~~~
+                      ^
+                          ^
+                                          ^
+                                          ^
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1954:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1958:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1963:38: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2273:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2277:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2281:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:672:45:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:672:45:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:672:45: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/mmio.c:255:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/mmio.c:256:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/vgpu.c:144:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:144:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
+cc1: all warnings being treated as errors
+cc1: all warnings being treated as errors
+ # define unlikely(x) __builtin_expect(!!(x), 0)
+ # define unlikely(x) __builtin_expect(!!(x), 0)
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it

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

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

* ✗ Fi.CI.BAT: failure for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (9 preceding siblings ...)
  2018-04-23 20:32 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-04-23 20:46 ` Patchwork
  2018-04-23 23:53 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2) Patchwork
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 20:46 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos
URL   : https://patchwork.freedesktop.org/series/42139/
State : failure

== Summary ==

= CI Bug Log - changes from CI_DRM_4081 -> Patchwork_8777 =

== Summary - FAILURE ==

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

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

== Possible new issues ==

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

  === IGT changes ===

    ==== Possible regressions ====

    igt@gem_exec_suspend@basic-s3:
      fi-skl-guc:         PASS -> FAIL

    
== Known issues ==

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

  === IGT changes ===

    ==== Possible fixes ====

    igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
      fi-snb-2520m:       INCOMPLETE (fdo#103713) -> PASS

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


== Participating hosts (35 -> 33) ==

  Additional (1): fi-glk-j4005 
  Missing    (3): fi-ctg-p8600 fi-ilk-m540 fi-skl-6700hq 


== Build changes ==

    * Linux: CI_DRM_4081 -> Patchwork_8777

  CI_DRM_4081: fb7048acaac8ece5ebc53f9b748b76cdcef60fa3 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4444: dcc44347494231feabc588c2a76998cbc9afdf8c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_8777: 123351d9c80ef8286f1d8d12e5a1d06e707c87d3 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4444: a2f486679f467cd6e82578384f56d4aabaa8cf2e @ git://anongit.freedesktop.org/piglit


== Linux commits ==

123351d9c80e drm/i915: Lazily unbind vma on close
23a6561be624 drm/i915: Split i915_gem_timeline into individual timelines
38d2d82de298 drm/i915: Move timeline from GTT to ring
1cca0fbbe09b drm/i915: Only track live rings for retiring
f1d8ea9d3683 drm/i915: Retire requests along rings
397f93096828 drm/i915: Stop tracking timeline->inflight_seqnos


== Kernel 32bit build ==

Warning: Kernel 32bit buildtest failed:
https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8777/build_32bit_failure.log

== Logs ==

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

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

* [PATCH] drm/i915: Split i915_gem_timeline into individual timelines
  2018-04-23 18:08 ` [PATCH v2 5/6] drm/i915: Split i915_gem_timeline into individual timelines Chris Wilson
@ 2018-04-23 23:11   ` Chris Wilson
  0 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-23 23:11 UTC (permalink / raw)
  To: intel-gfx

We need to move to a more flexible timeline that doesn't assume one
fence context per engine, and so allow for a single timeline to be used
across a combination of engines. This means that preallocating a fence
context per engine is now a hindrance, and so we want to introduce the
singular timeline. From the code perspective, this has the notable
advantage of clearing up a lot of mirky semantics and some clumsy
pointer chasing.

By splitting the timeline up into a single entity rather than an array
of per-engine timelines, we can realise the goal of the previous patch
of tracking the timeline alongside the ring.

v2: Tweak wait_for_idle to stop the compiling thinking that ret may be
uninitialised.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |   2 +-
 drivers/gpu/drm/i915/i915_drv.h               |   4 +-
 drivers/gpu/drm/i915/i915_gem.c               | 129 +++++-------
 drivers/gpu/drm/i915/i915_gem_context.c       |  49 ++---
 drivers/gpu/drm/i915/i915_gem_context.h       |   2 -
 drivers/gpu/drm/i915/i915_gem_gtt.h           |   3 +-
 drivers/gpu/drm/i915/i915_gem_timeline.c      | 198 ------------------
 drivers/gpu/drm/i915/i915_gpu_error.c         |   4 +-
 drivers/gpu/drm/i915/i915_perf.c              |  10 +-
 drivers/gpu/drm/i915/i915_request.c           |  66 +++---
 drivers/gpu/drm/i915/i915_request.h           |   3 +-
 drivers/gpu/drm/i915/i915_timeline.c          | 105 ++++++++++
 .../{i915_gem_timeline.h => i915_timeline.h}  |  67 +++---
 drivers/gpu/drm/i915/intel_engine_cs.c        |  27 ++-
 drivers/gpu/drm/i915/intel_guc_submission.c   |   4 +-
 drivers/gpu/drm/i915/intel_lrc.c              |  48 +++--
 drivers/gpu/drm/i915/intel_ringbuffer.c       |  23 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h       |  11 +-
 .../{i915_gem_timeline.c => i915_timeline.c}  |  94 +++------
 drivers/gpu/drm/i915/selftests/mock_engine.c  |  32 ++-
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  10 +-
 .../gpu/drm/i915/selftests/mock_timeline.c    |  45 ++--
 .../gpu/drm/i915/selftests/mock_timeline.h    |  28 +--
 23 files changed, 396 insertions(+), 568 deletions(-)
 delete mode 100644 drivers/gpu/drm/i915/i915_gem_timeline.c
 create mode 100644 drivers/gpu/drm/i915/i915_timeline.c
 rename drivers/gpu/drm/i915/{i915_gem_timeline.h => i915_timeline.h} (68%)
 rename drivers/gpu/drm/i915/selftests/{i915_gem_timeline.c => i915_timeline.c} (70%)

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9bee52a949a9..120db21fcd50 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -67,11 +67,11 @@ i915-y += i915_cmd_parser.o \
 	  i915_gem_shrinker.o \
 	  i915_gem_stolen.o \
 	  i915_gem_tiling.o \
-	  i915_gem_timeline.o \
 	  i915_gem_userptr.o \
 	  i915_gemfs.o \
 	  i915_query.o \
 	  i915_request.o \
+	  i915_timeline.o \
 	  i915_trace_points.o \
 	  i915_vma.o \
 	  intel_breadcrumbs.o \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b9bd8328f501..dab15b6abc3c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -72,10 +72,10 @@
 #include "i915_gem_fence_reg.h"
 #include "i915_gem_object.h"
 #include "i915_gem_gtt.h"
-#include "i915_gem_timeline.h"
 #include "i915_gpu_error.h"
 #include "i915_request.h"
 #include "i915_scheduler.h"
+#include "i915_timeline.h"
 #include "i915_vma.h"
 
 #include "intel_gvt.h"
@@ -2058,8 +2058,6 @@ struct drm_i915_private {
 		void (*resume)(struct drm_i915_private *);
 		void (*cleanup_engine)(struct intel_engine_cs *engine);
 
-		struct i915_gem_timeline execution_timeline;
-		struct i915_gem_timeline legacy_timeline;
 		struct list_head timelines;
 
 		struct list_head active_rings;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index d60f3bd4bc66..44cf67f713c7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -162,7 +162,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 	synchronize_irq(i915->drm.irq);
 
 	intel_engines_park(i915);
-	i915_gem_timelines_park(i915);
+	i915_timelines_park(i915);
 
 	i915_pmu_gt_parked(i915);
 
@@ -2977,8 +2977,8 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
 	 * extra delay for a recent interrupt is pointless. Hence, we do
 	 * not need an engine->irq_seqno_barrier() before the seqno reads.
 	 */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
-	list_for_each_entry(request, &engine->timeline->requests, link) {
+	spin_lock_irqsave(&engine->timeline.lock, flags);
+	list_for_each_entry(request, &engine->timeline.requests, link) {
 		if (__i915_request_completed(request, request->global_seqno))
 			continue;
 
@@ -2989,7 +2989,7 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
 		active = request;
 		break;
 	}
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 
 	return active;
 }
@@ -3110,15 +3110,15 @@ static void engine_skip_context(struct i915_request *request)
 {
 	struct intel_engine_cs *engine = request->engine;
 	struct i915_gem_context *hung_ctx = request->ctx;
-	struct intel_timeline *timeline = request->timeline;
+	struct i915_timeline *timeline = request->timeline;
 	unsigned long flags;
 
-	GEM_BUG_ON(timeline == engine->timeline);
+	GEM_BUG_ON(timeline == &engine->timeline);
 
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 	spin_lock(&timeline->lock);
 
-	list_for_each_entry_continue(request, &engine->timeline->requests, link)
+	list_for_each_entry_continue(request, &engine->timeline.requests, link)
 		if (request->ctx == hung_ctx)
 			skip_request(request);
 
@@ -3126,7 +3126,7 @@ static void engine_skip_context(struct i915_request *request)
 		skip_request(request);
 
 	spin_unlock(&timeline->lock);
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 /* Returns the request if it was guilty of the hang */
@@ -3183,11 +3183,11 @@ i915_gem_reset_request(struct intel_engine_cs *engine,
 			dma_fence_set_error(&request->fence, -EAGAIN);
 
 			/* Rewind the engine to replay the incomplete rq */
-			spin_lock_irq(&engine->timeline->lock);
+			spin_lock_irq(&engine->timeline.lock);
 			request = list_prev_entry(request, link);
-			if (&request->link == &engine->timeline->requests)
+			if (&request->link == &engine->timeline.requests)
 				request = NULL;
-			spin_unlock_irq(&engine->timeline->lock);
+			spin_unlock_irq(&engine->timeline.lock);
 		}
 	}
 
@@ -3300,10 +3300,10 @@ static void nop_complete_submit_request(struct i915_request *request)
 		  request->fence.context, request->fence.seqno);
 	dma_fence_set_error(&request->fence, -EIO);
 
-	spin_lock_irqsave(&request->engine->timeline->lock, flags);
+	spin_lock_irqsave(&request->engine->timeline.lock, flags);
 	__i915_request_submit(request);
 	intel_engine_init_global_seqno(request->engine, request->global_seqno);
-	spin_unlock_irqrestore(&request->engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&request->engine->timeline.lock, flags);
 }
 
 void i915_gem_set_wedged(struct drm_i915_private *i915)
@@ -3372,10 +3372,10 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
 		 * (lockless) lookup doesn't try and wait upon the request as we
 		 * reset it.
 		 */
-		spin_lock_irqsave(&engine->timeline->lock, flags);
+		spin_lock_irqsave(&engine->timeline.lock, flags);
 		intel_engine_init_global_seqno(engine,
 					       intel_engine_last_submit(engine));
-		spin_unlock_irqrestore(&engine->timeline->lock, flags);
+		spin_unlock_irqrestore(&engine->timeline.lock, flags);
 
 		i915_gem_reset_finish_engine(engine);
 	}
@@ -3387,8 +3387,7 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
 
 bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 {
-	struct i915_gem_timeline *tl;
-	int i;
+	struct i915_timeline *tl;
 
 	lockdep_assert_held(&i915->drm.struct_mutex);
 	if (!test_bit(I915_WEDGED, &i915->gpu_error.flags))
@@ -3407,29 +3406,27 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
 	 * No more can be submitted until we reset the wedged bit.
 	 */
 	list_for_each_entry(tl, &i915->gt.timelines, link) {
-		for (i = 0; i < ARRAY_SIZE(tl->engine); i++) {
-			struct i915_request *rq;
+		struct i915_request *rq;
 
-			rq = i915_gem_active_peek(&tl->engine[i].last_request,
-						  &i915->drm.struct_mutex);
-			if (!rq)
-				continue;
+		rq = i915_gem_active_peek(&tl->last_request,
+					  &i915->drm.struct_mutex);
+		if (!rq)
+			continue;
 
-			/*
-			 * We can't use our normal waiter as we want to
-			 * avoid recursively trying to handle the current
-			 * reset. The basic dma_fence_default_wait() installs
-			 * a callback for dma_fence_signal(), which is
-			 * triggered by our nop handler (indirectly, the
-			 * callback enables the signaler thread which is
-			 * woken by the nop_submit_request() advancing the seqno
-			 * and when the seqno passes the fence, the signaler
-			 * then signals the fence waking us up).
-			 */
-			if (dma_fence_default_wait(&rq->fence, true,
-						   MAX_SCHEDULE_TIMEOUT) < 0)
-				return false;
-		}
+		/*
+		 * We can't use our normal waiter as we want to
+		 * avoid recursively trying to handle the current
+		 * reset. The basic dma_fence_default_wait() installs
+		 * a callback for dma_fence_signal(), which is
+		 * triggered by our nop handler (indirectly, the
+		 * callback enables the signaler thread which is
+		 * woken by the nop_submit_request() advancing the seqno
+		 * and when the seqno passes the fence, the signaler
+		 * then signals the fence waking us up).
+		 */
+		if (dma_fence_default_wait(&rq->fence, true,
+					   MAX_SCHEDULE_TIMEOUT) < 0)
+			return false;
 	}
 	i915_retire_requests(i915);
 	GEM_BUG_ON(i915->gt.active_requests);
@@ -3734,17 +3731,9 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 	return ret;
 }
 
-static int wait_for_timeline(struct i915_gem_timeline *tl, unsigned int flags)
+static int wait_for_timeline(struct i915_timeline *tl, unsigned int flags)
 {
-	int ret, i;
-
-	for (i = 0; i < ARRAY_SIZE(tl->engine); i++) {
-		ret = i915_gem_active_wait(&tl->engine[i].last_request, flags);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
+	return i915_gem_active_wait(&tl->last_request, flags);
 }
 
 static int wait_for_engines(struct drm_i915_private *i915)
@@ -3762,30 +3751,37 @@ static int wait_for_engines(struct drm_i915_private *i915)
 
 int i915_gem_wait_for_idle(struct drm_i915_private *i915, unsigned int flags)
 {
-	int ret;
-
 	/* If the device is asleep, we have no requests outstanding */
 	if (!READ_ONCE(i915->gt.awake))
 		return 0;
 
 	if (flags & I915_WAIT_LOCKED) {
-		struct i915_gem_timeline *tl;
+		struct i915_timeline *tl;
+		int err;
 
 		lockdep_assert_held(&i915->drm.struct_mutex);
 
 		list_for_each_entry(tl, &i915->gt.timelines, link) {
-			ret = wait_for_timeline(tl, flags);
-			if (ret)
-				return ret;
+			err = wait_for_timeline(tl, flags);
+			if (err)
+				return err;
 		}
 		i915_retire_requests(i915);
 
-		ret = wait_for_engines(i915);
+		return wait_for_engines(i915);
 	} else {
-		ret = wait_for_timeline(&i915->gt.execution_timeline, flags);
-	}
+		struct intel_engine_cs *engine;
+		enum intel_engine_id id;
+		int err;
 
-	return ret;
+		for_each_engine(engine, i915, id) {
+			err = wait_for_timeline(&engine->timeline, flags);
+			if (err)
+				return err;
+		}
+
+		return 0;
+	}
 }
 
 static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj)
@@ -4954,7 +4950,7 @@ static void assert_kernel_context_is_current(struct drm_i915_private *i915)
 	enum intel_engine_id id;
 
 	for_each_engine(engine, i915, id) {
-		GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline->last_request));
+		GEM_BUG_ON(__i915_gem_active_peek(&engine->timeline.last_request));
 		GEM_BUG_ON(engine->last_retired_context != kernel_context);
 	}
 }
@@ -5603,12 +5599,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 	INIT_LIST_HEAD(&dev_priv->gt.timelines);
 	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
 
-	mutex_lock(&dev_priv->drm.struct_mutex);
-	err = i915_gem_timeline_init__global(dev_priv);
-	mutex_unlock(&dev_priv->drm.struct_mutex);
-	if (err)
-		goto err_priorities;
-
 	i915_gem_init__mm(dev_priv);
 
 	INIT_DELAYED_WORK(&dev_priv->gt.retire_work,
@@ -5628,8 +5618,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 
 	return 0;
 
-err_priorities:
-	kmem_cache_destroy(dev_priv->priorities);
 err_dependencies:
 	kmem_cache_destroy(dev_priv->dependencies);
 err_requests:
@@ -5650,12 +5638,7 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
 	GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
 	GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
 	WARN_ON(dev_priv->mm.object_count);
-
-	mutex_lock(&dev_priv->drm.struct_mutex);
-	i915_gem_timeline_fini(&dev_priv->gt.legacy_timeline);
-	i915_gem_timeline_fini(&dev_priv->gt.execution_timeline);
 	WARN_ON(!list_empty(&dev_priv->gt.timelines));
-	mutex_unlock(&dev_priv->drm.struct_mutex);
 
 	kmem_cache_destroy(dev_priv->priorities);
 	kmem_cache_destroy(dev_priv->dependencies);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 58b185abe652..027b7ddae1d3 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -122,7 +122,6 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
 	lockdep_assert_held(&ctx->i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
 
-	i915_gem_timeline_free(ctx->timeline);
 	i915_ppgtt_put(ctx->ppgtt);
 
 	for (i = 0; i < I915_NUM_ENGINES; i++) {
@@ -377,18 +376,6 @@ i915_gem_create_context(struct drm_i915_private *dev_priv,
 		ctx->desc_template = default_desc_template(dev_priv, ppgtt);
 	}
 
-	if (HAS_EXECLISTS(dev_priv)) {
-		struct i915_gem_timeline *timeline;
-
-		timeline = i915_gem_timeline_create(dev_priv, ctx->name);
-		if (IS_ERR(timeline)) {
-			__destroy_hw_context(ctx, file_priv);
-			return ERR_CAST(timeline);
-		}
-
-		ctx->timeline = timeline;
-	}
-
 	trace_i915_context_create(ctx);
 
 	return ctx;
@@ -590,21 +577,30 @@ void i915_gem_context_close(struct drm_file *file)
 	idr_destroy(&file_priv->context_idr);
 }
 
-static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
+static struct i915_request *
+last_timeline_request(struct i915_timeline *timeline,
+		      struct intel_engine_cs *engine)
 {
-	struct i915_gem_timeline *timeline;
+	struct i915_request *rq;
 
-	list_for_each_entry(timeline, &engine->i915->gt.timelines, link) {
-		struct intel_timeline *tl;
+	if (timeline == &engine->timeline)
+		return NULL;
 
-		if (timeline == &engine->i915->gt.execution_timeline)
-			continue;
+	rq = i915_gem_active_raw(&timeline->last_request,
+				 &engine->i915->drm.struct_mutex);
+	if (rq && rq->engine == engine)
+		return rq;
+
+	return NULL;
+}
 
-		tl = &timeline->engine[engine->id];
-		if (i915_gem_active_peek(&tl->last_request,
-					 &engine->i915->drm.struct_mutex))
+static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
+{
+	struct i915_timeline *timeline;
+
+	list_for_each_entry(timeline, &engine->i915->gt.timelines, link)
+		if (last_timeline_request(timeline, engine))
 			return false;
-	}
 
 	return intel_engine_has_kernel_context(engine);
 }
@@ -612,7 +608,7 @@ static bool engine_has_idle_kernel_context(struct intel_engine_cs *engine)
 int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
 {
 	struct intel_engine_cs *engine;
-	struct i915_gem_timeline *timeline;
+	struct i915_timeline *timeline;
 	enum intel_engine_id id;
 
 	lockdep_assert_held(&dev_priv->drm.struct_mutex);
@@ -632,11 +628,8 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
 		/* Queue this switch after all other activity */
 		list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
 			struct i915_request *prev;
-			struct intel_timeline *tl;
 
-			tl = &timeline->engine[engine->id];
-			prev = i915_gem_active_raw(&tl->last_request,
-						   &dev_priv->drm.struct_mutex);
+			prev = last_timeline_request(timeline, engine);
 			if (prev)
 				i915_sw_fence_await_sw_fence_gfp(&rq->submit,
 								 &prev->submit,
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
index 140edcb424df..b12a8a8c5af9 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/i915_gem_context.h
@@ -58,8 +58,6 @@ struct i915_gem_context {
 	/** file_priv: owning file descriptor */
 	struct drm_i915_file_private *file_priv;
 
-	struct i915_gem_timeline *timeline;
-
 	/**
 	 * @ppgtt: unique address space (GTT)
 	 *
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 98107925de48..1db0dedb4059 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -38,10 +38,9 @@
 #include <linux/mm.h>
 #include <linux/pagevec.h>
 
-#include "i915_gem_timeline.h"
-
 #include "i915_request.h"
 #include "i915_selftest.h"
+#include "i915_timeline.h"
 
 #define I915_GTT_PAGE_SIZE_4K BIT(12)
 #define I915_GTT_PAGE_SIZE_64K BIT(16)
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
deleted file mode 100644
index 24f4068cc137..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright © 2016 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_drv.h"
-#include "i915_syncmap.h"
-
-static void __intel_timeline_init(struct intel_timeline *tl,
-				  struct i915_gem_timeline *parent,
-				  u64 context,
-				  struct lock_class_key *lockclass,
-				  const char *lockname)
-{
-	tl->fence_context = context;
-	tl->common = parent;
-	spin_lock_init(&tl->lock);
-	lockdep_set_class_and_name(&tl->lock, lockclass, lockname);
-	init_request_active(&tl->last_request, NULL);
-	INIT_LIST_HEAD(&tl->requests);
-	i915_syncmap_init(&tl->sync);
-}
-
-static void __intel_timeline_fini(struct intel_timeline *tl)
-{
-	GEM_BUG_ON(!list_empty(&tl->requests));
-
-	i915_syncmap_free(&tl->sync);
-}
-
-static int __i915_gem_timeline_init(struct drm_i915_private *i915,
-				    struct i915_gem_timeline *timeline,
-				    const char *name,
-				    struct lock_class_key *lockclass,
-				    const char *lockname)
-{
-	unsigned int i;
-	u64 fences;
-
-	lockdep_assert_held(&i915->drm.struct_mutex);
-
-	/*
-	 * Ideally we want a set of engines on a single leaf as we expect
-	 * to mostly be tracking synchronisation between engines. It is not
-	 * a huge issue if this is not the case, but we may want to mitigate
-	 * any page crossing penalties if they become an issue.
-	 */
-	BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
-
-	timeline->i915 = i915;
-	timeline->name = kstrdup(name ?: "[kernel]", GFP_KERNEL);
-	if (!timeline->name)
-		return -ENOMEM;
-
-	list_add(&timeline->link, &i915->gt.timelines);
-
-	/* Called during early_init before we know how many engines there are */
-	fences = dma_fence_context_alloc(ARRAY_SIZE(timeline->engine));
-	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
-		__intel_timeline_init(&timeline->engine[i],
-				      timeline, fences++,
-				      lockclass, lockname);
-
-	return 0;
-}
-
-int i915_gem_timeline_init(struct drm_i915_private *i915,
-			   struct i915_gem_timeline *timeline,
-			   const char *name)
-{
-	static struct lock_class_key class;
-
-	return __i915_gem_timeline_init(i915, timeline, name,
-					&class, "&timeline->lock");
-}
-
-int i915_gem_timeline_init__global(struct drm_i915_private *i915)
-{
-	static struct lock_class_key class1, class2;
-	int err;
-
-	err = __i915_gem_timeline_init(i915,
-				       &i915->gt.execution_timeline,
-				       "[execution]", &class1,
-				       "i915_execution_timeline");
-	if (err)
-		return err;
-
-	err = __i915_gem_timeline_init(i915,
-				       &i915->gt.legacy_timeline,
-				       "[global]", &class2,
-				       "i915_global_timeline");
-	if (err)
-		goto err_exec_timeline;
-
-	return 0;
-
-err_exec_timeline:
-	i915_gem_timeline_fini(&i915->gt.execution_timeline);
-	return err;
-}
-
-/**
- * i915_gem_timelines_park - called when the driver idles
- * @i915: the drm_i915_private device
- *
- * When the driver is completely idle, we know that all of our sync points
- * have been signaled and our tracking is then entirely redundant. Any request
- * to wait upon an older sync point will be completed instantly as we know
- * the fence is signaled and therefore we will not even look them up in the
- * sync point map.
- */
-void i915_gem_timelines_park(struct drm_i915_private *i915)
-{
-	struct i915_gem_timeline *timeline;
-	int i;
-
-	lockdep_assert_held(&i915->drm.struct_mutex);
-
-	list_for_each_entry(timeline, &i915->gt.timelines, link) {
-		for (i = 0; i < ARRAY_SIZE(timeline->engine); i++) {
-			struct intel_timeline *tl = &timeline->engine[i];
-
-			/*
-			 * All known fences are completed so we can scrap
-			 * the current sync point tracking and start afresh,
-			 * any attempt to wait upon a previous sync point
-			 * will be skipped as the fence was signaled.
-			 */
-			i915_syncmap_free(&tl->sync);
-		}
-	}
-}
-
-void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
-{
-	int i;
-
-	lockdep_assert_held(&timeline->i915->drm.struct_mutex);
-
-	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
-		__intel_timeline_fini(&timeline->engine[i]);
-
-	list_del(&timeline->link);
-	kfree(timeline->name);
-}
-
-struct i915_gem_timeline *
-i915_gem_timeline_create(struct drm_i915_private *i915, const char *name)
-{
-	struct i915_gem_timeline *timeline;
-	int err;
-
-	timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
-	if (!timeline)
-		return ERR_PTR(-ENOMEM);
-
-	err = i915_gem_timeline_init(i915, timeline, name);
-	if (err) {
-		kfree(timeline);
-		return ERR_PTR(err);
-	}
-
-	return timeline;
-}
-
-void i915_gem_timeline_free(struct i915_gem_timeline *timeline)
-{
-	if (!timeline)
-		return;
-
-	i915_gem_timeline_fini(timeline);
-	kfree(timeline);
-}
-
-#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
-#include "selftests/mock_timeline.c"
-#include "selftests/i915_gem_timeline.c"
-#endif
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 671ffa37614e..71bb8230cb97 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1299,7 +1299,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
 
 	count = 0;
 	request = first;
-	list_for_each_entry_from(request, &engine->timeline->requests, link)
+	list_for_each_entry_from(request, &engine->timeline.requests, link)
 		count++;
 	if (!count)
 		return;
@@ -1312,7 +1312,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
 
 	count = 0;
 	request = first;
-	list_for_each_entry_from(request, &engine->timeline->requests, link) {
+	list_for_each_entry_from(request, &engine->timeline.requests, link) {
 		if (count >= ee->num_requests) {
 			/*
 			 * If the ring request list was changed in
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index bfc906cd4e5e..5dcd76e27c68 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -1695,7 +1695,7 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
 						 const struct i915_oa_config *oa_config)
 {
 	struct intel_engine_cs *engine = dev_priv->engine[RCS];
-	struct i915_gem_timeline *timeline;
+	struct i915_timeline *timeline;
 	struct i915_request *rq;
 	int ret;
 
@@ -1716,15 +1716,11 @@ static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_pr
 	/* Queue this switch after all other activity */
 	list_for_each_entry(timeline, &dev_priv->gt.timelines, link) {
 		struct i915_request *prev;
-		struct intel_timeline *tl;
 
-		tl = &timeline->engine[engine->id];
-		prev = i915_gem_active_raw(&tl->last_request,
+		prev = i915_gem_active_raw(&timeline->last_request,
 					   &dev_priv->drm.struct_mutex);
 		if (prev)
-			i915_sw_fence_await_sw_fence_gfp(&rq->submit,
-							 &prev->submit,
-							 GFP_KERNEL);
+			i915_request_await_dma_fence(rq, &prev->fence);
 	}
 
 	i915_request_add(rq);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 55d23c53132a..5035a8cce77b 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -49,7 +49,7 @@ static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
 	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
 		return "signaled";
 
-	return to_request(fence)->timeline->common->name;
+	return to_request(fence)->timeline->name;
 }
 
 static bool i915_fence_signaled(struct dma_fence *fence)
@@ -199,6 +199,7 @@ i915_sched_node_init(struct i915_sched_node *node)
 static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 {
 	struct intel_engine_cs *engine;
+	struct i915_timeline *timeline;
 	enum intel_engine_id id;
 	int ret;
 
@@ -213,16 +214,13 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 
 	/* If the seqno wraps around, we need to clear the breadcrumb rbtree */
 	for_each_engine(engine, i915, id) {
-		struct i915_gem_timeline *timeline;
-		struct intel_timeline *tl = engine->timeline;
-
 		GEM_TRACE("%s seqno %d (current %d) -> %d\n",
 			  engine->name,
-			  tl->seqno,
+			  engine->timeline.seqno,
 			  intel_engine_get_seqno(engine),
 			  seqno);
 
-		if (!i915_seqno_passed(seqno, tl->seqno)) {
+		if (!i915_seqno_passed(seqno, engine->timeline.seqno)) {
 			/* Flush any waiters before we reuse the seqno */
 			intel_engine_disarm_breadcrumbs(engine);
 			GEM_BUG_ON(!list_empty(&engine->breadcrumbs.signals));
@@ -230,18 +228,18 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
 
 		/* Check we are idle before we fiddle with hw state! */
 		GEM_BUG_ON(!intel_engine_is_idle(engine));
-		GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
+		GEM_BUG_ON(i915_gem_active_isset(&engine->timeline.last_request));
 
 		/* Finally reset hw state */
 		intel_engine_init_global_seqno(engine, seqno);
-		tl->seqno = seqno;
-
-		list_for_each_entry(timeline, &i915->gt.timelines, link)
-			memset(timeline->engine[id].global_sync, 0,
-			       sizeof(timeline->engine[id].global_sync));
+		engine->timeline.seqno = seqno;
 	}
 
+	list_for_each_entry(timeline, &i915->gt.timelines, link)
+		memset(timeline->global_sync, 0, sizeof(timeline->global_sync));
+
 	i915->gt.request_serial = seqno;
+
 	return 0;
 }
 
@@ -349,10 +347,10 @@ static void __request_retire__engine(struct i915_request *request)
 
 	local_irq_disable();
 
-	spin_lock(&engine->timeline->lock);
-	GEM_BUG_ON(!list_is_first(&request->link, &engine->timeline->requests));
+	spin_lock(&engine->timeline.lock);
+	GEM_BUG_ON(!list_is_first(&request->link, &engine->timeline.requests));
 	list_del_init(&request->link);
-	spin_unlock(&engine->timeline->lock);
+	spin_unlock(&engine->timeline.lock);
 
 	spin_lock(&request->lock);
 	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags))
@@ -389,7 +387,7 @@ static void __retire_engine_upto(struct intel_engine_cs *engine,
 		return;
 
 	do {
-		tmp = list_first_entry(&engine->timeline->requests,
+		tmp = list_first_entry(&engine->timeline.requests,
 				       typeof(*tmp), link);
 
 		__request_retire__engine(tmp);
@@ -479,16 +477,16 @@ void i915_request_retire_upto(struct i915_request *rq)
 	} while (tmp != rq);
 }
 
-static u32 timeline_get_seqno(struct intel_timeline *tl)
+static u32 timeline_get_seqno(struct i915_timeline *tl)
 {
 	return ++tl->seqno;
 }
 
 static void move_to_timeline(struct i915_request *request,
-			     struct intel_timeline *timeline)
+			     struct i915_timeline *timeline)
 {
-	GEM_BUG_ON(request->timeline == request->engine->timeline);
-	lockdep_assert_held(&request->engine->timeline->lock);
+	GEM_BUG_ON(request->timeline == &request->engine->timeline);
+	lockdep_assert_held(&request->engine->timeline.lock);
 
 	spin_lock(&request->timeline->lock);
 	list_move_tail(&request->link, &timeline->requests);
@@ -503,15 +501,15 @@ void __i915_request_submit(struct i915_request *request)
 	GEM_TRACE("%s fence %llx:%d -> global=%d, current %d\n",
 		  engine->name,
 		  request->fence.context, request->fence.seqno,
-		  engine->timeline->seqno + 1,
+		  engine->timeline.seqno + 1,
 		  intel_engine_get_seqno(engine));
 
 	GEM_BUG_ON(!irqs_disabled());
-	lockdep_assert_held(&engine->timeline->lock);
+	lockdep_assert_held(&engine->timeline.lock);
 
 	GEM_BUG_ON(request->global_seqno);
 
-	seqno = timeline_get_seqno(engine->timeline);
+	seqno = timeline_get_seqno(&engine->timeline);
 	GEM_BUG_ON(!seqno);
 	GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine), seqno));
 
@@ -526,7 +524,7 @@ void __i915_request_submit(struct i915_request *request)
 				request->ring->vaddr + request->postfix);
 
 	/* Transfer from per-context onto the global per-engine timeline */
-	move_to_timeline(request, engine->timeline);
+	move_to_timeline(request, &engine->timeline);
 
 	trace_i915_request_execute(request);
 
@@ -539,11 +537,11 @@ void i915_request_submit(struct i915_request *request)
 	unsigned long flags;
 
 	/* Will be called from irq-context when using foreign fences. */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	__i915_request_submit(request);
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 void __i915_request_unsubmit(struct i915_request *request)
@@ -557,17 +555,17 @@ void __i915_request_unsubmit(struct i915_request *request)
 		  intel_engine_get_seqno(engine));
 
 	GEM_BUG_ON(!irqs_disabled());
-	lockdep_assert_held(&engine->timeline->lock);
+	lockdep_assert_held(&engine->timeline.lock);
 
 	/*
 	 * Only unwind in reverse order, required so that the per-context list
 	 * is kept in seqno/ring order.
 	 */
 	GEM_BUG_ON(!request->global_seqno);
-	GEM_BUG_ON(request->global_seqno != engine->timeline->seqno);
+	GEM_BUG_ON(request->global_seqno != engine->timeline.seqno);
 	GEM_BUG_ON(i915_seqno_passed(intel_engine_get_seqno(engine),
 				     request->global_seqno));
-	engine->timeline->seqno--;
+	engine->timeline.seqno--;
 
 	/* We may be recursing from the signal callback of another i915 fence */
 	spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
@@ -594,11 +592,11 @@ void i915_request_unsubmit(struct i915_request *request)
 	unsigned long flags;
 
 	/* Will be called from irq-context when using foreign fences. */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	__i915_request_unsubmit(request);
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 static int __i915_sw_fence_call
@@ -914,7 +912,7 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
 
 		/* Squash repeated waits to the same timelines */
 		if (fence->context != rq->i915->mm.unordered_timeline &&
-		    intel_timeline_sync_is_later(rq->timeline, fence))
+		    i915_timeline_sync_is_later(rq->timeline, fence))
 			continue;
 
 		if (dma_fence_is_i915(fence))
@@ -928,7 +926,7 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence)
 
 		/* Record the latest fence used against each timeline */
 		if (fence->context != rq->i915->mm.unordered_timeline)
-			intel_timeline_sync_set(rq->timeline, fence);
+			i915_timeline_sync_set(rq->timeline, fence);
 	} while (--nchild);
 
 	return 0;
@@ -1005,7 +1003,7 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
 {
 	struct intel_engine_cs *engine = request->engine;
 	struct intel_ring *ring = request->ring;
-	struct intel_timeline *timeline = request->timeline;
+	struct i915_timeline *timeline = request->timeline;
 	struct i915_request *prev;
 	u32 *cs;
 	int err;
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 8f31ca8272f8..eddbd4245cb3 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -37,6 +37,7 @@
 struct drm_file;
 struct drm_i915_gem_object;
 struct i915_request;
+struct i915_timeline;
 
 struct intel_wait {
 	struct rb_node node;
@@ -95,7 +96,7 @@ struct i915_request {
 	struct i915_gem_context *ctx;
 	struct intel_engine_cs *engine;
 	struct intel_ring *ring;
-	struct intel_timeline *timeline;
+	struct i915_timeline *timeline;
 	struct intel_signal_node signaling;
 
 	/*
diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c
new file mode 100644
index 000000000000..4667cc08c416
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_timeline.c
@@ -0,0 +1,105 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2016-2018 Intel Corporation
+ */
+
+#include "i915_drv.h"
+
+#include "i915_timeline.h"
+#include "i915_syncmap.h"
+
+void i915_timeline_init(struct drm_i915_private *i915,
+			struct i915_timeline *timeline,
+			const char *name)
+{
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	/*
+	 * Ideally we want a set of engines on a single leaf as we expect
+	 * to mostly be tracking synchronisation between engines. It is not
+	 * a huge issue if this is not the case, but we may want to mitigate
+	 * any page crossing penalties if they become an issue.
+	 */
+	BUILD_BUG_ON(KSYNCMAP < I915_NUM_ENGINES);
+
+	timeline->name = name;
+
+	list_add(&timeline->link, &i915->gt.timelines);
+
+	/* Called during early_init before we know how many engines there are */
+
+	timeline->fence_context = dma_fence_context_alloc(1);
+
+	spin_lock_init(&timeline->lock);
+
+	init_request_active(&timeline->last_request, NULL);
+	INIT_LIST_HEAD(&timeline->requests);
+
+	i915_syncmap_init(&timeline->sync);
+}
+
+/**
+ * i915_timelines_park - called when the driver idles
+ * @i915: the drm_i915_private device
+ *
+ * When the driver is completely idle, we know that all of our sync points
+ * have been signaled and our tracking is then entirely redundant. Any request
+ * to wait upon an older sync point will be completed instantly as we know
+ * the fence is signaled and therefore we will not even look them up in the
+ * sync point map.
+ */
+void i915_timelines_park(struct drm_i915_private *i915)
+{
+	struct i915_timeline *timeline;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+
+	list_for_each_entry(timeline, &i915->gt.timelines, link) {
+		/*
+		 * All known fences are completed so we can scrap
+		 * the current sync point tracking and start afresh,
+		 * any attempt to wait upon a previous sync point
+		 * will be skipped as the fence was signaled.
+		 */
+		i915_syncmap_free(&timeline->sync);
+	}
+}
+
+void i915_timeline_fini(struct i915_timeline *timeline)
+{
+	GEM_BUG_ON(!list_empty(&timeline->requests));
+
+	i915_syncmap_free(&timeline->sync);
+
+	list_del(&timeline->link);
+}
+
+struct i915_timeline *
+i915_timeline_create(struct drm_i915_private *i915, const char *name)
+{
+	struct i915_timeline *timeline;
+
+	timeline = kzalloc(sizeof(*timeline), GFP_KERNEL);
+	if (!timeline)
+		return ERR_PTR(-ENOMEM);
+
+	i915_timeline_init(i915, timeline, name);
+	kref_init(&timeline->kref);
+
+	return timeline;
+}
+
+void __i915_timeline_free(struct kref *kref)
+{
+	struct i915_timeline *timeline =
+		container_of(kref, typeof(*timeline), kref);
+
+	i915_timeline_fini(timeline);
+	kfree(timeline);
+}
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftests/mock_timeline.c"
+#include "selftests/i915_timeline.c"
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h
similarity index 68%
rename from drivers/gpu/drm/i915/i915_gem_timeline.h
rename to drivers/gpu/drm/i915/i915_timeline.h
index 780ed465c4fc..dc2a4632faa7 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_timeline.h
@@ -22,18 +22,17 @@
  *
  */
 
-#ifndef I915_GEM_TIMELINE_H
-#define I915_GEM_TIMELINE_H
+#ifndef I915_TIMELINE_H
+#define I915_TIMELINE_H
 
 #include <linux/list.h>
+#include <linux/kref.h>
 
 #include "i915_request.h"
 #include "i915_syncmap.h"
 #include "i915_utils.h"
 
-struct i915_gem_timeline;
-
-struct intel_timeline {
+struct i915_timeline {
 	u64 fence_context;
 	u32 seqno;
 
@@ -71,51 +70,57 @@ struct intel_timeline {
 	 */
 	u32 global_sync[I915_NUM_ENGINES];
 
-	struct i915_gem_timeline *common;
-};
-
-struct i915_gem_timeline {
 	struct list_head link;
-
-	struct drm_i915_private *i915;
 	const char *name;
 
-	struct intel_timeline engine[I915_NUM_ENGINES];
+	struct kref kref;
 };
 
-int i915_gem_timeline_init(struct drm_i915_private *i915,
-			   struct i915_gem_timeline *tl,
-			   const char *name);
-int i915_gem_timeline_init__global(struct drm_i915_private *i915);
-void i915_gem_timelines_park(struct drm_i915_private *i915);
-void i915_gem_timeline_fini(struct i915_gem_timeline *tl);
+void i915_timeline_init(struct drm_i915_private *i915,
+			struct i915_timeline *tl,
+			const char *name);
+void i915_timeline_fini(struct i915_timeline *tl);
 
-struct i915_gem_timeline *
-i915_gem_timeline_create(struct drm_i915_private *i915, const char *name);
-void i915_gem_timeline_free(struct i915_gem_timeline *timeline);
+struct i915_timeline *
+i915_timeline_create(struct drm_i915_private *i915, const char *name);
 
-static inline int __intel_timeline_sync_set(struct intel_timeline *tl,
-					    u64 context, u32 seqno)
+static inline struct i915_timeline *
+i915_timeline_get(struct i915_timeline *timeline)
+{
+	kref_get(&timeline->kref);
+	return timeline;
+}
+
+void __i915_timeline_free(struct kref *kref);
+static inline void i915_timeline_put(struct i915_timeline *timeline)
+{
+	kref_put(&timeline->kref, __i915_timeline_free);
+}
+
+static inline int __i915_timeline_sync_set(struct i915_timeline *tl,
+					   u64 context, u32 seqno)
 {
 	return i915_syncmap_set(&tl->sync, context, seqno);
 }
 
-static inline int intel_timeline_sync_set(struct intel_timeline *tl,
-					  const struct dma_fence *fence)
+static inline int i915_timeline_sync_set(struct i915_timeline *tl,
+					 const struct dma_fence *fence)
 {
-	return __intel_timeline_sync_set(tl, fence->context, fence->seqno);
+	return __i915_timeline_sync_set(tl, fence->context, fence->seqno);
 }
 
-static inline bool __intel_timeline_sync_is_later(struct intel_timeline *tl,
-						  u64 context, u32 seqno)
+static inline bool __i915_timeline_sync_is_later(struct i915_timeline *tl,
+						 u64 context, u32 seqno)
 {
 	return i915_syncmap_is_later(&tl->sync, context, seqno);
 }
 
-static inline bool intel_timeline_sync_is_later(struct intel_timeline *tl,
-						const struct dma_fence *fence)
+static inline bool i915_timeline_sync_is_later(struct i915_timeline *tl,
+					       const struct dma_fence *fence)
 {
-	return __intel_timeline_sync_is_later(tl, fence->context, fence->seqno);
+	return __i915_timeline_sync_is_later(tl, fence->context, fence->seqno);
 }
 
+void i915_timelines_park(struct drm_i915_private *i915);
+
 #endif
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index d44a8eb83379..dcfdd4439935 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -451,12 +451,6 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
 	GEM_BUG_ON(intel_engine_get_seqno(engine) != seqno);
 }
 
-static void intel_engine_init_timeline(struct intel_engine_cs *engine)
-{
-	engine->timeline =
-		&engine->i915->gt.execution_timeline.engine[engine->id];
-}
-
 static void intel_engine_init_batch_pool(struct intel_engine_cs *engine)
 {
 	i915_gem_batch_pool_init(&engine->batch_pool, engine);
@@ -508,8 +502,9 @@ static void intel_engine_init_execlist(struct intel_engine_cs *engine)
  */
 void intel_engine_setup_common(struct intel_engine_cs *engine)
 {
+	i915_timeline_init(engine->i915, &engine->timeline, engine->name);
+
 	intel_engine_init_execlist(engine);
-	intel_engine_init_timeline(engine);
 	intel_engine_init_hangcheck(engine);
 	intel_engine_init_batch_pool(engine);
 	intel_engine_init_cmd_parser(engine);
@@ -757,6 +752,8 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
 	if (engine->i915->preempt_context)
 		engine->context_unpin(engine, engine->i915->preempt_context);
 	engine->context_unpin(engine, engine->i915->kernel_context);
+
+	i915_timeline_fini(&engine->timeline);
 }
 
 u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
@@ -1009,7 +1006,7 @@ bool intel_engine_has_kernel_context(const struct intel_engine_cs *engine)
 	 * the last request that remains in the timeline. When idle, it is
 	 * the last executed context as tracked by retirement.
 	 */
-	rq = __i915_gem_active_peek(&engine->timeline->last_request);
+	rq = __i915_gem_active_peek(&engine->timeline.last_request);
 	if (rq)
 		return rq->ctx == kernel_context;
 	else
@@ -1332,14 +1329,14 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 
 	drm_printf(m, "\tRequests:\n");
 
-	rq = list_first_entry(&engine->timeline->requests,
+	rq = list_first_entry(&engine->timeline.requests,
 			      struct i915_request, link);
-	if (&rq->link != &engine->timeline->requests)
+	if (&rq->link != &engine->timeline.requests)
 		print_request(m, rq, "\t\tfirst  ");
 
-	rq = list_last_entry(&engine->timeline->requests,
+	rq = list_last_entry(&engine->timeline.requests,
 			     struct i915_request, link);
-	if (&rq->link != &engine->timeline->requests)
+	if (&rq->link != &engine->timeline.requests)
 		print_request(m, rq, "\t\tlast   ");
 
 	rq = i915_gem_find_active_request(engine);
@@ -1371,8 +1368,8 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 		drm_printf(m, "\tDevice is asleep; skipping register dump\n");
 	}
 
-	spin_lock_irq(&engine->timeline->lock);
-	list_for_each_entry(rq, &engine->timeline->requests, link)
+	spin_lock_irq(&engine->timeline.lock);
+	list_for_each_entry(rq, &engine->timeline.requests, link)
 		print_request(m, rq, "\t\tE ");
 	drm_printf(m, "\t\tQueue priority: %d\n", execlists->queue_priority);
 	for (rb = execlists->first; rb; rb = rb_next(rb)) {
@@ -1382,7 +1379,7 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 		list_for_each_entry(rq, &p->requests, sched.link)
 			print_request(m, rq, "\t\tQ ");
 	}
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 
 	spin_lock_irq(&b->rb_lock);
 	for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index 02da05875aa7..cb4fcde1ffdc 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -677,7 +677,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
 	bool submit = false;
 	struct rb_node *rb;
 
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 	rb = execlists->first;
 	GEM_BUG_ON(rb_first(&execlists->queue) != rb);
 
@@ -748,7 +748,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
 	GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
 
 unlock:
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 }
 
 static void guc_submission_tasklet(unsigned long data)
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index fd3539034665..fa802d791804 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -330,10 +330,10 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine)
 	struct i915_priolist *uninitialized_var(p);
 	int last_prio = I915_PRIORITY_INVALID;
 
-	lockdep_assert_held(&engine->timeline->lock);
+	lockdep_assert_held(&engine->timeline.lock);
 
 	list_for_each_entry_safe_reverse(rq, rn,
-					 &engine->timeline->requests,
+					 &engine->timeline.requests,
 					 link) {
 		if (i915_request_completed(rq))
 			return;
@@ -357,9 +357,9 @@ execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists)
 	struct intel_engine_cs *engine =
 		container_of(execlists, typeof(*engine), execlists);
 
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 	__unwind_incomplete_requests(engine);
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 }
 
 static inline void
@@ -583,7 +583,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 	 * and context switches) submission.
 	 */
 
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 	rb = execlists->first;
 	GEM_BUG_ON(rb_first(&execlists->queue) != rb);
 
@@ -743,7 +743,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 	GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
 
 unlock:
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 
 	if (submit) {
 		execlists_user_begin(execlists, execlists->port);
@@ -868,10 +868,10 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
 	execlists_cancel_port_requests(execlists);
 	reset_irq(engine);
 
-	spin_lock(&engine->timeline->lock);
+	spin_lock(&engine->timeline.lock);
 
 	/* Mark all executing requests as skipped. */
-	list_for_each_entry(rq, &engine->timeline->requests, link) {
+	list_for_each_entry(rq, &engine->timeline.requests, link) {
 		GEM_BUG_ON(!rq->global_seqno);
 		if (!i915_request_completed(rq))
 			dma_fence_set_error(&rq->fence, -EIO);
@@ -903,7 +903,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine)
 	execlists->first = NULL;
 	GEM_BUG_ON(port_isset(execlists->port));
 
-	spin_unlock(&engine->timeline->lock);
+	spin_unlock(&engine->timeline.lock);
 
 	local_irq_restore(flags);
 }
@@ -1141,7 +1141,7 @@ static void execlists_submit_request(struct i915_request *request)
 	unsigned long flags;
 
 	/* Will be called from irq-context when using foreign fences. */
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	queue_request(engine, &request->sched, rq_prio(request));
 	submit_queue(engine, rq_prio(request));
@@ -1149,7 +1149,7 @@ static void execlists_submit_request(struct i915_request *request)
 	GEM_BUG_ON(!engine->execlists.first);
 	GEM_BUG_ON(list_empty(&request->sched.link));
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 static struct i915_request *sched_to_request(struct i915_sched_node *node)
@@ -1165,8 +1165,8 @@ sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
 	GEM_BUG_ON(!locked);
 
 	if (engine != locked) {
-		spin_unlock(&locked->timeline->lock);
-		spin_lock(&engine->timeline->lock);
+		spin_unlock(&locked->timeline.lock);
+		spin_lock(&engine->timeline.lock);
 	}
 
 	return engine;
@@ -1249,7 +1249,7 @@ static void execlists_schedule(struct i915_request *request,
 	}
 
 	engine = request->engine;
-	spin_lock_irq(&engine->timeline->lock);
+	spin_lock_irq(&engine->timeline.lock);
 
 	/* Fifo and depth-first replacement ensure our deps execute before us */
 	list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) {
@@ -1273,7 +1273,7 @@ static void execlists_schedule(struct i915_request *request,
 			__submit_queue(engine, prio);
 	}
 
-	spin_unlock_irq(&engine->timeline->lock);
+	spin_unlock_irq(&engine->timeline.lock);
 }
 
 static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma)
@@ -1802,9 +1802,9 @@ static void reset_common_ring(struct intel_engine_cs *engine,
 	reset_irq(engine);
 
 	/* Push back any incomplete requests for replay after the reset. */
-	spin_lock(&engine->timeline->lock);
+	spin_lock(&engine->timeline.lock);
 	__unwind_incomplete_requests(engine);
-	spin_unlock(&engine->timeline->lock);
+	spin_unlock(&engine->timeline.lock);
 
 	local_irq_restore(flags);
 
@@ -2559,6 +2559,7 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 	struct i915_vma *vma;
 	uint32_t context_size;
 	struct intel_ring *ring;
+	struct i915_timeline *timeline;
 	int ret;
 
 	if (ce->state)
@@ -2574,8 +2575,8 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 
 	ctx_obj = i915_gem_object_create(ctx->i915, context_size);
 	if (IS_ERR(ctx_obj)) {
-		DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n");
-		return PTR_ERR(ctx_obj);
+		ret = PTR_ERR(ctx_obj);
+		goto error_deref_obj;
 	}
 
 	vma = i915_vma_instance(ctx_obj, &ctx->i915->ggtt.base, NULL);
@@ -2584,7 +2585,14 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
 		goto error_deref_obj;
 	}
 
-	ring = intel_engine_create_ring(engine, ctx->timeline, ctx->ring_size);
+	timeline = i915_timeline_create(ctx->i915, ctx->name);
+	if (IS_ERR(timeline)) {
+		ret = PTR_ERR(timeline);
+		goto error_deref_obj;
+	}
+
+	ring = intel_engine_create_ring(engine, timeline, ctx->ring_size);
+	i915_timeline_put(timeline);
 	if (IS_ERR(ring)) {
 		ret = PTR_ERR(ring);
 		goto error_deref_obj;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 47009695b378..823cf49f1887 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -696,17 +696,17 @@ static void cancel_requests(struct intel_engine_cs *engine)
 	struct i915_request *request;
 	unsigned long flags;
 
-	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock_irqsave(&engine->timeline.lock, flags);
 
 	/* Mark all submitted requests as skipped. */
-	list_for_each_entry(request, &engine->timeline->requests, link) {
+	list_for_each_entry(request, &engine->timeline.requests, link) {
 		GEM_BUG_ON(!request->global_seqno);
 		if (!i915_request_completed(request))
 			dma_fence_set_error(&request->fence, -EIO);
 	}
 	/* Remaining _unready_ requests will be nop'ed when submitted */
 
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	spin_unlock_irqrestore(&engine->timeline.lock, flags);
 }
 
 static void i9xx_submit_request(struct i915_request *request)
@@ -1117,7 +1117,7 @@ intel_ring_create_vma(struct drm_i915_private *dev_priv, int size)
 
 struct intel_ring *
 intel_engine_create_ring(struct intel_engine_cs *engine,
-			 struct i915_gem_timeline *timeline,
+			 struct i915_timeline *timeline,
 			 int size)
 {
 	struct intel_ring *ring;
@@ -1133,7 +1133,7 @@ intel_engine_create_ring(struct intel_engine_cs *engine,
 		return ERR_PTR(-ENOMEM);
 
 	INIT_LIST_HEAD(&ring->request_list);
-	ring->timeline = &timeline->engine[engine->id];
+	ring->timeline = i915_timeline_get(timeline);
 
 	ring->size = size;
 	/* Workaround an erratum on the i830 which causes a hang if
@@ -1164,6 +1164,7 @@ intel_ring_free(struct intel_ring *ring)
 	i915_vma_close(ring->vma);
 	__i915_gem_object_release_unless_active(obj);
 
+	i915_timeline_put(ring->timeline);
 	kfree(ring);
 }
 
@@ -1322,6 +1323,7 @@ static void intel_ring_context_unpin(struct intel_engine_cs *engine,
 static int intel_init_ring_buffer(struct intel_engine_cs *engine)
 {
 	struct intel_ring *ring;
+	struct i915_timeline *timeline;
 	int err;
 
 	intel_engine_setup_common(engine);
@@ -1330,9 +1332,14 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
 	if (err)
 		goto err;
 
-	ring = intel_engine_create_ring(engine,
-					&engine->i915->gt.legacy_timeline,
-					32 * PAGE_SIZE);
+	timeline = i915_timeline_create(engine->i915, engine->name);
+	if (IS_ERR(timeline)) {
+		err = PTR_ERR(timeline);
+		goto err;
+	}
+
+	ring = intel_engine_create_ring(engine, timeline, 32 * PAGE_SIZE);
+	i915_timeline_put(timeline);
 	if (IS_ERR(ring)) {
 		err = PTR_ERR(ring);
 		goto err;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index b3c3f8f47f38..569b3203e123 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -5,12 +5,12 @@
 #include <linux/hashtable.h>
 
 #include "i915_gem_batch_pool.h"
-#include "i915_gem_timeline.h"
 
 #include "i915_reg.h"
 #include "i915_pmu.h"
 #include "i915_request.h"
 #include "i915_selftest.h"
+#include "i915_timeline.h"
 #include "intel_gpu_commands.h"
 
 struct drm_printer;
@@ -128,7 +128,7 @@ struct intel_ring {
 	struct i915_vma *vma;
 	void *vaddr;
 
-	struct intel_timeline *timeline;
+	struct i915_timeline *timeline;
 	struct list_head request_list;
 	struct list_head active_link;
 
@@ -337,7 +337,8 @@ struct intel_engine_cs {
 	u32 mmio_base;
 
 	struct intel_ring *buffer;
-	struct intel_timeline *timeline;
+
+	struct i915_timeline timeline;
 
 	struct drm_i915_gem_object *default_state;
 
@@ -769,7 +770,7 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 
 struct intel_ring *
 intel_engine_create_ring(struct intel_engine_cs *engine,
-			 struct i915_gem_timeline *timeline,
+			 struct i915_timeline *timeline,
 			 int size);
 int intel_ring_pin(struct intel_ring *ring,
 		   struct drm_i915_private *i915,
@@ -888,7 +889,7 @@ static inline u32 intel_engine_last_submit(struct intel_engine_cs *engine)
 	 * wtih serialising this hint with anything, so document it as
 	 * a hint and nothing more.
 	 */
-	return READ_ONCE(engine->timeline->seqno);
+	return READ_ONCE(engine->timeline.seqno);
 }
 
 void intel_engine_get_instdone(struct intel_engine_cs *engine,
diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c b/drivers/gpu/drm/i915/selftests/i915_timeline.c
similarity index 70%
rename from drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
rename to drivers/gpu/drm/i915/selftests/i915_timeline.c
index 3000e6a7d82d..19f1c6a5c8fb 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/selftests/i915_timeline.c
@@ -1,25 +1,7 @@
 /*
- * 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.
+ * SPDX-License-Identifier: MIT
  *
+ * Copyright © 2017-2018 Intel Corporation
  */
 
 #include "../i915_selftest.h"
@@ -35,21 +17,21 @@ struct __igt_sync {
 	bool set;
 };
 
-static int __igt_sync(struct intel_timeline *tl,
+static int __igt_sync(struct i915_timeline *tl,
 		      u64 ctx,
 		      const struct __igt_sync *p,
 		      const char *name)
 {
 	int ret;
 
-	if (__intel_timeline_sync_is_later(tl, ctx, p->seqno) != p->expected) {
+	if (__i915_timeline_sync_is_later(tl, ctx, p->seqno) != p->expected) {
 		pr_err("%s: %s(ctx=%llu, seqno=%u) expected passed %s but failed\n",
 		       name, p->name, ctx, p->seqno, yesno(p->expected));
 		return -EINVAL;
 	}
 
 	if (p->set) {
-		ret = __intel_timeline_sync_set(tl, ctx, p->seqno);
+		ret = __i915_timeline_sync_set(tl, ctx, p->seqno);
 		if (ret)
 			return ret;
 	}
@@ -77,37 +59,31 @@ static int igt_sync(void *arg)
 		{ "unwrap", UINT_MAX, true, false },
 		{},
 	}, *p;
-	struct intel_timeline *tl;
+	struct i915_timeline tl;
 	int order, offset;
 	int ret = -ENODEV;
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
-
+	mock_timeline_init(&tl, 0);
 	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;
 
-				ret = __igt_sync(tl, ctx, p, "1");
+				ret = __igt_sync(&tl, ctx, p, "1");
 				if (ret)
 					goto out;
 			}
 		}
 	}
-	mock_timeline_destroy(tl);
-
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_fini(&tl);
 
+	mock_timeline_init(&tl, 0);
 	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++) {
-				ret = __igt_sync(tl, ctx, p, "2");
+				ret = __igt_sync(&tl, ctx, p, "2");
 				if (ret)
 					goto out;
 			}
@@ -115,7 +91,7 @@ static int igt_sync(void *arg)
 	}
 
 out:
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	return ret;
 }
 
@@ -127,15 +103,13 @@ static unsigned int random_engine(struct rnd_state *rnd)
 static int bench_sync(void *arg)
 {
 	struct rnd_state prng;
-	struct intel_timeline *tl;
+	struct i915_timeline tl;
 	unsigned long end_time, count;
 	u64 prng32_1M;
 	ktime_t kt;
 	int order, last_order;
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_init(&tl, 0);
 
 	/* Lookups from cache are very fast and so the random number generation
 	 * and the loop itself becomes a significant factor in the per-iteration
@@ -167,7 +141,7 @@ static int bench_sync(void *arg)
 	do {
 		u64 id = i915_prandom_u64_state(&prng);
 
-		__intel_timeline_sync_set(tl, id, 0);
+		__i915_timeline_sync_set(&tl, id, 0);
 		count++;
 	} while (!time_after(jiffies, end_time));
 	kt = ktime_sub(ktime_get(), kt);
@@ -182,8 +156,8 @@ static int bench_sync(void *arg)
 	while (end_time--) {
 		u64 id = i915_prandom_u64_state(&prng);
 
-		if (!__intel_timeline_sync_is_later(tl, id, 0)) {
-			mock_timeline_destroy(tl);
+		if (!__i915_timeline_sync_is_later(&tl, id, 0)) {
+			mock_timeline_fini(&tl);
 			pr_err("Lookup of %llu failed\n", id);
 			return -EINVAL;
 		}
@@ -193,19 +167,17 @@ static int bench_sync(void *arg)
 	pr_info("%s: %lu random lookups, %lluns/lookup\n",
 		__func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
 
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	cond_resched();
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_init(&tl, 0);
 
 	/* Benchmark setting the first N (in order) contexts */
 	count = 0;
 	kt = ktime_get();
 	end_time = jiffies + HZ/10;
 	do {
-		__intel_timeline_sync_set(tl, count++, 0);
+		__i915_timeline_sync_set(&tl, count++, 0);
 	} while (!time_after(jiffies, end_time));
 	kt = ktime_sub(ktime_get(), kt);
 	pr_info("%s: %lu in-order insertions, %lluns/insert\n",
@@ -215,9 +187,9 @@ static int bench_sync(void *arg)
 	end_time = count;
 	kt = ktime_get();
 	while (end_time--) {
-		if (!__intel_timeline_sync_is_later(tl, end_time, 0)) {
+		if (!__i915_timeline_sync_is_later(&tl, end_time, 0)) {
 			pr_err("Lookup of %lu failed\n", end_time);
-			mock_timeline_destroy(tl);
+			mock_timeline_fini(&tl);
 			return -EINVAL;
 		}
 	}
@@ -225,12 +197,10 @@ static int bench_sync(void *arg)
 	pr_info("%s: %lu in-order lookups, %lluns/lookup\n",
 		__func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
 
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	cond_resched();
 
-	tl = mock_timeline(0);
-	if (!tl)
-		return -ENOMEM;
+	mock_timeline_init(&tl, 0);
 
 	/* Benchmark searching for a random context id and maybe changing it */
 	prandom_seed_state(&prng, i915_selftest.random_seed);
@@ -241,8 +211,8 @@ static int bench_sync(void *arg)
 		u32 id = random_engine(&prng);
 		u32 seqno = prandom_u32_state(&prng);
 
-		if (!__intel_timeline_sync_is_later(tl, id, seqno))
-			__intel_timeline_sync_set(tl, id, seqno);
+		if (!__i915_timeline_sync_is_later(&tl, id, seqno))
+			__i915_timeline_sync_set(&tl, id, seqno);
 
 		count++;
 	} while (!time_after(jiffies, end_time));
@@ -250,7 +220,7 @@ static int bench_sync(void *arg)
 	kt = ktime_sub_ns(kt, (count * prng32_1M * 2) >> 20);
 	pr_info("%s: %lu repeated insert/lookups, %lluns/op\n",
 		__func__, count, (long long)div64_ul(ktime_to_ns(kt), count));
-	mock_timeline_destroy(tl);
+	mock_timeline_fini(&tl);
 	cond_resched();
 
 	/* Benchmark searching for a known context id and changing the seqno */
@@ -258,9 +228,7 @@ static int bench_sync(void *arg)
 	     ({ int tmp = last_order; last_order = order; order += tmp; })) {
 		unsigned int mask = BIT(order) - 1;
 
-		tl = mock_timeline(0);
-		if (!tl)
-			return -ENOMEM;
+		mock_timeline_init(&tl, 0);
 
 		count = 0;
 		kt = ktime_get();
@@ -272,8 +240,8 @@ static int bench_sync(void *arg)
 			 */
 			u64 id = (u64)(count & mask) << order;
 
-			__intel_timeline_sync_is_later(tl, id, 0);
-			__intel_timeline_sync_set(tl, id, 0);
+			__i915_timeline_sync_is_later(&tl, id, 0);
+			__i915_timeline_sync_set(&tl, id, 0);
 
 			count++;
 		} while (!time_after(jiffies, end_time));
@@ -281,7 +249,7 @@ static int bench_sync(void *arg)
 		pr_info("%s: %lu cyclic/%d insert/lookups, %lluns/op\n",
 			__func__, count, order,
 			(long long)div64_ul(ktime_to_ns(kt), count));
-		mock_timeline_destroy(tl);
+		mock_timeline_fini(&tl);
 		cond_resched();
 	}
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index 6a10cb734c35..31cc210d51e9 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -25,6 +25,11 @@
 #include "mock_engine.h"
 #include "mock_request.h"
 
+struct mock_ring {
+	struct intel_ring base;
+	struct i915_timeline timeline;
+};
+
 static struct mock_request *first_request(struct mock_engine *engine)
 {
 	return list_first_entry_or_null(&engine->hw_queue,
@@ -125,7 +130,7 @@ static void mock_submit_request(struct i915_request *request)
 static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 {
 	const unsigned long sz = PAGE_SIZE / 2;
-	struct intel_ring *ring;
+	struct mock_ring *ring;
 
 	BUILD_BUG_ON(MIN_SPACE_FOR_ADD_REQUEST > sz);
 
@@ -133,18 +138,24 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	if (!ring)
 		return NULL;
 
-	ring->size = sz;
-	ring->effective_size = sz;
-	ring->vaddr = (void *)(ring + 1);
+	i915_timeline_init(engine->i915, &ring->timeline, engine->name);
+
+	ring->base.size = sz;
+	ring->base.effective_size = sz;
+	ring->base.vaddr = (void *)(ring + 1);
+	ring->base.timeline = &ring->timeline;
 
-	INIT_LIST_HEAD(&ring->request_list);
-	intel_ring_update_space(ring);
+	INIT_LIST_HEAD(&ring->base.request_list);
+	intel_ring_update_space(&ring->base);
 
-	return ring;
+	return &ring->base;
 }
 
-static void mock_ring_free(struct intel_ring *ring)
+static void mock_ring_free(struct intel_ring *base)
 {
+	struct mock_ring *ring = container_of(base, typeof(*ring), base);
+
+	i915_timeline_fini(&ring->timeline);
 	kfree(ring);
 }
 
@@ -173,8 +184,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 	engine->base.emit_breadcrumb = mock_emit_breadcrumb;
 	engine->base.submit_request = mock_submit_request;
 
-	intel_engine_init_timeline(&engine->base);
-
+	i915_timeline_init(i915, &engine->base.timeline, engine->base.name);
 	intel_engine_init_breadcrumbs(&engine->base);
 	engine->base.breadcrumbs.mock = true; /* prevent touching HW for irqs */
 
@@ -191,6 +201,7 @@ struct intel_engine_cs *mock_engine(struct drm_i915_private *i915,
 
 err_breadcrumbs:
 	intel_engine_fini_breadcrumbs(&engine->base);
+	i915_timeline_fini(&engine->base.timeline);
 	kfree(engine);
 	return NULL;
 }
@@ -229,6 +240,7 @@ void mock_engine_free(struct intel_engine_cs *engine)
 	mock_ring_free(engine->buffer);
 
 	intel_engine_fini_breadcrumbs(engine);
+	i915_timeline_fini(&engine->timeline);
 
 	kfree(engine);
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index f11c83e8ff32..a662c0450e77 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -73,10 +73,8 @@ static void mock_device_release(struct drm_device *dev)
 
 	mutex_lock(&i915->drm.struct_mutex);
 	mock_fini_ggtt(i915);
-	i915_gem_timeline_fini(&i915->gt.legacy_timeline);
-	i915_gem_timeline_fini(&i915->gt.execution_timeline);
-	WARN_ON(!list_empty(&i915->gt.timelines));
 	mutex_unlock(&i915->drm.struct_mutex);
+	WARN_ON(!list_empty(&i915->gt.timelines));
 
 	destroy_workqueue(i915->wq);
 
@@ -230,12 +228,6 @@ struct drm_i915_private *mock_gem_device(void)
 	INIT_LIST_HEAD(&i915->gt.active_rings);
 
 	mutex_lock(&i915->drm.struct_mutex);
-	err = i915_gem_timeline_init__global(i915);
-	if (err) {
-		mutex_unlock(&i915->drm.struct_mutex);
-		goto err_priorities;
-	}
-
 	mock_init_ggtt(i915);
 	mutex_unlock(&i915->drm.struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.c b/drivers/gpu/drm/i915/selftests/mock_timeline.c
index 47b1f47c5812..dcf3b16f5a07 100644
--- a/drivers/gpu/drm/i915/selftests/mock_timeline.c
+++ b/drivers/gpu/drm/i915/selftests/mock_timeline.c
@@ -1,45 +1,28 @@
 /*
- * 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.
+ * SPDX-License-Identifier: MIT
  *
+ * Copyright © 2017-2018 Intel Corporation
  */
 
+#include "../i915_timeline.h"
+
 #include "mock_timeline.h"
 
-struct intel_timeline *mock_timeline(u64 context)
+void mock_timeline_init(struct i915_timeline *timeline, u64 context)
 {
-	static struct lock_class_key class;
-	struct intel_timeline *tl;
+	timeline->fence_context = context;
+
+	spin_lock_init(&timeline->lock);
 
-	tl = kzalloc(sizeof(*tl), GFP_KERNEL);
-	if (!tl)
-		return NULL;
+	init_request_active(&timeline->last_request, NULL);
+	INIT_LIST_HEAD(&timeline->requests);
 
-	__intel_timeline_init(tl, NULL, context, &class, "mock");
+	i915_syncmap_init(&timeline->sync);
 
-	return tl;
+	INIT_LIST_HEAD(&timeline->link);
 }
 
-void mock_timeline_destroy(struct intel_timeline *tl)
+void mock_timeline_fini(struct i915_timeline *timeline)
 {
-	__intel_timeline_fini(tl);
-	kfree(tl);
+	i915_timeline_fini(timeline);
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.h b/drivers/gpu/drm/i915/selftests/mock_timeline.h
index c27ff4639b8b..b6deaa61110d 100644
--- a/drivers/gpu/drm/i915/selftests/mock_timeline.h
+++ b/drivers/gpu/drm/i915/selftests/mock_timeline.h
@@ -1,33 +1,15 @@
 /*
- * 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.
+ * SPDX-License-Identifier: MIT
  *
+ * Copyright © 2017-2018 Intel Corporation
  */
 
 #ifndef __MOCK_TIMELINE__
 #define __MOCK_TIMELINE__
 
-#include "../i915_gem_timeline.h"
+struct i915_timeline;
 
-struct intel_timeline *mock_timeline(u64 context);
-void mock_timeline_destroy(struct intel_timeline *tl);
+void mock_timeline_init(struct i915_timeline *timeline, u64 context);
+void mock_timeline_fini(struct i915_timeline *timeline);
 
 #endif /* !__MOCK_TIMELINE__ */
-- 
2.17.0

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

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

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2)
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (10 preceding siblings ...)
  2018-04-23 20:46 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2018-04-23 23:53 ` Patchwork
  2018-04-23 23:55 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 23:53 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2)
URL   : https://patchwork.freedesktop.org/series/42139/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
84a91bc19416 drm/i915: Stop tracking timeline->inflight_seqnos
-:17: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("<title line>")' - ie: 'commit 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")'
#17: 
References: 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")

total: 1 errors, 0 warnings, 0 checks, 128 lines checked
bbfb45c829a5 drm/i915: Retire requests along rings
f329f05ed93a drm/i915: Only track live rings for retiring
73d820ce21e1 drm/i915: Move timeline from GTT to ring
8b221e8610f7 drm/i915: Split i915_gem_timeline into individual timelines
-:464: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#464: 
deleted file mode 100644

-:960: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#960: FILE: drivers/gpu/drm/i915/i915_timeline.c:1:
+/*

total: 0 errors, 2 warnings, 0 checks, 1619 lines checked
088bede798a4 drm/i915: Lazily unbind vma on close

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

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

* ✗ Fi.CI.SPARSE: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2)
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (11 preceding siblings ...)
  2018-04-23 23:53 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2) Patchwork
@ 2018-04-23 23:55 ` Patchwork
  2018-04-24  0:08 ` ✗ Fi.CI.BAT: failure " Patchwork
  2018-04-24 10:14 ` [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Tvrtko Ursulin
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-23 23:55 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2)
URL   : https://patchwork.freedesktop.org/series/42139/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Commit: drm/i915: Stop tracking timeline->inflight_seqnos
-O:drivers/gpu/drm/i915/i915_request.c:268:13: error: undefined identifier '__builtin_add_overflow_p'
-O:drivers/gpu/drm/i915/i915_request.c:268:13: warning: call with no type!
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2211:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3659:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2212:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3660:16: warning: expression using sizeof(void)

Commit: drm/i915: Retire requests along rings
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2212:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3660:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2213:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3661:16: warning: expression using sizeof(void)

Commit: drm/i915: Only track live rings for retiring
-drivers/gpu/drm/i915/selftests/../i915_drv.h:2213:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/selftests/../i915_drv.h:3661:16: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/selftests/../i915_drv.h:2214:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
+drivers/gpu/drm/i915/selftests/../i915_drv.h:3662:16: warning: expression using sizeof(void)

Commit: drm/i915: Move timeline from GTT to ring
+  ^~~~~~~~~~
+  ^~~~~~~~~~
+                      ^
+                          ^
+                                          ^
+                                          ^
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:115:31: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-./arch/x86/include/asm/pgalloc.h:86:29: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1954:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1958:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:1963:38: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2273:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2277:17: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:2281:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    expected void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void [noderef] <asn:4>**
-drivers/gpu/drm/i915/gvt/gtt.c:671:9:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:671:9: warning: incorrect type in assignment (different address spaces)
-drivers/gpu/drm/i915/gvt/gtt.c:672:45:    expected void [noderef] <asn:4>**slot
-drivers/gpu/drm/i915/gvt/gtt.c:672:45:    got void **slot
-drivers/gpu/drm/i915/gvt/gtt.c:672:45: warning: incorrect type in argument 1 (different address spaces)
-drivers/gpu/drm/i915/gvt/mmio.c:255:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/mmio.c:256:23: warning: memcpy with byte count of 279040
-drivers/gpu/drm/i915/gvt/vgpu.c:144:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:144:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/gvt/vgpu.c:192:48: warning: expression using sizeof(void)
+cc1: all warnings being treated as errors
+cc1: all warnings being treated as errors
+ # define unlikely(x) __builtin_expect(!!(x), 0)
+ # define unlikely(x) __builtin_expect(!!(x), 0)
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it is unsigned long
-drivers/gpu/drm/i915/i915_drv.h:2215:33: warning: constant 0xffffea0000000000 is so big it

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

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

* ✗ Fi.CI.BAT: failure for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2)
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (12 preceding siblings ...)
  2018-04-23 23:55 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2018-04-24  0:08 ` Patchwork
  2018-04-24 10:14 ` [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Tvrtko Ursulin
  14 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-04-24  0:08 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2)
URL   : https://patchwork.freedesktop.org/series/42139/
State : failure

== Summary ==

= CI Bug Log - changes from CI_DRM_4082 -> Patchwork_8780 =

== Summary - FAILURE ==

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

  External URL: https://patchwork.freedesktop.org/api/1.0/series/42139/revisions/2/mbox/

== Possible new issues ==

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

  === IGT changes ===

    ==== Possible regressions ====

    igt@gem_ctx_switch@basic-default:
      fi-bsw-n3050:       PASS -> INCOMPLETE

    igt@gem_exec_suspend@basic-s4-devices:
      fi-skl-guc:         PASS -> FAIL

    
== Known issues ==

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

  === IGT changes ===

    ==== Issues hit ====

    igt@kms_chamelium@hdmi-hpd-fast:
      fi-kbl-7500u:       SKIP -> FAIL (fdo#102672, fdo#103841)

    igt@kms_flip@basic-flip-vs-wf_vblank:
      fi-cfl-s3:          PASS -> FAIL (fdo#100368)

    igt@kms_pipe_crc_basic@read-crc-pipe-a-frame-sequence:
      fi-cfl-s3:          PASS -> FAIL (fdo#103481)

    igt@kms_pipe_crc_basic@suspend-read-crc-pipe-c:
      fi-ivb-3520m:       PASS -> DMESG-WARN (fdo#106084)
      fi-cnl-psr:         PASS -> DMESG-WARN (fdo#104951)

    
    ==== Possible fixes ====

    igt@drv_module_reload@basic-no-display:
      fi-ilk-650:         DMESG-WARN -> PASS

    igt@kms_pipe_crc_basic@suspend-read-crc-pipe-b:
      fi-snb-2520m:       INCOMPLETE (fdo#103713) -> PASS

    igt@prime_vgem@basic-fence-flip:
      fi-ilk-650:         FAIL (fdo#104008) -> PASS

    
  fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
  fdo#102672 https://bugs.freedesktop.org/show_bug.cgi?id=102672
  fdo#103481 https://bugs.freedesktop.org/show_bug.cgi?id=103481
  fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713
  fdo#103841 https://bugs.freedesktop.org/show_bug.cgi?id=103841
  fdo#104008 https://bugs.freedesktop.org/show_bug.cgi?id=104008
  fdo#104951 https://bugs.freedesktop.org/show_bug.cgi?id=104951
  fdo#106084 https://bugs.freedesktop.org/show_bug.cgi?id=106084


== Participating hosts (36 -> 32) ==

  Missing    (4): fi-ctg-p8600 fi-ilk-m540 fi-cnl-y3 fi-skl-6700hq 


== Build changes ==

    * Linux: CI_DRM_4082 -> Patchwork_8780

  CI_DRM_4082: 0600266ef9b8407e0dc281acb6b754eba8178c91 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_4444: dcc44347494231feabc588c2a76998cbc9afdf8c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_8780: 088bede798a4806e09b457a6db4143b2510daa2e @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4444: a2f486679f467cd6e82578384f56d4aabaa8cf2e @ git://anongit.freedesktop.org/piglit


== Linux commits ==

088bede798a4 drm/i915: Lazily unbind vma on close
8b221e8610f7 drm/i915: Split i915_gem_timeline into individual timelines
73d820ce21e1 drm/i915: Move timeline from GTT to ring
f329f05ed93a drm/i915: Only track live rings for retiring
bbfb45c829a5 drm/i915: Retire requests along rings
84a91bc19416 drm/i915: Stop tracking timeline->inflight_seqnos

== Logs ==

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

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

* Re: [PATCH v2 3/6] drm/i915: Only track live rings for retiring
  2018-04-23 18:08 ` [PATCH v2 3/6] drm/i915: Only track live rings for retiring Chris Wilson
@ 2018-04-24  9:37   ` Tvrtko Ursulin
  2018-04-24  9:43     ` Chris Wilson
  0 siblings, 1 reply; 26+ messages in thread
From: Tvrtko Ursulin @ 2018-04-24  9:37 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 23/04/2018 19:08, Chris Wilson wrote:
> We don't need to track every ring for its lifetime as they are managed
> by the contexts/engines. What we do want to track are the live rings so
> that we can sporadically clean up requests if userspace falls behind. We
> can simply restrict the gt->rings list to being only gt->live_rings.
> 
> v2: s/live/active/ for consistency with gt.active_requests
> 
> Suggested-by: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/i915_drv.h                  |  3 ++-
>   drivers/gpu/drm/i915/i915_gem.c                  |  6 ++++--
>   drivers/gpu/drm/i915/i915_request.c              | 10 ++++++++--
>   drivers/gpu/drm/i915/intel_ringbuffer.c          |  4 ----
>   drivers/gpu/drm/i915/intel_ringbuffer.h          |  2 +-
>   drivers/gpu/drm/i915/selftests/mock_engine.c     |  4 ----
>   drivers/gpu/drm/i915/selftests/mock_gem_device.c |  5 +++--
>   7 files changed, 18 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1837c01d44d0..54351cace362 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2060,7 +2060,8 @@ struct drm_i915_private {
>   
>   		struct i915_gem_timeline global_timeline;
>   		struct list_head timelines;
> -		struct list_head rings;
> +
> +		struct list_head active_rings;
>   		u32 active_requests;
>   		u32 request_serial;
>   
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 906e2395c245..56c79df5ebce 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -141,6 +141,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
>   {
>   	lockdep_assert_held(&i915->drm.struct_mutex);
>   	GEM_BUG_ON(i915->gt.active_requests);
> +	GEM_BUG_ON(!list_empty(&i915->gt.active_rings));
>   
>   	if (!i915->gt.awake)
>   		return I915_EPOCH_INVALID;
> @@ -5599,9 +5600,10 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
>   	if (!dev_priv->priorities)
>   		goto err_dependencies;
>   
> -	mutex_lock(&dev_priv->drm.struct_mutex);
> -	INIT_LIST_HEAD(&dev_priv->gt.rings);
>   	INIT_LIST_HEAD(&dev_priv->gt.timelines);
> +	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
> +
> +	mutex_lock(&dev_priv->drm.struct_mutex);
>   	err = i915_gem_timeline_init__global(dev_priv);
>   	mutex_unlock(&dev_priv->drm.struct_mutex);
>   	if (err)
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index 0a117bf9e455..f13b7a1a0aa9 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -321,6 +321,7 @@ static void advance_ring(struct i915_request *request)
>   		 * noops - they are safe to be replayed on a reset.
>   		 */
>   		tail = READ_ONCE(request->tail);
> +		list_del(&ring->active_link);
>   	} else {
>   		tail = request->postfix;
>   	}
> @@ -1081,6 +1082,8 @@ void __i915_request_add(struct i915_request *request, bool flush_caches)
>   	i915_gem_active_set(&timeline->last_request, request);
>   
>   	list_add_tail(&request->ring_link, &ring->request_list);
> +	if (list_is_first(&request->ring_link, &ring->request_list))
> +		list_add(&ring->active_link, &request->i915->gt.active_rings);

So sneaky.. lets see if it is justified in its new home. :)

>   	request->emitted_jiffies = jiffies;
>   
>   	/*
> @@ -1403,14 +1406,17 @@ static void ring_retire_requests(struct intel_ring *ring)
>   
>   void i915_retire_requests(struct drm_i915_private *i915)
>   {
> -	struct intel_ring *ring, *next;
> +	struct intel_ring *ring, *tmp;
>   
>   	lockdep_assert_held(&i915->drm.struct_mutex);
>   
>   	if (!i915->gt.active_requests)
>   		return;
>   
> -	list_for_each_entry_safe(ring, next, &i915->gt.rings, link)
> +	/* An outstanding request must be on a still active ring somewhere */
> +	GEM_BUG_ON(list_empty(&i915->gt.active_rings));

Okay, but I still think my assert would be stronger. As long as we allow 
calling this function with no active requests, why not check both 
internal states are consistent every time?

> +
> +	list_for_each_entry_safe(ring, tmp, &i915->gt.active_rings, active_link)
>   		ring_retire_requests(ring);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 75dca28782ee..3d02b2c779e7 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -1149,8 +1149,6 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size)
>   	}
>   	ring->vma = vma;
>   
> -	list_add(&ring->link, &engine->i915->gt.rings);
> -
>   	return ring;
>   }
>   
> @@ -1162,8 +1160,6 @@ intel_ring_free(struct intel_ring *ring)
>   	i915_vma_close(ring->vma);
>   	__i915_gem_object_release_unless_active(obj);
>   
> -	list_del(&ring->link);
> -
>   	kfree(ring);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index d816f8dea245..e8d17bcd9bee 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -129,7 +129,7 @@ struct intel_ring {
>   	void *vaddr;
>   
>   	struct list_head request_list;
> -	struct list_head link;
> +	struct list_head active_link;
>   
>   	u32 head;
>   	u32 tail;
> diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
> index a0bc324edadd..74a88913623f 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_engine.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
> @@ -140,15 +140,11 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
>   	INIT_LIST_HEAD(&ring->request_list);
>   	intel_ring_update_space(ring);
>   
> -	list_add(&ring->link, &engine->i915->gt.rings);
> -
>   	return ring;
>   }
>   
>   static void mock_ring_free(struct intel_ring *ring)
>   {
> -	list_del(&ring->link);
> -
>   	kfree(ring);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> index ac4bacf8b5b9..f22a2b35a283 100644
> --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
> @@ -224,9 +224,10 @@ struct drm_i915_private *mock_gem_device(void)
>   	if (!i915->priorities)
>   		goto err_dependencies;
>   
> -	mutex_lock(&i915->drm.struct_mutex);
> -	INIT_LIST_HEAD(&i915->gt.rings);
>   	INIT_LIST_HEAD(&i915->gt.timelines);
> +	INIT_LIST_HEAD(&i915->gt.active_rings);
> +
> +	mutex_lock(&i915->drm.struct_mutex);
>   	err = i915_gem_timeline_init__global(i915);
>   	if (err) {
>   		mutex_unlock(&i915->drm.struct_mutex);
> 

Regards,

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

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

* Re: [PATCH v2 3/6] drm/i915: Only track live rings for retiring
  2018-04-24  9:37   ` Tvrtko Ursulin
@ 2018-04-24  9:43     ` Chris Wilson
  0 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-24  9:43 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2018-04-24 10:37:03)
> 
> On 23/04/2018 19:08, Chris Wilson wrote:
> > @@ -1403,14 +1406,17 @@ static void ring_retire_requests(struct intel_ring *ring)
> >   
> >   void i915_retire_requests(struct drm_i915_private *i915)
> >   {
> > -     struct intel_ring *ring, *next;
> > +     struct intel_ring *ring, *tmp;
> >   
> >       lockdep_assert_held(&i915->drm.struct_mutex);
> >   
> >       if (!i915->gt.active_requests)
> >               return;
> >   
> > -     list_for_each_entry_safe(ring, next, &i915->gt.rings, link)
> > +     /* An outstanding request must be on a still active ring somewhere */
> > +     GEM_BUG_ON(list_empty(&i915->gt.active_rings));
> 
> Okay, but I still think my assert would be stronger. As long as we allow 
> calling this function with no active requests, why not check both 
> internal states are consistent every time?

I agree that checking both simultaneously would be useful, but we do
check both for cross-consistency already, just not in the same place.
It's just doing so in a readable fashion.

After this we aren't using active_requests as more than a boolean; so
I'm wondering if not just replacing it with list_empty(&active_rings)
for the infrequent uses.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
                   ` (13 preceding siblings ...)
  2018-04-24  0:08 ` ✗ Fi.CI.BAT: failure " Patchwork
@ 2018-04-24 10:14 ` Tvrtko Ursulin
  2018-04-24 10:40   ` Chris Wilson
  14 siblings, 1 reply; 26+ messages in thread
From: Tvrtko Ursulin @ 2018-04-24 10:14 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 23/04/2018 19:08, Chris Wilson wrote:
> In commit 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine"), we
> moved from a global inflight counter to per-engine counters in the
> hope that will be easy to run concurrently in future. However, with the
> advent of the desire to move requests between engines, we do need a
> global counter to preserve the semantics that no engine wraps in the
> middle of a submit. (Although this semantic is now only required for gen7
> semaphore support, which only supports greater-then comparisons!)
> 
> v2: Keep a global counter of all requests ever submitted and force the
> reset when it wraps.
> 
> References: 9b6586ae9f6b ("drm/i915: Keep a global seqno per-engine")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c      |  5 ++--
>   drivers/gpu/drm/i915/i915_drv.h          |  1 +
>   drivers/gpu/drm/i915/i915_gem_timeline.h |  6 -----
>   drivers/gpu/drm/i915/i915_request.c      | 33 ++++++++++++------------
>   drivers/gpu/drm/i915/intel_engine_cs.c   |  5 ++--
>   5 files changed, 22 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 2f05f5262bba..547e97102b85 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1340,10 +1340,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused)
>   		struct rb_node *rb;
>   
>   		seq_printf(m, "%s:\n", engine->name);
> -		seq_printf(m, "\tseqno = %x [current %x, last %x], inflight %d\n",
> +		seq_printf(m, "\tseqno = %x [current %x, last %x]\n",
>   			   engine->hangcheck.seqno, seqno[id],
> -			   intel_engine_last_submit(engine),
> -			   engine->timeline->inflight_seqnos);
> +			   intel_engine_last_submit(engine));
>   		seq_printf(m, "\twaiters? %s, fake irq active? %s, stalled? %s\n",
>   			   yesno(intel_engine_has_waiter(engine)),
>   			   yesno(test_bit(engine->id,
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8444ca8d5aa3..8fd9fb6efba5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2061,6 +2061,7 @@ struct drm_i915_private {
>   		struct list_head timelines;
>   		struct i915_gem_timeline global_timeline;
>   		u32 active_requests;
> +		u32 request_serial;
>   
>   		/**
>   		 * Is the GPU currently considered idle, or busy executing
> diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
> index 33e01bf6aa36..6e82119e2cd8 100644
> --- a/drivers/gpu/drm/i915/i915_gem_timeline.h
> +++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
> @@ -37,12 +37,6 @@ struct intel_timeline {
>   	u64 fence_context;
>   	u32 seqno;
>   
> -	/**
> -	 * Count of outstanding requests, from the time they are constructed
> -	 * to the moment they are retired. Loosely coupled to hardware.
> -	 */
> -	u32 inflight_seqnos;
> -
>   	spinlock_t lock;
>   
>   	/**
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index b692a9f7c357..f3d04f0ab21c 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -241,6 +241,7 @@ static int reset_all_global_seqno(struct drm_i915_private *i915, u32 seqno)
>   			       sizeof(timeline->engine[id].global_sync));
>   	}
>   
> +	i915->gt.request_serial = seqno;
>   	return 0;
>   }
>   
> @@ -257,18 +258,22 @@ int i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno)
>   	return reset_all_global_seqno(i915, seqno - 1);
>   }
>   
> -static int reserve_engine(struct intel_engine_cs *engine)
> +static int reserve_gt(struct drm_i915_private *i915)
>   {
> -	struct drm_i915_private *i915 = engine->i915;
> -	u32 active = ++engine->timeline->inflight_seqnos;
> -	u32 seqno = engine->timeline->seqno;
>   	int ret;
>   
> -	/* Reservation is fine until we need to wrap around */
> -	if (unlikely(add_overflows(seqno, active))) {
> +	/*
> +	 * Reservation is fine until we may need to wrap around
> +	 *
> +	 * By incrementing the serial for every request, we know that no
> +	 * individual engine may exceed that serial (as each is reset to 0
> +	 * on any wrap). This protects even the most pessimistic of migrations
> +	 * of every request from all engines onto just one.
> +	 */

I didn't really figure out what was wrong with v1? Neither could handle 
more than four billion of simultaneously active requests - but I thought 
that should not concern us. :)

I don't quite get wrapping based on otherwise unused counter.

v1 made sense to wrap then any engine timeline couldn't handle all 
active requests without wrapping.

> +	if (unlikely(++i915->gt.request_serial == 0)) {
>   		ret = reset_all_global_seqno(i915, 0);
>   		if (ret) {
> -			engine->timeline->inflight_seqnos--;
> +			i915->gt.request_serial--;
>   			return ret;
>   		}
>   	}
> @@ -279,15 +284,10 @@ static int reserve_engine(struct intel_engine_cs *engine)
>   	return 0;
>   }
>   
> -static void unreserve_engine(struct intel_engine_cs *engine)
> +static void unreserve_gt(struct drm_i915_private *i915)
>   {
> -	struct drm_i915_private *i915 = engine->i915;
> -
>   	if (!--i915->gt.active_requests)
>   		i915_gem_park(i915);
> -
> -	GEM_BUG_ON(!engine->timeline->inflight_seqnos);
> -	engine->timeline->inflight_seqnos--;
>   }
>   
>   void i915_gem_retire_noop(struct i915_gem_active *active,
> @@ -362,7 +362,6 @@ static void i915_request_retire(struct i915_request *request)
>   	list_del_init(&request->link);
>   	spin_unlock_irq(&engine->timeline->lock);
>   
> -	unreserve_engine(request->engine);
>   	advance_ring(request);
>   
>   	free_capture_list(request);
> @@ -424,6 +423,8 @@ static void i915_request_retire(struct i915_request *request)
>   	}
>   	spin_unlock_irq(&request->lock);
>   
> +	unreserve_gt(request->i915);
> +
>   	i915_sched_node_fini(request->i915, &request->sched);
>   	i915_request_put(request);
>   }
> @@ -642,7 +643,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
>   		return ERR_CAST(ring);
>   	GEM_BUG_ON(!ring);
>   
> -	ret = reserve_engine(engine);
> +	ret = reserve_gt(i915);

Maybe more descriptive name? reserve_gt_global_seqno?

>   	if (ret)
>   		goto err_unpin;
>   
> @@ -784,7 +785,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx)
>   
>   	kmem_cache_free(i915->requests, rq);
>   err_unreserve:
> -	unreserve_engine(engine);
> +	unreserve_gt(i915);
>   err_unpin:
>   	engine->context_unpin(engine, ctx);
>   	return ERR_PTR(ret);
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
> index be608f7111f5..a55a849b81b6 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -1318,12 +1318,11 @@ void intel_engine_dump(struct intel_engine_cs *engine,
>   	if (i915_terminally_wedged(&engine->i915->gpu_error))
>   		drm_printf(m, "*** WEDGED ***\n");
>   
> -	drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n",
> +	drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms]\n",
>   		   intel_engine_get_seqno(engine),
>   		   intel_engine_last_submit(engine),
>   		   engine->hangcheck.seqno,
> -		   jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
> -		   engine->timeline->inflight_seqnos);
> +		   jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp));
>   	drm_printf(m, "\tReset count: %d (global %d)\n",
>   		   i915_reset_engine_count(error, engine),
>   		   i915_reset_count(error));
> 

Regards,

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

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 10:14 ` [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Tvrtko Ursulin
@ 2018-04-24 10:40   ` Chris Wilson
  2018-04-24 11:17     ` Tvrtko Ursulin
  0 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-04-24 10:40 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
> 
> On 23/04/2018 19:08, Chris Wilson wrote:
> > -static int reserve_engine(struct intel_engine_cs *engine)
> > +static int reserve_gt(struct drm_i915_private *i915)
> >   {
> > -     struct drm_i915_private *i915 = engine->i915;
> > -     u32 active = ++engine->timeline->inflight_seqnos;
> > -     u32 seqno = engine->timeline->seqno;
> >       int ret;
> >   
> > -     /* Reservation is fine until we need to wrap around */
> > -     if (unlikely(add_overflows(seqno, active))) {
> > +     /*
> > +      * Reservation is fine until we may need to wrap around
> > +      *
> > +      * By incrementing the serial for every request, we know that no
> > +      * individual engine may exceed that serial (as each is reset to 0
> > +      * on any wrap). This protects even the most pessimistic of migrations
> > +      * of every request from all engines onto just one.
> > +      */
> 
> I didn't really figure out what was wrong with v1? Neither could handle 
> more than four billion of simultaneously active requests - but I thought 
> that should not concern us. :)

It was still using the local engine->timeline.seqno as it's base. If we
swapped from one at 0 to another at U32_MAX, we would overflow much
later in submission; after the point of no return.
 
> I don't quite get wrapping based on otherwise unused counter.
> 
> v1 made sense to wrap then any engine timeline couldn't handle all 
> active requests without wrapping.

Emphasis on *any*, not just the current engine.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 10:40   ` Chris Wilson
@ 2018-04-24 11:17     ` Tvrtko Ursulin
  2018-04-24 11:28       ` Chris Wilson
  0 siblings, 1 reply; 26+ messages in thread
From: Tvrtko Ursulin @ 2018-04-24 11:17 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 24/04/2018 11:40, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
>>
>> On 23/04/2018 19:08, Chris Wilson wrote:
>>> -static int reserve_engine(struct intel_engine_cs *engine)
>>> +static int reserve_gt(struct drm_i915_private *i915)
>>>    {
>>> -     struct drm_i915_private *i915 = engine->i915;
>>> -     u32 active = ++engine->timeline->inflight_seqnos;
>>> -     u32 seqno = engine->timeline->seqno;
>>>        int ret;
>>>    
>>> -     /* Reservation is fine until we need to wrap around */
>>> -     if (unlikely(add_overflows(seqno, active))) {
>>> +     /*
>>> +      * Reservation is fine until we may need to wrap around
>>> +      *
>>> +      * By incrementing the serial for every request, we know that no
>>> +      * individual engine may exceed that serial (as each is reset to 0
>>> +      * on any wrap). This protects even the most pessimistic of migrations
>>> +      * of every request from all engines onto just one.
>>> +      */
>>
>> I didn't really figure out what was wrong with v1? Neither could handle
>> more than four billion of simultaneously active requests - but I thought
>> that should not concern us. :)
> 
> It was still using the local engine->timeline.seqno as it's base. If we
> swapped from one at 0 to another at U32_MAX, we would overflow much
> later in submission; after the point of no return.

By swapped you already refer to engine change? Ok, I can see that yes. 
In this case global counter does prevent that.

In the light of that, what is your current thinking with regards to 
mixing engine classes?

If the thinking is still to only allow within a class then per-class 
seqno counter would be an option.

Regards,

Tvrtko

>> I don't quite get wrapping based on otherwise unused counter.
>>
>> v1 made sense to wrap then any engine timeline couldn't handle all
>> active requests without wrapping.
> 
> Emphasis on *any*, not just the current engine.
> -Chris
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 11:17     ` Tvrtko Ursulin
@ 2018-04-24 11:28       ` Chris Wilson
  2018-04-24 13:55         ` Tvrtko Ursulin
  0 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-04-24 11:28 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2018-04-24 12:17:15)
> 
> On 24/04/2018 11:40, Chris Wilson wrote:
> > Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
> >>
> >> On 23/04/2018 19:08, Chris Wilson wrote:
> >>> -static int reserve_engine(struct intel_engine_cs *engine)
> >>> +static int reserve_gt(struct drm_i915_private *i915)
> >>>    {
> >>> -     struct drm_i915_private *i915 = engine->i915;
> >>> -     u32 active = ++engine->timeline->inflight_seqnos;
> >>> -     u32 seqno = engine->timeline->seqno;
> >>>        int ret;
> >>>    
> >>> -     /* Reservation is fine until we need to wrap around */
> >>> -     if (unlikely(add_overflows(seqno, active))) {
> >>> +     /*
> >>> +      * Reservation is fine until we may need to wrap around
> >>> +      *
> >>> +      * By incrementing the serial for every request, we know that no
> >>> +      * individual engine may exceed that serial (as each is reset to 0
> >>> +      * on any wrap). This protects even the most pessimistic of migrations
> >>> +      * of every request from all engines onto just one.
> >>> +      */
> >>
> >> I didn't really figure out what was wrong with v1? Neither could handle
> >> more than four billion of simultaneously active requests - but I thought
> >> that should not concern us. :)
> > 
> > It was still using the local engine->timeline.seqno as it's base. If we
> > swapped from one at 0 to another at U32_MAX, we would overflow much
> > later in submission; after the point of no return.
> 
> By swapped you already refer to engine change? Ok, I can see that yes. 
> In this case global counter does prevent that.
> 
> In the light of that, what is your current thinking with regards to 
> mixing engine classes?

That classes are a hw limitation that doesn't impact on balancing itself,
just which engines the user is allowed to put into the same group.

> If the thinking is still to only allow within a class then per-class 
> seqno counter would be an option.

The goal of localising the seqno here was to try and reduce the locking
requirements (or at least make it easier to reduce them in future).
Whether it's one u32 across all engines, or one u32 across a few isn't
enough for me to worry. The breadcrumb tracking should be happy enough
(sorted by i915_seqno_passed rather than absolute u32) so the only
limitation in wrapping should be gen7 HW semaphores. Hmm, with a bit of
thought, I believe we can reduce the wrap logic to simply skip semaphore
sync inside the danger zone. Would be worth the effort.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 11:28       ` Chris Wilson
@ 2018-04-24 13:55         ` Tvrtko Ursulin
  2018-04-24 14:04           ` Chris Wilson
  0 siblings, 1 reply; 26+ messages in thread
From: Tvrtko Ursulin @ 2018-04-24 13:55 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 24/04/2018 12:28, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2018-04-24 12:17:15)
>>
>> On 24/04/2018 11:40, Chris Wilson wrote:
>>> Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
>>>>
>>>> On 23/04/2018 19:08, Chris Wilson wrote:
>>>>> -static int reserve_engine(struct intel_engine_cs *engine)
>>>>> +static int reserve_gt(struct drm_i915_private *i915)
>>>>>     {
>>>>> -     struct drm_i915_private *i915 = engine->i915;
>>>>> -     u32 active = ++engine->timeline->inflight_seqnos;
>>>>> -     u32 seqno = engine->timeline->seqno;
>>>>>         int ret;
>>>>>     
>>>>> -     /* Reservation is fine until we need to wrap around */
>>>>> -     if (unlikely(add_overflows(seqno, active))) {
>>>>> +     /*
>>>>> +      * Reservation is fine until we may need to wrap around
>>>>> +      *
>>>>> +      * By incrementing the serial for every request, we know that no
>>>>> +      * individual engine may exceed that serial (as each is reset to 0
>>>>> +      * on any wrap). This protects even the most pessimistic of migrations
>>>>> +      * of every request from all engines onto just one.
>>>>> +      */
>>>>
>>>> I didn't really figure out what was wrong with v1? Neither could handle
>>>> more than four billion of simultaneously active requests - but I thought
>>>> that should not concern us. :)
>>>
>>> It was still using the local engine->timeline.seqno as it's base. If we
>>> swapped from one at 0 to another at U32_MAX, we would overflow much
>>> later in submission; after the point of no return.
>>
>> By swapped you already refer to engine change? Ok, I can see that yes.
>> In this case global counter does prevent that.
>>
>> In the light of that, what is your current thinking with regards to
>> mixing engine classes?
> 
> That classes are a hw limitation that doesn't impact on balancing itself,
> just which engines the user is allowed to put into the same group.
> 
>> If the thinking is still to only allow within a class then per-class
>> seqno counter would be an option.
> 
> The goal of localising the seqno here was to try and reduce the locking
> requirements (or at least make it easier to reduce them in future).
> Whether it's one u32 across all engines, or one u32 across a few isn't
> enough for me to worry. The breadcrumb tracking should be happy enough
> (sorted by i915_seqno_passed rather than absolute u32) so the only
> limitation in wrapping should be gen7 HW semaphores. Hmm, with a bit of
> thought, I believe we can reduce the wrap logic to simply skip semaphore
> sync inside the danger zone. Would be worth the effort.

I was thinking about reducing the number of global seqno resets as much 
as we can in general. For instance would it be possible to keep using 
the gt.active_requests together with a new gt.max_engine_seqno? The 
latter would be the maximum last allocated seqno from the engine 
timelines. This way reset would be much less frequent if the load is 
distributed over engines (divided by num engines less frequent).

Regards,

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

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 13:55         ` Tvrtko Ursulin
@ 2018-04-24 14:04           ` Chris Wilson
  2018-04-24 14:48             ` Tvrtko Ursulin
  0 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-04-24 14:04 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2018-04-24 14:55:51)
> 
> On 24/04/2018 12:28, Chris Wilson wrote:
> > Quoting Tvrtko Ursulin (2018-04-24 12:17:15)
> >>
> >> On 24/04/2018 11:40, Chris Wilson wrote:
> >>> Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
> >>>>
> >>>> On 23/04/2018 19:08, Chris Wilson wrote:
> >>>>> -static int reserve_engine(struct intel_engine_cs *engine)
> >>>>> +static int reserve_gt(struct drm_i915_private *i915)
> >>>>>     {
> >>>>> -     struct drm_i915_private *i915 = engine->i915;
> >>>>> -     u32 active = ++engine->timeline->inflight_seqnos;
> >>>>> -     u32 seqno = engine->timeline->seqno;
> >>>>>         int ret;
> >>>>>     
> >>>>> -     /* Reservation is fine until we need to wrap around */
> >>>>> -     if (unlikely(add_overflows(seqno, active))) {
> >>>>> +     /*
> >>>>> +      * Reservation is fine until we may need to wrap around
> >>>>> +      *
> >>>>> +      * By incrementing the serial for every request, we know that no
> >>>>> +      * individual engine may exceed that serial (as each is reset to 0
> >>>>> +      * on any wrap). This protects even the most pessimistic of migrations
> >>>>> +      * of every request from all engines onto just one.
> >>>>> +      */
> >>>>
> >>>> I didn't really figure out what was wrong with v1? Neither could handle
> >>>> more than four billion of simultaneously active requests - but I thought
> >>>> that should not concern us. :)
> >>>
> >>> It was still using the local engine->timeline.seqno as it's base. If we
> >>> swapped from one at 0 to another at U32_MAX, we would overflow much
> >>> later in submission; after the point of no return.
> >>
> >> By swapped you already refer to engine change? Ok, I can see that yes.
> >> In this case global counter does prevent that.
> >>
> >> In the light of that, what is your current thinking with regards to
> >> mixing engine classes?
> > 
> > That classes are a hw limitation that doesn't impact on balancing itself,
> > just which engines the user is allowed to put into the same group.
> > 
> >> If the thinking is still to only allow within a class then per-class
> >> seqno counter would be an option.
> > 
> > The goal of localising the seqno here was to try and reduce the locking
> > requirements (or at least make it easier to reduce them in future).
> > Whether it's one u32 across all engines, or one u32 across a few isn't
> > enough for me to worry. The breadcrumb tracking should be happy enough
> > (sorted by i915_seqno_passed rather than absolute u32) so the only
> > limitation in wrapping should be gen7 HW semaphores. Hmm, with a bit of
> > thought, I believe we can reduce the wrap logic to simply skip semaphore
> > sync inside the danger zone. Would be worth the effort.
> 
> I was thinking about reducing the number of global seqno resets as much 
> as we can in general. For instance would it be possible to keep using 
> the gt.active_requests together with a new gt.max_engine_seqno? The 
> latter would be the maximum last allocated seqno from the engine 
> timelines. This way reset would be much less frequent if the load is 
> distributed over engines (divided by num engines less frequent).

I win with a divide by 0 with removing the global seqno and wrap. :-p

The frequency we are talking about is a short wrap (will take as long as
the active request takes to sync) approximately every 47 days divided by
N engines. The cost of contention on struct_mutex must surely outweigh
that during those 47/N days...
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 14:04           ` Chris Wilson
@ 2018-04-24 14:48             ` Tvrtko Ursulin
  2018-04-24 15:58               ` Chris Wilson
  0 siblings, 1 reply; 26+ messages in thread
From: Tvrtko Ursulin @ 2018-04-24 14:48 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 24/04/2018 15:04, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2018-04-24 14:55:51)
>>
>> On 24/04/2018 12:28, Chris Wilson wrote:
>>> Quoting Tvrtko Ursulin (2018-04-24 12:17:15)
>>>>
>>>> On 24/04/2018 11:40, Chris Wilson wrote:
>>>>> Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
>>>>>>
>>>>>> On 23/04/2018 19:08, Chris Wilson wrote:
>>>>>>> -static int reserve_engine(struct intel_engine_cs *engine)
>>>>>>> +static int reserve_gt(struct drm_i915_private *i915)
>>>>>>>      {
>>>>>>> -     struct drm_i915_private *i915 = engine->i915;
>>>>>>> -     u32 active = ++engine->timeline->inflight_seqnos;
>>>>>>> -     u32 seqno = engine->timeline->seqno;
>>>>>>>          int ret;
>>>>>>>      
>>>>>>> -     /* Reservation is fine until we need to wrap around */
>>>>>>> -     if (unlikely(add_overflows(seqno, active))) {
>>>>>>> +     /*
>>>>>>> +      * Reservation is fine until we may need to wrap around
>>>>>>> +      *
>>>>>>> +      * By incrementing the serial for every request, we know that no
>>>>>>> +      * individual engine may exceed that serial (as each is reset to 0
>>>>>>> +      * on any wrap). This protects even the most pessimistic of migrations
>>>>>>> +      * of every request from all engines onto just one.
>>>>>>> +      */
>>>>>>
>>>>>> I didn't really figure out what was wrong with v1? Neither could handle
>>>>>> more than four billion of simultaneously active requests - but I thought
>>>>>> that should not concern us. :)
>>>>>
>>>>> It was still using the local engine->timeline.seqno as it's base. If we
>>>>> swapped from one at 0 to another at U32_MAX, we would overflow much
>>>>> later in submission; after the point of no return.
>>>>
>>>> By swapped you already refer to engine change? Ok, I can see that yes.
>>>> In this case global counter does prevent that.
>>>>
>>>> In the light of that, what is your current thinking with regards to
>>>> mixing engine classes?
>>>
>>> That classes are a hw limitation that doesn't impact on balancing itself,
>>> just which engines the user is allowed to put into the same group.
>>>
>>>> If the thinking is still to only allow within a class then per-class
>>>> seqno counter would be an option.
>>>
>>> The goal of localising the seqno here was to try and reduce the locking
>>> requirements (or at least make it easier to reduce them in future).
>>> Whether it's one u32 across all engines, or one u32 across a few isn't
>>> enough for me to worry. The breadcrumb tracking should be happy enough
>>> (sorted by i915_seqno_passed rather than absolute u32) so the only
>>> limitation in wrapping should be gen7 HW semaphores. Hmm, with a bit of
>>> thought, I believe we can reduce the wrap logic to simply skip semaphore
>>> sync inside the danger zone. Would be worth the effort.
>>
>> I was thinking about reducing the number of global seqno resets as much
>> as we can in general. For instance would it be possible to keep using
>> the gt.active_requests together with a new gt.max_engine_seqno? The
>> latter would be the maximum last allocated seqno from the engine
>> timelines. This way reset would be much less frequent if the load is
>> distributed over engines (divided by num engines less frequent).
> 
> I win with a divide by 0 with removing the global seqno and wrap. :-p
> 
> The frequency we are talking about is a short wrap (will take as long as
> the active request takes to sync) approximately every 47 days divided by
> N engines. The cost of contention on struct_mutex must surely outweigh
> that during those 47/N days...

You may be right, but where did 47 days come from? :)

Regards,

Tvrtko

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

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

* Re: [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos
  2018-04-24 14:48             ` Tvrtko Ursulin
@ 2018-04-24 15:58               ` Chris Wilson
  0 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-04-24 15:58 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2018-04-24 15:48:10)
> 
> On 24/04/2018 15:04, Chris Wilson wrote:
> > Quoting Tvrtko Ursulin (2018-04-24 14:55:51)
> >>
> >> On 24/04/2018 12:28, Chris Wilson wrote:
> >>> Quoting Tvrtko Ursulin (2018-04-24 12:17:15)
> >>>>
> >>>> On 24/04/2018 11:40, Chris Wilson wrote:
> >>>>> Quoting Tvrtko Ursulin (2018-04-24 11:14:21)
> >>>>>>
> >>>>>> On 23/04/2018 19:08, Chris Wilson wrote:
> >>>>>>> -static int reserve_engine(struct intel_engine_cs *engine)
> >>>>>>> +static int reserve_gt(struct drm_i915_private *i915)
> >>>>>>>      {
> >>>>>>> -     struct drm_i915_private *i915 = engine->i915;
> >>>>>>> -     u32 active = ++engine->timeline->inflight_seqnos;
> >>>>>>> -     u32 seqno = engine->timeline->seqno;
> >>>>>>>          int ret;
> >>>>>>>      
> >>>>>>> -     /* Reservation is fine until we need to wrap around */
> >>>>>>> -     if (unlikely(add_overflows(seqno, active))) {
> >>>>>>> +     /*
> >>>>>>> +      * Reservation is fine until we may need to wrap around
> >>>>>>> +      *
> >>>>>>> +      * By incrementing the serial for every request, we know that no
> >>>>>>> +      * individual engine may exceed that serial (as each is reset to 0
> >>>>>>> +      * on any wrap). This protects even the most pessimistic of migrations
> >>>>>>> +      * of every request from all engines onto just one.
> >>>>>>> +      */
> >>>>>>
> >>>>>> I didn't really figure out what was wrong with v1? Neither could handle
> >>>>>> more than four billion of simultaneously active requests - but I thought
> >>>>>> that should not concern us. :)
> >>>>>
> >>>>> It was still using the local engine->timeline.seqno as it's base. If we
> >>>>> swapped from one at 0 to another at U32_MAX, we would overflow much
> >>>>> later in submission; after the point of no return.
> >>>>
> >>>> By swapped you already refer to engine change? Ok, I can see that yes.
> >>>> In this case global counter does prevent that.
> >>>>
> >>>> In the light of that, what is your current thinking with regards to
> >>>> mixing engine classes?
> >>>
> >>> That classes are a hw limitation that doesn't impact on balancing itself,
> >>> just which engines the user is allowed to put into the same group.
> >>>
> >>>> If the thinking is still to only allow within a class then per-class
> >>>> seqno counter would be an option.
> >>>
> >>> The goal of localising the seqno here was to try and reduce the locking
> >>> requirements (or at least make it easier to reduce them in future).
> >>> Whether it's one u32 across all engines, or one u32 across a few isn't
> >>> enough for me to worry. The breadcrumb tracking should be happy enough
> >>> (sorted by i915_seqno_passed rather than absolute u32) so the only
> >>> limitation in wrapping should be gen7 HW semaphores. Hmm, with a bit of
> >>> thought, I believe we can reduce the wrap logic to simply skip semaphore
> >>> sync inside the danger zone. Would be worth the effort.
> >>
> >> I was thinking about reducing the number of global seqno resets as much
> >> as we can in general. For instance would it be possible to keep using
> >> the gt.active_requests together with a new gt.max_engine_seqno? The
> >> latter would be the maximum last allocated seqno from the engine
> >> timelines. This way reset would be much less frequent if the load is
> >> distributed over engines (divided by num engines less frequent).
> > 
> > I win with a divide by 0 with removing the global seqno and wrap. :-p
> > 
> > The frequency we are talking about is a short wrap (will take as long as
> > the active request takes to sync) approximately every 47 days divided by
> > N engines. The cost of contention on struct_mutex must surely outweigh
> > that during those 47/N days...
> 
> You may be right, but where did 47 days come from? :)

U32_MAX * assumed throughput of 1ms per request.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2018-04-24 15:58 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-23 18:08 [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Chris Wilson
2018-04-23 18:08 ` [PATCH v2 2/6] drm/i915: Retire requests along rings Chris Wilson
2018-04-23 18:08 ` [PATCH v2 3/6] drm/i915: Only track live rings for retiring Chris Wilson
2018-04-24  9:37   ` Tvrtko Ursulin
2018-04-24  9:43     ` Chris Wilson
2018-04-23 18:08 ` [PATCH v2 4/6] drm/i915: Move timeline from GTT to ring Chris Wilson
2018-04-23 18:08 ` [PATCH v2 5/6] drm/i915: Split i915_gem_timeline into individual timelines Chris Wilson
2018-04-23 23:11   ` [PATCH] " Chris Wilson
2018-04-23 18:08 ` [PATCH v2 6/6] drm/i915: Lazily unbind vma on close Chris Wilson
2018-04-23 18:17 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos Patchwork
2018-04-23 18:19 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-04-23 18:32 ` ✗ Fi.CI.BAT: failure " Patchwork
2018-04-23 20:29 ` ✗ Fi.CI.CHECKPATCH: warning " Patchwork
2018-04-23 20:32 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-04-23 20:46 ` ✗ Fi.CI.BAT: failure " Patchwork
2018-04-23 23:53 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/6] drm/i915: Stop tracking timeline->inflight_seqnos (rev2) Patchwork
2018-04-23 23:55 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-04-24  0:08 ` ✗ Fi.CI.BAT: failure " Patchwork
2018-04-24 10:14 ` [PATCH v2 1/6] drm/i915: Stop tracking timeline->inflight_seqnos Tvrtko Ursulin
2018-04-24 10:40   ` Chris Wilson
2018-04-24 11:17     ` Tvrtko Ursulin
2018-04-24 11:28       ` Chris Wilson
2018-04-24 13:55         ` Tvrtko Ursulin
2018-04-24 14:04           ` Chris Wilson
2018-04-24 14:48             ` Tvrtko Ursulin
2018-04-24 15:58               ` Chris Wilson

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.