All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 02/20] drm/i915/gt: Hook up intel_context_fini()
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-22 12:22   ` Tvrtko Ursulin
  2019-07-18  7:00 ` [PATCH 04/20] drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine Chris Wilson
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Prior to freeing the struct, call the fini function to cleanup the
common members. Currently this only calls the debug functions to mark
the structs as destroyed, but may be extended to real work in future.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_context.c    | 6 ++++++
 drivers/gpu/drm/i915/gt/intel_context.h    | 1 +
 drivers/gpu/drm/i915/gt/intel_lrc.c        | 2 ++
 drivers/gpu/drm/i915/gt/intel_ringbuffer.c | 1 +
 drivers/gpu/drm/i915/gt/mock_engine.c      | 1 +
 5 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index b667e2b35804..9292b6ca5e9c 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -204,6 +204,12 @@ intel_context_init(struct intel_context *ce,
 			 __intel_context_active, __intel_context_retire);
 }
 
+void intel_context_fini(struct intel_context *ce)
+{
+	mutex_destroy(&ce->pin_mutex);
+	i915_active_fini(&ce->active);
+}
+
 static void i915_global_context_shrink(void)
 {
 	kmem_cache_shrink(global.slab_ce);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index b41c610c2ce6..23c7e4c0ce7c 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -16,6 +16,7 @@
 void intel_context_init(struct intel_context *ce,
 			struct i915_gem_context *ctx,
 			struct intel_engine_cs *engine);
+void intel_context_fini(struct intel_context *ce);
 
 struct intel_context *
 intel_context_create(struct i915_gem_context *ctx,
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index d076d9148b6d..f95a042a92c6 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1553,6 +1553,7 @@ static void execlists_context_destroy(struct kref *kref)
 	if (ce->state)
 		__execlists_context_fini(ce);
 
+	intel_context_fini(ce);
 	intel_context_free(ce);
 }
 
@@ -3186,6 +3187,7 @@ static void virtual_context_destroy(struct kref *kref)
 
 	if (ve->context.state)
 		__execlists_context_fini(&ve->context);
+	intel_context_fini(&ve->context);
 
 	kfree(ve->bonds);
 	kfree(ve);
diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
index 901ce1a94664..b056f25c66f2 100644
--- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
@@ -1388,6 +1388,7 @@ static void ring_context_destroy(struct kref *ref)
 	if (ce->state)
 		__ring_context_fini(ce);
 
+	intel_context_fini(ce);
 	intel_context_free(ce);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index 490ebd121f4c..10cb312462e5 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -142,6 +142,7 @@ static void mock_context_destroy(struct kref *ref)
 	if (ce->ring)
 		mock_ring_free(ce->ring);
 
+	intel_context_fini(ce);
 	intel_context_free(ce);
 }
 
-- 
2.22.0

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

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

* [PATCH 04/20] drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
  2019-07-18  7:00 ` [PATCH 02/20] drm/i915/gt: Hook up intel_context_fini() Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:00 ` [PATCH 05/20] drm/i915: Hide unshrinkable context objects from the shrinker Chris Wilson
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

As we unwind the requests for a preemption event, we return a virtual
request back to its original virtual engine (so that it is available for
execution on any of its siblings). In the process, this means that its
breadcrumb should no longer be associated with the original physical
engine, and so we are forced to decouple it. Previously, as the request
could not complete without our awareness, we would move it to the next
real engine without any danger. However, preempt-to-busy allowed for
requests to continue on the HW and complete in the background as we
unwound, which meant that we could end up retiring the request before
fixing up the breadcrumb link.

[51679.517943] INFO: trying to register non-static key.
[51679.517956] the code is fine but needs lockdep annotation.
[51679.517960] turning off the locking correctness validator.
[51679.517966] CPU: 0 PID: 3270 Comm: kworker/u8:0 Tainted: G     U            5.2.0+ #717
[51679.517971] Hardware name: Intel Corporation NUC7i5BNK/NUC7i5BNB, BIOS BNKBL357.86A.0052.2017.0918.1346 09/18/2017
[51679.518012] Workqueue: i915 retire_work_handler [i915]
[51679.518017] Call Trace:
[51679.518026]  dump_stack+0x67/0x90
[51679.518031]  register_lock_class+0x52c/0x540
[51679.518038]  ? find_held_lock+0x2d/0x90
[51679.518042]  __lock_acquire+0x68/0x1800
[51679.518047]  ? find_held_lock+0x2d/0x90
[51679.518073]  ? __i915_sw_fence_complete+0xff/0x1c0 [i915]
[51679.518079]  lock_acquire+0x90/0x170
[51679.518105]  ? i915_request_cancel_breadcrumb+0x29/0x160 [i915]
[51679.518112]  _raw_spin_lock+0x27/0x40
[51679.518138]  ? i915_request_cancel_breadcrumb+0x29/0x160 [i915]
[51679.518165]  i915_request_cancel_breadcrumb+0x29/0x160 [i915]
[51679.518199]  i915_request_retire+0x43f/0x530 [i915]
[51679.518232]  retire_requests+0x4d/0x60 [i915]
[51679.518263]  i915_retire_requests+0xdf/0x1f0 [i915]
[51679.518294]  retire_work_handler+0x4c/0x60 [i915]
[51679.518301]  process_one_work+0x22c/0x5c0
[51679.518307]  worker_thread+0x37/0x390
[51679.518311]  ? process_one_work+0x5c0/0x5c0
[51679.518316]  kthread+0x116/0x130
[51679.518320]  ? kthread_create_on_node+0x40/0x40
[51679.518325]  ret_from_fork+0x24/0x30
[51679.520177] ------------[ cut here ]------------
[51679.520189] list_del corruption, ffff88883675e2f0->next is LIST_POISON1 (dead000000000100)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111159
Fixes: 22b7a426bbe1 ("drm/i915/execlists: Preempt-to-busy")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_lrc.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index f95a042a92c6..884dfc1cb033 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -495,6 +495,19 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
 			list_move(&rq->sched.link, pl);
 			active = rq;
 		} else {
+			/*
+			 * Decouple the virtual breadcrumb before moving it
+			 * back to the virtual engine -- we don't want the
+			 * request to complete in the background and try
+			 * and cancel the breadcrumb on the virtual engine
+			 * (instead of the old engine where it is linked)!
+			 */
+			if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
+				     &rq->fence.flags)) {
+				spin_lock(&rq->lock);
+				i915_request_cancel_breadcrumb(rq);
+				spin_unlock(&rq->lock);
+			}
 			rq->engine = owner;
 			owner->submit_request(rq);
 			active = NULL;
-- 
2.22.0

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

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

* [PATCH 05/20] drm/i915: Hide unshrinkable context objects from the shrinker
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
  2019-07-18  7:00 ` [PATCH 02/20] drm/i915/gt: Hook up intel_context_fini() Chris Wilson
  2019-07-18  7:00 ` [PATCH 04/20] drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:00 ` [PATCH 06/20] drm/i915: Remove obsolete engine cleanup Chris Wilson
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

The shrinker cannot touch objects used by the contexts (logical state
and ring). Currently we mark those as "pin_global" to let the shrinker
skip over them, however, if we remove them from the shrinker lists
entirely, we don't event have to include them in our shrink accounting.

By keeping the unshrinkable objects in our shrinker tracking, we report
a large number of objects available to be shrunk, and leave the shrinker
deeply unsatisfied when we fail to reclaim those. The shrinker will
persist in trying to reclaim the unavailable objects, forcing the system
into a livelock (not even hitting the dread oomkiller).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c   | 11 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object.h   |  4 ++
 drivers/gpu/drm/i915/gem/i915_gem_pages.c    | 13 +----
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 57 ++++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_context.c      |  4 +-
 drivers/gpu/drm/i915/gt/intel_ringbuffer.c   | 17 +++---
 drivers/gpu/drm/i915/i915_debugfs.c          |  3 +-
 drivers/gpu/drm/i915/i915_vma.c              | 15 ++++++
 drivers/gpu/drm/i915/i915_vma.h              |  4 ++
 9 files changed, 97 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index d5197a2a106f..4ea97fca9c35 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -63,6 +63,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	spin_lock_init(&obj->vma.lock);
 	INIT_LIST_HEAD(&obj->vma.list);
 
+	INIT_LIST_HEAD(&obj->mm.link);
+
 	INIT_LIST_HEAD(&obj->lut_list);
 	INIT_LIST_HEAD(&obj->batch_pool_link);
 
@@ -273,14 +275,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
 	 * or else we may oom whilst there are plenty of deferred
 	 * freed objects.
 	 */
-	if (i915_gem_object_has_pages(obj) &&
-	    i915_gem_object_is_shrinkable(obj)) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&i915->mm.obj_lock, flags);
-		list_del_init(&obj->mm.link);
-		spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
-	}
+	i915_gem_object_make_unshrinkable(obj);
 
 	/*
 	 * Since we require blocking on struct_mutex to unbind the freed
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 67aea07ea019..3714cf234d64 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -394,6 +394,10 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 				     unsigned int flags);
 void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
 
+void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj);
+void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj);
+void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj);
+
 static inline bool cpu_write_needs_clflush(struct drm_i915_gem_object *obj)
 {
 	if (obj->cache_dirty)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index b36ad269f4ea..92ad3cc220e3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -153,24 +153,13 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj)
 struct sg_table *
 __i915_gem_object_unset_pages(struct drm_i915_gem_object *obj)
 {
-	struct drm_i915_private *i915 = to_i915(obj->base.dev);
 	struct sg_table *pages;
 
 	pages = fetch_and_zero(&obj->mm.pages);
 	if (IS_ERR_OR_NULL(pages))
 		return pages;
 
-	if (i915_gem_object_is_shrinkable(obj)) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&i915->mm.obj_lock, flags);
-
-		list_del(&obj->mm.link);
-		i915->mm.shrink_count--;
-		i915->mm.shrink_memory -= obj->base.size;
-
-		spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
-	}
+	i915_gem_object_make_unshrinkable(obj);
 
 	if (obj->mm.mapping) {
 		void *ptr;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 3f4c6bdcc3c3..14abfd77365f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -530,3 +530,60 @@ void i915_gem_shrinker_taints_mutex(struct drm_i915_private *i915,
 	if (unlock)
 		mutex_release(&i915->drm.struct_mutex.dep_map, 0, _RET_IP_);
 }
+
+void i915_gem_object_make_unshrinkable(struct drm_i915_gem_object *obj)
+{
+	if (!list_empty(&obj->mm.link)) {
+		struct drm_i915_private *i915 = to_i915(obj->base.dev);
+		unsigned long flags;
+
+		spin_lock_irqsave(&i915->mm.obj_lock, flags);
+		GEM_BUG_ON(list_empty(&obj->mm.link));
+
+		list_del_init(&obj->mm.link);
+		i915->mm.shrink_count--;
+		i915->mm.shrink_memory -= obj->base.size;
+
+		spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
+	}
+}
+
+void i915_gem_object_make_shrinkable(struct drm_i915_gem_object *obj)
+{
+	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
+	GEM_BUG_ON(!list_empty(&obj->mm.link));
+
+	if (i915_gem_object_is_shrinkable(obj)) {
+		struct drm_i915_private *i915 = to_i915(obj->base.dev);
+		unsigned long flags;
+
+		spin_lock_irqsave(&i915->mm.obj_lock, flags);
+		GEM_BUG_ON(!kref_read(&obj->base.refcount));
+
+		list_add_tail(&obj->mm.link, &i915->mm.shrink_list);
+		i915->mm.shrink_count++;
+		i915->mm.shrink_memory += obj->base.size;
+
+		spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
+	}
+}
+
+void i915_gem_object_make_purgeable(struct drm_i915_gem_object *obj)
+{
+	GEM_BUG_ON(!i915_gem_object_has_pages(obj));
+	GEM_BUG_ON(!list_empty(&obj->mm.link));
+
+	if (i915_gem_object_is_shrinkable(obj)) {
+		struct drm_i915_private *i915 = to_i915(obj->base.dev);
+		unsigned long flags;
+
+		spin_lock_irqsave(&i915->mm.obj_lock, flags);
+		GEM_BUG_ON(!kref_read(&obj->base.refcount));
+
+		list_add_tail(&obj->mm.link, &i915->mm.purge_list);
+		i915->mm.shrink_count++;
+		i915->mm.shrink_memory += obj->base.size;
+
+		spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
+	}
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 9e4f51ce52ff..9830edda1ade 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -118,7 +118,7 @@ static int __context_pin_state(struct i915_vma *vma)
 	 * And mark it as a globally pinned object to let the shrinker know
 	 * it cannot reclaim the object until we release it.
 	 */
-	vma->obj->pin_global++;
+	i915_vma_make_unshrinkable(vma);
 	vma->obj->mm.dirty = true;
 
 	return 0;
@@ -126,8 +126,8 @@ static int __context_pin_state(struct i915_vma *vma)
 
 static void __context_unpin_state(struct i915_vma *vma)
 {
-	vma->obj->pin_global--;
 	__i915_vma_unpin(vma);
+	i915_vma_make_shrinkable(vma);
 }
 
 static void __intel_context_retire(struct i915_active *active)
diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
index 38ec11ae6ed7..d8efb88f33f3 100644
--- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
@@ -1238,7 +1238,7 @@ int intel_ring_pin(struct intel_ring *ring)
 		goto err_ring;
 	}
 
-	vma->obj->pin_global++;
+	i915_vma_make_unshrinkable(vma);
 
 	GEM_BUG_ON(ring->vaddr);
 	ring->vaddr = addr;
@@ -1267,6 +1267,8 @@ void intel_ring_reset(struct intel_ring *ring, u32 tail)
 
 void intel_ring_unpin(struct intel_ring *ring)
 {
+	struct i915_vma *vma = ring->vma;
+
 	if (!atomic_dec_and_test(&ring->pin_count))
 		return;
 
@@ -1275,18 +1277,17 @@ void intel_ring_unpin(struct intel_ring *ring)
 	/* Discard any unused bytes beyond that submitted to hw. */
 	intel_ring_reset(ring, ring->tail);
 
-	GEM_BUG_ON(!ring->vma);
-	i915_vma_unset_ggtt_write(ring->vma);
-	if (i915_vma_is_map_and_fenceable(ring->vma))
-		i915_vma_unpin_iomap(ring->vma);
+	i915_vma_unset_ggtt_write(vma);
+	if (i915_vma_is_map_and_fenceable(vma))
+		i915_vma_unpin_iomap(vma);
 	else
-		i915_gem_object_unpin_map(ring->vma->obj);
+		i915_gem_object_unpin_map(vma->obj);
 
 	GEM_BUG_ON(!ring->vaddr);
 	ring->vaddr = NULL;
 
-	ring->vma->obj->pin_global--;
-	i915_vma_unpin(ring->vma);
+	i915_vma_unpin(vma);
+	i915_vma_make_purgeable(vma);
 
 	intel_timeline_unpin(ring->timeline);
 }
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 6b84d04a6a28..c43f270085f5 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -363,8 +363,9 @@ static int i915_gem_object_info(struct seq_file *m, void *data)
 	struct drm_i915_private *i915 = node_to_i915(m->private);
 	int ret;
 
-	seq_printf(m, "%u shrinkable objects, %llu bytes\n",
+	seq_printf(m, "%u shrinkable [%u free] objects, %llu bytes\n",
 		   i915->mm.shrink_count,
+		   atomic_read(&i915->mm.free_count),
 		   i915->mm.shrink_memory);
 
 	seq_putc(m, '\n');
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index eb16a1a93bbc..e27ddbff487e 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1030,6 +1030,21 @@ int i915_vma_unbind(struct i915_vma *vma)
 	return 0;
 }
 
+void i915_vma_make_unshrinkable(struct i915_vma *vma)
+{
+	i915_gem_object_make_unshrinkable(vma->obj);
+}
+
+void i915_vma_make_shrinkable(struct i915_vma *vma)
+{
+	i915_gem_object_make_shrinkable(vma->obj);
+}
+
+void i915_vma_make_purgeable(struct i915_vma *vma)
+{
+	i915_gem_object_make_purgeable(vma->obj);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftests/i915_vma.c"
 #endif
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 4b769db649bf..a24bd6787ef7 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -459,4 +459,8 @@ void i915_vma_parked(struct drm_i915_private *i915);
 struct i915_vma *i915_vma_alloc(void);
 void i915_vma_free(struct i915_vma *vma);
 
+void i915_vma_make_unshrinkable(struct i915_vma *vma);
+void i915_vma_make_shrinkable(struct i915_vma *vma);
+void i915_vma_make_purgeable(struct i915_vma *vma);
+
 #endif
-- 
2.22.0

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

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

* [PATCH 06/20] drm/i915: Remove obsolete engine cleanup
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (2 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 05/20] drm/i915: Hide unshrinkable context objects from the shrinker Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-22 12:46   ` Tvrtko Ursulin
  2019-07-18  7:00 ` [PATCH 07/20] drm/i915/gt: Move the [class][inst] lookup for engines onto the GT Chris Wilson
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Remove the outer layer cleanup of engine stubs; as i915_drv itself no
longer tries to preallocate and so is not responsible for either the
allocation or free. By the time we call the cleanup function, we already
have cleaned up the engines.

v2: Lack of symmetry between mmio_probe and mmio_release for handling
the error cleanup. engine->destroy() is a compound function that is
called earlier in the normal release as it ties together other bits of
state.

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

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 7c209743e478..d1c3499c8e03 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -848,15 +848,6 @@ static int i915_workqueues_init(struct drm_i915_private *dev_priv)
 	return -ENOMEM;
 }
 
-static void i915_engines_cleanup(struct drm_i915_private *i915)
-{
-	struct intel_engine_cs *engine;
-	enum intel_engine_id id;
-
-	for_each_engine(engine, i915, id)
-		kfree(engine);
-}
-
 static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
 {
 	destroy_workqueue(dev_priv->hotplug.dp_wq);
@@ -928,7 +919,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
 
 	ret = i915_workqueues_init(dev_priv);
 	if (ret < 0)
-		goto err_engines;
+		return ret;
 
 	intel_gt_init_early(&dev_priv->gt, dev_priv);
 
@@ -961,8 +952,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
 	i915_gem_cleanup_early(dev_priv);
 err_workqueues:
 	i915_workqueues_cleanup(dev_priv);
-err_engines:
-	i915_engines_cleanup(dev_priv);
 	return ret;
 }
 
@@ -978,7 +967,6 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv)
 	intel_uc_cleanup_early(&dev_priv->gt.uc);
 	i915_gem_cleanup_early(dev_priv);
 	i915_workqueues_cleanup(dev_priv);
-	i915_engines_cleanup(dev_priv);
 
 	pm_qos_remove_request(&dev_priv->sb_qos);
 	mutex_destroy(&dev_priv->sb_lock);
@@ -1039,6 +1027,7 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv)
  */
 static void i915_driver_mmio_release(struct drm_i915_private *dev_priv)
 {
+	intel_engines_cleanup(dev_priv);
 	intel_teardown_mchbar(dev_priv);
 	intel_uncore_fini_mmio(&dev_priv->uncore);
 	pci_dev_put(dev_priv->bridge_dev);
-- 
2.22.0

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

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

* [PATCH 07/20] drm/i915/gt: Move the [class][inst] lookup for engines onto the GT
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (3 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 06/20] drm/i915: Remove obsolete engine cleanup Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:00 ` [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc Chris Wilson
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

To maintain a fast lookup from a GT centric irq handler, we want the
engine lookup tables on the intel_gt. To avoid having multiple copies of
the same multi-dimension lookup table, move the generic user engine
lookup into an rbtree (for fast and flexible indexing).

v2: Split uabi_instance cf uabi_class

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_context.c  |  3 +-
 drivers/gpu/drm/i915/gt/intel_engine.h       |  3 -
 drivers/gpu/drm/i915/gt/intel_engine_cs.c    | 53 +++++-----------
 drivers/gpu/drm/i915/gt/intel_engine_types.h |  9 ++-
 drivers/gpu/drm/i915/gt/intel_engine_user.c  | 66 ++++++++++++++++++++
 drivers/gpu/drm/i915/gt/intel_engine_user.h  | 20 ++++++
 drivers/gpu/drm/i915/gt/intel_gt_types.h     |  4 ++
 drivers/gpu/drm/i915/gt/selftest_lrc.c       | 15 +++--
 drivers/gpu/drm/i915/i915_drv.h              |  7 ++-
 drivers/gpu/drm/i915/i915_irq.c              |  2 +-
 drivers/gpu/drm/i915/i915_pmu.c              |  3 +-
 drivers/gpu/drm/i915/i915_query.c            |  2 +-
 drivers/gpu/drm/i915/i915_trace.h            | 10 +--
 14 files changed, 138 insertions(+), 60 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_user.c
 create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_user.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 524516251a40..fafc3763dc2d 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -74,6 +74,7 @@ gt-y += \
 	gt/intel_context.o \
 	gt/intel_engine_cs.o \
 	gt/intel_engine_pm.o \
+	gt/intel_engine_user.o \
 	gt/intel_gt.o \
 	gt/intel_gt_pm.o \
 	gt/intel_hangcheck.o \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index de9bb7aaef22..86c57cfb64d2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -70,6 +70,7 @@
 #include <drm/i915_drm.h>
 
 #include "gt/intel_lrc_reg.h"
+#include "gt/intel_engine_user.h"
 
 #include "i915_gem_context.h"
 #include "i915_globals.h"
@@ -1753,7 +1754,7 @@ get_engines(struct i915_gem_context *ctx,
 
 		if (e->engines[n]) {
 			ci.engine_class = e->engines[n]->engine->uabi_class;
-			ci.engine_instance = e->engines[n]->engine->instance;
+			ci.engine_instance = e->engines[n]->engine->uabi_instance;
 		}
 
 		if (copy_to_user(&user->engines[n], &ci, sizeof(ci))) {
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index db5c73ce86ee..30856383e4c5 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -432,9 +432,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 		       struct drm_printer *m,
 		       const char *header, ...);
 
-struct intel_engine_cs *
-intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
-
 static inline void intel_engine_context_in(struct intel_engine_cs *engine)
 {
 	unsigned long flags;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index c0bc9cb7f228..02b6565b2550 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -32,6 +32,7 @@
 
 #include "intel_engine.h"
 #include "intel_engine_pm.h"
+#include "intel_engine_user.h"
 #include "intel_context.h"
 #include "intel_lrc.h"
 #include "intel_reset.h"
@@ -285,9 +286,7 @@ static void intel_engine_sanitize_mmio(struct intel_engine_cs *engine)
 	intel_engine_set_hwsp_writemask(engine, ~0u);
 }
 
-static int
-intel_engine_setup(struct drm_i915_private *dev_priv,
-		   enum intel_engine_id id)
+static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
 {
 	const struct engine_info *info = &intel_engines[id];
 	struct intel_engine_cs *engine;
@@ -303,10 +302,9 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 	if (GEM_DEBUG_WARN_ON(info->instance > MAX_ENGINE_INSTANCE))
 		return -EINVAL;
 
-	if (GEM_DEBUG_WARN_ON(dev_priv->engine_class[info->class][info->instance]))
+	if (GEM_DEBUG_WARN_ON(gt->engine_class[info->class][info->instance]))
 		return -EINVAL;
 
-	GEM_BUG_ON(dev_priv->engine[id]);
 	engine = kzalloc(sizeof(*engine), GFP_KERNEL);
 	if (!engine)
 		return -ENOMEM;
@@ -315,12 +313,12 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 
 	engine->id = id;
 	engine->mask = BIT(id);
-	engine->i915 = dev_priv;
-	engine->gt = &dev_priv->gt;
-	engine->uncore = &dev_priv->uncore;
+	engine->i915 = gt->i915;
+	engine->gt = gt;
+	engine->uncore = gt->uncore;
 	__sprint_engine_name(engine->name, info);
 	engine->hw_id = engine->guc_id = info->hw_id;
-	engine->mmio_base = __engine_mmio_base(dev_priv, info->mmio_bases);
+	engine->mmio_base = __engine_mmio_base(gt->i915, info->mmio_bases);
 	engine->class = info->class;
 	engine->instance = info->instance;
 
@@ -331,13 +329,14 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 	engine->destroy = (typeof(engine->destroy))kfree;
 
 	engine->uabi_class = intel_engine_classes[info->class].uabi_class;
+	engine->uabi_instance = info->instance;
 
-	engine->context_size = intel_engine_context_size(dev_priv,
+	engine->context_size = intel_engine_context_size(gt->i915,
 							 engine->class);
 	if (WARN_ON(engine->context_size > BIT(20)))
 		engine->context_size = 0;
 	if (engine->context_size)
-		DRIVER_CAPS(dev_priv)->has_logical_contexts = true;
+		DRIVER_CAPS(gt->i915)->has_logical_contexts = true;
 
 	/* Nothing to do here, execute in order of dependencies */
 	engine->schedule = NULL;
@@ -349,8 +348,11 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 	/* Scrub mmio state on takeover */
 	intel_engine_sanitize_mmio(engine);
 
-	dev_priv->engine_class[info->class][info->instance] = engine;
-	dev_priv->engine[id] = engine;
+	engine->gt->engine_class[info->class][info->instance] = engine;
+
+	intel_engine_add_user(engine);
+	gt->i915->engine[id] = engine;
+
 	return 0;
 }
 
@@ -433,7 +435,7 @@ int intel_engines_init_mmio(struct drm_i915_private *i915)
 		if (!HAS_ENGINE(i915, i))
 			continue;
 
-		err = intel_engine_setup(i915, i);
+		err = intel_engine_setup(&i915->gt, i);
 		if (err)
 			goto cleanup;
 
@@ -1533,29 +1535,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 	intel_engine_print_breadcrumbs(engine, m);
 }
 
-static u8 user_class_map[] = {
-	[I915_ENGINE_CLASS_RENDER] = RENDER_CLASS,
-	[I915_ENGINE_CLASS_COPY] = COPY_ENGINE_CLASS,
-	[I915_ENGINE_CLASS_VIDEO] = VIDEO_DECODE_CLASS,
-	[I915_ENGINE_CLASS_VIDEO_ENHANCE] = VIDEO_ENHANCEMENT_CLASS,
-};
-
-struct intel_engine_cs *
-intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
-{
-	if (class >= ARRAY_SIZE(user_class_map))
-		return NULL;
-
-	class = user_class_map[class];
-
-	GEM_BUG_ON(class > MAX_ENGINE_CLASS);
-
-	if (instance > MAX_ENGINE_INSTANCE)
-		return NULL;
-
-	return i915->engine_class[class][instance];
-}
-
 /**
  * intel_enable_engine_stats() - Enable engine busy tracking on engine
  * @engine: engine to enable stats collection
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 8be63019d707..9c927fa408aa 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -12,6 +12,7 @@
 #include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/llist.h>
+#include <linux/rbtree.h>
 #include <linux/timer.h>
 #include <linux/types.h>
 
@@ -267,15 +268,19 @@ struct intel_engine_cs {
 	unsigned int guc_id;
 	intel_engine_mask_t mask;
 
-	u8 uabi_class;
-
 	u8 class;
 	u8 instance;
+
+	u8 uabi_class;
+	u8 uabi_instance;
+
 	u32 context_size;
 	u32 mmio_base;
 
 	u32 uabi_capabilities;
 
+	struct rb_node uabi_node;
+
 	struct intel_sseu sseu;
 
 	struct intel_ring *buffer;
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c b/drivers/gpu/drm/i915/gt/intel_engine_user.c
new file mode 100644
index 000000000000..f74fb4d2fa0d
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -0,0 +1,66 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "intel_engine.h"
+#include "intel_engine_user.h"
+
+struct intel_engine_cs *
+intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance)
+{
+	struct rb_node *p = i915->uabi_engines.rb_node;
+
+	while (p) {
+		struct intel_engine_cs *it =
+			rb_entry(p, typeof(*it), uabi_node);
+
+		if (class < it->uabi_class)
+			p = p->rb_left;
+		else if (class > it->uabi_class ||
+			 instance > it->uabi_instance)
+			p = p->rb_right;
+		else if (instance < it->uabi_instance)
+			p = p->rb_left;
+		else
+			return it;
+	}
+
+	return NULL;
+}
+
+void intel_engine_add_user(struct intel_engine_cs *engine)
+{
+	struct rb_root *root = &engine->i915->uabi_engines;
+	struct rb_node **p, *parent;
+
+	parent = NULL;
+	p = &root->rb_node;
+	while (*p) {
+		struct intel_engine_cs *it;
+
+		parent = *p;
+		it = rb_entry(parent, typeof(*it), uabi_node);
+
+		/* All user class:instance identifiers must be unique */
+		GEM_BUG_ON(it->uabi_class == engine->uabi_class &&
+			   it->uabi_instance == engine->uabi_instance);
+
+		if (engine->uabi_class < it->uabi_class)
+			p = &parent->rb_left;
+		else if (engine->uabi_class > it->uabi_class ||
+			 engine->uabi_instance > it->uabi_instance)
+			p = &parent->rb_right;
+		else
+			p = &parent->rb_left;
+	}
+
+	rb_link_node(&engine->uabi_node, parent, p);
+	rb_insert_color(&engine->uabi_node, root);
+
+	GEM_BUG_ON(intel_engine_lookup_user(engine->i915,
+					    engine->uabi_class,
+					    engine->uabi_instance) != engine);
+}
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.h b/drivers/gpu/drm/i915/gt/intel_engine_user.h
new file mode 100644
index 000000000000..091dc8a4a39f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.h
@@ -0,0 +1,20 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef INTEL_ENGINE_USER_H
+#define INTEL_ENGINE_USER_H
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_engine_cs;
+
+struct intel_engine_cs *
+intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
+
+void intel_engine_add_user(struct intel_engine_cs *engine);
+
+#endif /* INTEL_ENGINE_USER_H */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index 34d4a868e4f1..5fd11e361d03 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -21,6 +21,7 @@
 
 struct drm_i915_private;
 struct i915_ggtt;
+struct intel_engine_cs;
 struct intel_uncore;
 
 struct intel_hangcheck {
@@ -76,6 +77,9 @@ struct intel_gt {
 	u32 pm_ier;
 
 	u32 pm_guc_events;
+
+	struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
+					    [MAX_ENGINE_INSTANCE + 1];
 };
 
 enum intel_gt_scratch_field {
diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c
index 60f27e52d267..eb40a58665be 100644
--- a/drivers/gpu/drm/i915/gt/selftest_lrc.c
+++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c
@@ -1773,6 +1773,7 @@ static int live_virtual_engine(void *arg)
 	struct drm_i915_private *i915 = arg;
 	struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1];
 	struct intel_engine_cs *engine;
+	struct intel_gt *gt = &i915->gt;
 	enum intel_engine_id id;
 	unsigned int class, inst;
 	int err = -ENODEV;
@@ -1796,10 +1797,10 @@ static int live_virtual_engine(void *arg)
 
 		nsibling = 0;
 		for (inst = 0; inst <= MAX_ENGINE_INSTANCE; inst++) {
-			if (!i915->engine_class[class][inst])
+			if (!gt->engine_class[class][inst])
 				continue;
 
-			siblings[nsibling++] = i915->engine_class[class][inst];
+			siblings[nsibling++] = gt->engine_class[class][inst];
 		}
 		if (nsibling < 2)
 			continue;
@@ -1920,6 +1921,7 @@ static int live_virtual_mask(void *arg)
 {
 	struct drm_i915_private *i915 = arg;
 	struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1];
+	struct intel_gt *gt = &i915->gt;
 	unsigned int class, inst;
 	int err = 0;
 
@@ -1933,10 +1935,10 @@ static int live_virtual_mask(void *arg)
 
 		nsibling = 0;
 		for (inst = 0; inst <= MAX_ENGINE_INSTANCE; inst++) {
-			if (!i915->engine_class[class][inst])
+			if (!gt->engine_class[class][inst])
 				break;
 
-			siblings[nsibling++] = i915->engine_class[class][inst];
+			siblings[nsibling++] = gt->engine_class[class][inst];
 		}
 		if (nsibling < 2)
 			continue;
@@ -2097,6 +2099,7 @@ static int live_virtual_bond(void *arg)
 	};
 	struct drm_i915_private *i915 = arg;
 	struct intel_engine_cs *siblings[MAX_ENGINE_INSTANCE + 1];
+	struct intel_gt *gt = &i915->gt;
 	unsigned int class, inst;
 	int err = 0;
 
@@ -2111,11 +2114,11 @@ static int live_virtual_bond(void *arg)
 
 		nsibling = 0;
 		for (inst = 0; inst <= MAX_ENGINE_INSTANCE; inst++) {
-			if (!i915->engine_class[class][inst])
+			if (!gt->engine_class[class][inst])
 				break;
 
 			GEM_BUG_ON(nsibling == ARRAY_SIZE(siblings));
-			siblings[nsibling++] = i915->engine_class[class][inst];
+			siblings[nsibling++] = gt->engine_class[class][inst];
 		}
 		if (nsibling < 2)
 			continue;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5499fc5305f1..b8a69f236510 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1371,11 +1371,12 @@ struct drm_i915_private {
 	wait_queue_head_t gmbus_wait_queue;
 
 	struct pci_dev *bridge_dev;
-	struct intel_engine_cs *engine[I915_NUM_ENGINES];
+
 	/* Context used internally to idle the GPU and setup initial state */
 	struct i915_gem_context *kernel_context;
-	struct intel_engine_cs *engine_class[MAX_ENGINE_CLASS + 1]
-					    [MAX_ENGINE_INSTANCE + 1];
+
+	struct intel_engine_cs *engine[I915_NUM_ENGINES];
+	struct rb_root uabi_engines;
 
 	struct resource mch_res;
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 91f8c81028c3..af1bb653579a 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -3106,7 +3106,7 @@ gen11_engine_irq_handler(struct intel_gt *gt, const u8 class,
 	struct intel_engine_cs *engine;
 
 	if (instance <= MAX_ENGINE_INSTANCE)
-		engine = gt->i915->engine_class[class][instance];
+		engine = gt->engine_class[class][instance];
 	else
 		engine = NULL;
 
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index eff86483bec0..bdf7963a043b 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -8,6 +8,7 @@
 #include <linux/pm_runtime.h>
 
 #include "gt/intel_engine.h"
+#include "gt/intel_engine_user.h"
 
 #include "i915_drv.h"
 #include "i915_pmu.h"
@@ -926,7 +927,7 @@ create_event_attributes(struct drm_i915_private *i915)
 			i915_iter =
 				add_i915_attr(i915_iter, str,
 					      __I915_PMU_ENGINE(engine->uabi_class,
-								engine->instance,
+								engine->uabi_instance,
 								engine_events[i].sample));
 
 			str = kasprintf(GFP_KERNEL, "%s-%s.unit",
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index 7b7016171057..70b1ad38e615 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -127,7 +127,7 @@ query_engine_info(struct drm_i915_private *i915,
 
 	for_each_engine(engine, i915, id) {
 		info.engine.engine_class = engine->uabi_class;
-		info.engine.engine_instance = engine->instance;
+		info.engine.engine_instance = engine->uabi_instance;
 		info.capabilities = engine->uabi_capabilities;
 
 		if (__copy_to_user(info_ptr, &info, sizeof(info)))
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index da18b8d6b80c..1d11245c4c87 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -677,7 +677,7 @@ TRACE_EVENT(i915_request_queue,
 			   __entry->dev = rq->i915->drm.primary->index;
 			   __entry->hw_id = rq->gem_context->hw_id;
 			   __entry->class = rq->engine->uabi_class;
-			   __entry->instance = rq->engine->instance;
+			   __entry->instance = rq->engine->uabi_instance;
 			   __entry->ctx = rq->fence.context;
 			   __entry->seqno = rq->fence.seqno;
 			   __entry->flags = flags;
@@ -706,7 +706,7 @@ DECLARE_EVENT_CLASS(i915_request,
 			   __entry->dev = rq->i915->drm.primary->index;
 			   __entry->hw_id = rq->gem_context->hw_id;
 			   __entry->class = rq->engine->uabi_class;
-			   __entry->instance = rq->engine->instance;
+			   __entry->instance = rq->engine->uabi_instance;
 			   __entry->ctx = rq->fence.context;
 			   __entry->seqno = rq->fence.seqno;
 			   ),
@@ -751,7 +751,7 @@ TRACE_EVENT(i915_request_in,
 			   __entry->dev = rq->i915->drm.primary->index;
 			   __entry->hw_id = rq->gem_context->hw_id;
 			   __entry->class = rq->engine->uabi_class;
-			   __entry->instance = rq->engine->instance;
+			   __entry->instance = rq->engine->uabi_instance;
 			   __entry->ctx = rq->fence.context;
 			   __entry->seqno = rq->fence.seqno;
 			   __entry->prio = rq->sched.attr.priority;
@@ -782,7 +782,7 @@ TRACE_EVENT(i915_request_out,
 			   __entry->dev = rq->i915->drm.primary->index;
 			   __entry->hw_id = rq->gem_context->hw_id;
 			   __entry->class = rq->engine->uabi_class;
-			   __entry->instance = rq->engine->instance;
+			   __entry->instance = rq->engine->uabi_instance;
 			   __entry->ctx = rq->fence.context;
 			   __entry->seqno = rq->fence.seqno;
 			   __entry->completed = i915_request_completed(rq);
@@ -847,7 +847,7 @@ TRACE_EVENT(i915_request_wait_begin,
 			   __entry->dev = rq->i915->drm.primary->index;
 			   __entry->hw_id = rq->gem_context->hw_id;
 			   __entry->class = rq->engine->uabi_class;
-			   __entry->instance = rq->engine->instance;
+			   __entry->instance = rq->engine->uabi_instance;
 			   __entry->ctx = rq->fence.context;
 			   __entry->seqno = rq->fence.seqno;
 			   __entry->flags = flags;
-- 
2.22.0

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

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

* [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (4 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 07/20] drm/i915/gt: Move the [class][inst] lookup for engines onto the GT Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-22 12:49   ` Tvrtko Ursulin
  2019-07-18  7:00 ` [PATCH 11/20] drm/i915: Rely on spinlock protection for GPU error capture Chris Wilson
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Use the same mechanism to determine if a backend engine exists for a
uabi mapping as used internally.

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

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index d1c3499c8e03..367bdc4689f1 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -61,6 +61,7 @@
 
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_ioctls.h"
+#include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_reset.h"
@@ -371,16 +372,20 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
 		value = dev_priv->overlay ? 1 : 0;
 		break;
 	case I915_PARAM_HAS_BSD:
-		value = !!dev_priv->engine[VCS0];
+		value = !!intel_engine_lookup_user(dev_priv,
+						   I915_ENGINE_CLASS_VIDEO, 0);
 		break;
 	case I915_PARAM_HAS_BLT:
-		value = !!dev_priv->engine[BCS0];
+		value = !!intel_engine_lookup_user(dev_priv,
+						   I915_ENGINE_CLASS_COPY, 0);
 		break;
 	case I915_PARAM_HAS_VEBOX:
-		value = !!dev_priv->engine[VECS0];
+		value = !!intel_engine_lookup_user(dev_priv,
+						   I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
 		break;
 	case I915_PARAM_HAS_BSD2:
-		value = !!dev_priv->engine[VCS1];
+		value = !!intel_engine_lookup_user(dev_priv,
+						   I915_ENGINE_CLASS_VIDEO, 1);
 		break;
 	case I915_PARAM_HAS_LLC:
 		value = HAS_LLC(dev_priv);
-- 
2.22.0

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

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

* [PATCH 11/20] drm/i915: Rely on spinlock protection for GPU error capture
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (5 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-22 13:40   ` Tvrtko Ursulin
  2019-07-18  7:00 ` [PATCH 13/20] drm/i915: Teach execbuffer to take the engine wakeref not GT Chris Wilson
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Trust that we now have adequate protection over the low level structures
via the engine->active.lock to allow ourselves to capture the GPU error
state without the heavy hammer of stop_machine(). Sadly this does mean
that we have to forgo some of the lesser used information (not derived
from the active state) that is not controlled by the active locks. This
includes the list of buffers in the ppGTT and pinned globally in the
GGTT. Originally this was used to manually verify relocations, but
hasn't been required for sometime and modern mesa now has the habit of
ensuring that all interesting buffers within a batch are captured in their
entirety (that are the auxiliary state buffers, but not the textures).

A useful side-effect is that this allows us to restore error capturing
for Braswell and Broxton.

v2: Use pagevec for a typical random number

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c   |   5 -
 drivers/gpu/drm/i915/i915_gpu_error.c | 499 +++++++++++---------------
 drivers/gpu/drm/i915/i915_gpu_error.h |  17 -
 3 files changed, 203 insertions(+), 318 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 8f33d3e52b9e..500f3cdcc4b3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2966,11 +2966,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 		ggtt->vm.insert_page    = bxt_vtd_ggtt_insert_page__BKL;
 		if (ggtt->vm.clear_range != nop_clear_range)
 			ggtt->vm.clear_range = bxt_vtd_ggtt_clear_range__BKL;
-
-		/* Prevent recursively calling stop_machine() and deadlocks. */
-		dev_info(dev_priv->drm.dev,
-			 "Disabling error capture for VT-d workaround\n");
-		i915_disable_error_state(dev_priv, -ENODEV);
 	}
 
 	ggtt->invalidate = gen6_ggtt_invalidate;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 24835be300bc..131a52c428de 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -29,8 +29,8 @@
 
 #include <linux/ascii85.h>
 #include <linux/nmi.h>
+#include <linux/pagevec.h>
 #include <linux/scatterlist.h>
-#include <linux/stop_machine.h>
 #include <linux/utsname.h>
 #include <linux/zlib.h>
 
@@ -46,6 +46,9 @@
 #include "i915_scatterlist.h"
 #include "intel_csr.h"
 
+#define ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
+#define ATOMIC_MAYFAIL (GFP_ATOMIC | __GFP_NOWARN)
+
 static inline const struct intel_engine_cs *
 engine_lookup(const struct drm_i915_private *i915, unsigned int id)
 {
@@ -67,26 +70,6 @@ engine_name(const struct drm_i915_private *i915, unsigned int id)
 	return __engine_name(engine_lookup(i915, id));
 }
 
-static const char *tiling_flag(int tiling)
-{
-	switch (tiling) {
-	default:
-	case I915_TILING_NONE: return "";
-	case I915_TILING_X: return " X";
-	case I915_TILING_Y: return " Y";
-	}
-}
-
-static const char *dirty_flag(int dirty)
-{
-	return dirty ? " dirty" : "";
-}
-
-static const char *purgeable_flag(int purgeable)
-{
-	return purgeable ? " purgeable" : "";
-}
-
 static void __sg_set_buf(struct scatterlist *sg,
 			 void *addr, unsigned int len, loff_t it)
 {
@@ -114,7 +97,7 @@ static bool __i915_error_grow(struct drm_i915_error_state_buf *e, size_t len)
 	if (e->cur == e->end) {
 		struct scatterlist *sgl;
 
-		sgl = (typeof(sgl))__get_free_page(GFP_KERNEL);
+		sgl = (typeof(sgl))__get_free_page(ALLOW_FAIL);
 		if (!sgl) {
 			e->err = -ENOMEM;
 			return false;
@@ -134,7 +117,7 @@ static bool __i915_error_grow(struct drm_i915_error_state_buf *e, size_t len)
 	}
 
 	e->size = ALIGN(len + 1, SZ_64K);
-	e->buf = kmalloc(e->size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+	e->buf = kmalloc(e->size, ALLOW_FAIL);
 	if (!e->buf) {
 		e->size = PAGE_ALIGN(len + 1);
 		e->buf = kmalloc(e->size, GFP_KERNEL);
@@ -211,47 +194,125 @@ i915_error_printer(struct drm_i915_error_state_buf *e)
 	return p;
 }
 
+/* single threaded page allocator with a reserved stash for emergencies */
+static void *__alloc_page(gfp_t gfp)
+{
+	return (void *)__get_free_page(gfp);
+}
+
+static void pool_fini(struct pagevec *pv)
+{
+	pagevec_release(pv);
+}
+
+static int pool_refill(struct pagevec *pv, gfp_t gfp)
+{
+	while (pagevec_space(pv)) {
+		struct page *p;
+
+		p = alloc_page(gfp);
+		if (!p)
+			return -ENOMEM;
+
+		pagevec_add(pv, p);
+	}
+
+	return 0;
+}
+
+static int pool_init(struct pagevec *pv, gfp_t gfp)
+{
+	int err;
+
+	pagevec_init(pv);
+
+	err = pool_refill(pv, gfp);
+	if (err)
+		pool_fini(pv);
+
+	return err;
+}
+
+static void *pool_alloc(struct pagevec *pv, gfp_t gfp)
+{
+	void *ptr;
+
+	ptr = __alloc_page(gfp);
+	if (ptr)
+		return ptr;
+
+	if (!pagevec_count(pv))
+		return NULL;
+
+	return page_address(pv->pages[--pv->nr]);
+}
+
+static void pool_free(struct pagevec *pv, void *addr)
+{
+	struct page *p = virt_to_page(addr);
+
+	if (pagevec_space(pv)) {
+		pv->pages[pv->nr++] = p;
+		return;
+	}
+
+	__free_pages(p, 0);
+}
+
 #ifdef CONFIG_DRM_I915_COMPRESS_ERROR
 
 struct compress {
+	struct pagevec pool;
 	struct z_stream_s zstream;
 	void *tmp;
 };
 
 static bool compress_init(struct compress *c)
 {
-	struct z_stream_s *zstream = memset(&c->zstream, 0, sizeof(c->zstream));
+	struct z_stream_s *zstream = &c->zstream;
 
-	zstream->workspace =
-		kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
-			GFP_ATOMIC | __GFP_NOWARN);
-	if (!zstream->workspace)
+	if (pool_init(&c->pool, ALLOW_FAIL))
 		return false;
 
-	if (zlib_deflateInit(zstream, Z_DEFAULT_COMPRESSION) != Z_OK) {
-		kfree(zstream->workspace);
+	zstream->workspace =
+		kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
+			ALLOW_FAIL);
+	if (!zstream->workspace) {
+		pool_fini(&c->pool);
 		return false;
 	}
 
 	c->tmp = NULL;
 	if (i915_has_memcpy_from_wc())
-		c->tmp = (void *)__get_free_page(GFP_ATOMIC | __GFP_NOWARN);
+		c->tmp = pool_alloc(&c->pool, ALLOW_FAIL);
 
 	return true;
 }
 
-static void *compress_next_page(struct drm_i915_error_object *dst)
+static bool compress_start(struct compress *c)
 {
-	unsigned long page;
+	struct z_stream_s *zstream = &c->zstream;
+	void *workspace = zstream->workspace;
+
+	memset(zstream, 0, sizeof(*zstream));
+	zstream->workspace = workspace;
+
+	return zlib_deflateInit(zstream, Z_DEFAULT_COMPRESSION) == Z_OK;
+}
+
+static void *compress_next_page(struct compress *c,
+				struct drm_i915_error_object *dst)
+{
+	void *page;
 
 	if (dst->page_count >= dst->num_pages)
 		return ERR_PTR(-ENOSPC);
 
-	page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
+	page = pool_alloc(&c->pool, ATOMIC_MAYFAIL);
 	if (!page)
 		return ERR_PTR(-ENOMEM);
 
-	return dst->pages[dst->page_count++] = (void *)page;
+	return dst->pages[dst->page_count++] = page;
 }
 
 static int compress_page(struct compress *c,
@@ -267,7 +328,7 @@ static int compress_page(struct compress *c,
 
 	do {
 		if (zstream->avail_out == 0) {
-			zstream->next_out = compress_next_page(dst);
+			zstream->next_out = compress_next_page(c, dst);
 			if (IS_ERR(zstream->next_out))
 				return PTR_ERR(zstream->next_out);
 
@@ -295,7 +356,7 @@ static int compress_flush(struct compress *c,
 	do {
 		switch (zlib_deflate(zstream, Z_FINISH)) {
 		case Z_OK: /* more space requested */
-			zstream->next_out = compress_next_page(dst);
+			zstream->next_out = compress_next_page(c, dst);
 			if (IS_ERR(zstream->next_out))
 				return PTR_ERR(zstream->next_out);
 
@@ -316,15 +377,17 @@ static int compress_flush(struct compress *c,
 	return 0;
 }
 
-static void compress_fini(struct compress *c,
-			  struct drm_i915_error_object *dst)
+static void compress_finish(struct compress *c)
 {
-	struct z_stream_s *zstream = &c->zstream;
+	zlib_deflateEnd(&c->zstream);
+}
 
-	zlib_deflateEnd(zstream);
-	kfree(zstream->workspace);
+static void compress_fini(struct compress *c)
+{
+	kfree(c->zstream.workspace);
 	if (c->tmp)
-		free_page((unsigned long)c->tmp);
+		pool_free(&c->pool, c->tmp);
+	pool_fini(&c->pool);
 }
 
 static void err_compression_marker(struct drm_i915_error_state_buf *m)
@@ -335,9 +398,15 @@ static void err_compression_marker(struct drm_i915_error_state_buf *m)
 #else
 
 struct compress {
+	struct pagevec pool;
 };
 
 static bool compress_init(struct compress *c)
+{
+	return pool_init(&c->pool, ALLOW_FAIL) == 0;
+}
+
+static bool compress_start(struct compress *c)
 {
 	return true;
 }
@@ -346,14 +415,12 @@ static int compress_page(struct compress *c,
 			 void *src,
 			 struct drm_i915_error_object *dst)
 {
-	unsigned long page;
 	void *ptr;
 
-	page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
-	if (!page)
+	ptr = pool_alloc(&c->pool, ATOMIC_MAYFAIL);
+	if (!ptr)
 		return -ENOMEM;
 
-	ptr = (void *)page;
 	if (!i915_memcpy_from_wc(ptr, src, PAGE_SIZE))
 		memcpy(ptr, src, PAGE_SIZE);
 	dst->pages[dst->page_count++] = ptr;
@@ -367,9 +434,13 @@ static int compress_flush(struct compress *c,
 	return 0;
 }
 
-static void compress_fini(struct compress *c,
-			  struct drm_i915_error_object *dst)
+static void compress_finish(struct compress *c)
+{
+}
+
+static void compress_fini(struct compress *c)
 {
+	pool_fini(&c->pool);
 }
 
 static void err_compression_marker(struct drm_i915_error_state_buf *m)
@@ -379,36 +450,6 @@ static void err_compression_marker(struct drm_i915_error_state_buf *m)
 
 #endif
 
-static void print_error_buffers(struct drm_i915_error_state_buf *m,
-				const char *name,
-				struct drm_i915_error_buffer *err,
-				int count)
-{
-	err_printf(m, "%s [%d]:\n", name, count);
-
-	while (count--) {
-		err_printf(m, "    %08x_%08x %8u %02x %02x",
-			   upper_32_bits(err->gtt_offset),
-			   lower_32_bits(err->gtt_offset),
-			   err->size,
-			   err->read_domains,
-			   err->write_domain);
-		err_puts(m, tiling_flag(err->tiling));
-		err_puts(m, dirty_flag(err->dirty));
-		err_puts(m, purgeable_flag(err->purgeable));
-		err_puts(m, err->userptr ? " userptr" : "");
-		err_puts(m, i915_cache_level_str(m->i915, err->cache_level));
-
-		if (err->name)
-			err_printf(m, " (name: %d)", err->name);
-		if (err->fence_reg != I915_FENCE_REG_NONE)
-			err_printf(m, " (fence: %d)", err->fence_reg);
-
-		err_puts(m, "\n");
-		err++;
-	}
-}
-
 static void error_print_instdone(struct drm_i915_error_state_buf *m,
 				 const struct drm_i915_error_engine *ee)
 {
@@ -734,33 +775,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
 			error_print_engine(m, &error->engine[i], error->epoch);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(error->active_vm); i++) {
-		char buf[128];
-		int len, first = 1;
-
-		if (!error->active_vm[i])
-			break;
-
-		len = scnprintf(buf, sizeof(buf), "Active (");
-		for (j = 0; j < ARRAY_SIZE(error->engine); j++) {
-			if (error->engine[j].vm != error->active_vm[i])
-				continue;
-
-			len += scnprintf(buf + len, sizeof(buf), "%s%s",
-					 first ? "" : ", ",
-					 m->i915->engine[j]->name);
-			first = 0;
-		}
-		scnprintf(buf + len, sizeof(buf), ")");
-		print_error_buffers(m, buf,
-				    error->active_bo[i],
-				    error->active_bo_count[i]);
-	}
-
-	print_error_buffers(m, "Pinned (global)",
-			    error->pinned_bo,
-			    error->pinned_bo_count);
-
 	for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
 		const struct drm_i915_error_engine *ee = &error->engine[i];
 
@@ -974,10 +988,6 @@ void __i915_gpu_state_free(struct kref *error_ref)
 		kfree(ee->requests);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(error->active_bo); i++)
-		kfree(error->active_bo[i]);
-	kfree(error->pinned_bo);
-
 	kfree(error->overlay);
 	kfree(error->display);
 
@@ -990,12 +1000,12 @@ void __i915_gpu_state_free(struct kref *error_ref)
 
 static struct drm_i915_error_object *
 i915_error_object_create(struct drm_i915_private *i915,
-			 struct i915_vma *vma)
+			 struct i915_vma *vma,
+			 struct compress *compress)
 {
 	struct i915_ggtt *ggtt = &i915->ggtt;
 	const u64 slot = ggtt->error_capture.start;
 	struct drm_i915_error_object *dst;
-	struct compress compress;
 	unsigned long num_pages;
 	struct sgt_iter iter;
 	dma_addr_t dma;
@@ -1006,22 +1016,21 @@ i915_error_object_create(struct drm_i915_private *i915,
 
 	num_pages = min_t(u64, vma->size, vma->obj->base.size) >> PAGE_SHIFT;
 	num_pages = DIV_ROUND_UP(10 * num_pages, 8); /* worstcase zlib growth */
-	dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *),
-		      GFP_ATOMIC | __GFP_NOWARN);
+	dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), ATOMIC_MAYFAIL);
 	if (!dst)
 		return NULL;
 
+	if (!compress_start(compress)) {
+		kfree(dst);
+		return NULL;
+	}
+
 	dst->gtt_offset = vma->node.start;
 	dst->gtt_size = vma->node.size;
 	dst->num_pages = num_pages;
 	dst->page_count = 0;
 	dst->unused = 0;
 
-	if (!compress_init(&compress)) {
-		kfree(dst);
-		return NULL;
-	}
-
 	ret = -EINVAL;
 	for_each_sgt_dma(dma, iter, vma->pages) {
 		void __iomem *s;
@@ -1029,69 +1038,23 @@ i915_error_object_create(struct drm_i915_private *i915,
 		ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
 
 		s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
-		ret = compress_page(&compress, (void  __force *)s, dst);
+		ret = compress_page(compress, (void  __force *)s, dst);
 		io_mapping_unmap_atomic(s);
 		if (ret)
 			break;
 	}
 
-	if (ret || compress_flush(&compress, dst)) {
+	if (ret || compress_flush(compress, dst)) {
 		while (dst->page_count--)
-			free_page((unsigned long)dst->pages[dst->page_count]);
+			pool_free(&compress->pool, dst->pages[dst->page_count]);
 		kfree(dst);
 		dst = NULL;
 	}
+	compress_finish(compress);
 
-	compress_fini(&compress, dst);
 	return dst;
 }
 
-static void capture_bo(struct drm_i915_error_buffer *err,
-		       struct i915_vma *vma)
-{
-	struct drm_i915_gem_object *obj = vma->obj;
-
-	err->size = obj->base.size;
-	err->name = obj->base.name;
-
-	err->gtt_offset = vma->node.start;
-	err->read_domains = obj->read_domains;
-	err->write_domain = obj->write_domain;
-	err->fence_reg = vma->fence ? vma->fence->id : -1;
-	err->tiling = i915_gem_object_get_tiling(obj);
-	err->dirty = obj->mm.dirty;
-	err->purgeable = obj->mm.madv != I915_MADV_WILLNEED;
-	err->userptr = obj->userptr.mm != NULL;
-	err->cache_level = obj->cache_level;
-}
-
-static u32 capture_error_bo(struct drm_i915_error_buffer *err,
-			    int count, struct list_head *head,
-			    unsigned int flags)
-#define ACTIVE_ONLY BIT(0)
-#define PINNED_ONLY BIT(1)
-{
-	struct i915_vma *vma;
-	int i = 0;
-
-	list_for_each_entry(vma, head, vm_link) {
-		if (!vma->obj)
-			continue;
-
-		if (flags & ACTIVE_ONLY && !i915_vma_is_active(vma))
-			continue;
-
-		if (flags & PINNED_ONLY && !i915_vma_is_pinned(vma))
-			continue;
-
-		capture_bo(err++, vma);
-		if (++i == count)
-			break;
-	}
-
-	return i;
-}
-
 /*
  * Generate a semi-unique error code. The code is not meant to have meaning, The
  * code's only purpose is to try to prevent false duplicated bug reports by
@@ -1281,7 +1244,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
 	if (!count)
 		return;
 
-	ee->requests = kcalloc(count, sizeof(*ee->requests), GFP_ATOMIC);
+	ee->requests = kcalloc(count, sizeof(*ee->requests), ATOMIC_MAYFAIL);
 	if (!ee->requests)
 		return;
 
@@ -1349,8 +1312,10 @@ static void record_context(struct drm_i915_error_context *e,
 	e->active = atomic_read(&ctx->active_count);
 }
 
-static void request_record_user_bo(struct i915_request *request,
-				   struct drm_i915_error_engine *ee)
+static void
+request_record_user_bo(struct i915_request *request,
+		       struct drm_i915_error_engine *ee,
+		       struct compress *compress)
 {
 	struct i915_capture_list *c;
 	struct drm_i915_error_object **bo;
@@ -1362,18 +1327,20 @@ static void request_record_user_bo(struct i915_request *request,
 	if (!max)
 		return;
 
-	bo = kmalloc_array(max, sizeof(*bo), GFP_ATOMIC);
+	bo = kmalloc_array(max, sizeof(*bo), ATOMIC_MAYFAIL);
 	if (!bo) {
 		/* If we can't capture everything, try to capture something. */
 		max = min_t(long, max, PAGE_SIZE / sizeof(*bo));
-		bo = kmalloc_array(max, sizeof(*bo), GFP_ATOMIC);
+		bo = kmalloc_array(max, sizeof(*bo), ATOMIC_MAYFAIL);
 	}
 	if (!bo)
 		return;
 
 	count = 0;
 	for (c = request->capture_list; c; c = c->next) {
-		bo[count] = i915_error_object_create(request->i915, c->vma);
+		bo[count] = i915_error_object_create(request->i915,
+						     c->vma,
+						     compress);
 		if (!bo[count])
 			break;
 		if (++count == max)
@@ -1386,7 +1353,8 @@ static void request_record_user_bo(struct i915_request *request,
 
 static struct drm_i915_error_object *
 capture_object(struct drm_i915_private *dev_priv,
-	       struct drm_i915_gem_object *obj)
+	       struct drm_i915_gem_object *obj,
+	       struct compress *compress)
 {
 	if (obj && i915_gem_object_has_pages(obj)) {
 		struct i915_vma fake = {
@@ -1396,13 +1364,14 @@ capture_object(struct drm_i915_private *dev_priv,
 			.obj = obj,
 		};
 
-		return i915_error_object_create(dev_priv, &fake);
+		return i915_error_object_create(dev_priv, &fake, compress);
 	} else {
 		return NULL;
 	}
 }
 
-static void gem_record_rings(struct i915_gpu_state *error)
+static void
+gem_record_rings(struct i915_gpu_state *error, struct compress *compress)
 {
 	struct drm_i915_private *i915 = error->i915;
 	int i;
@@ -1420,6 +1389,9 @@ static void gem_record_rings(struct i915_gpu_state *error)
 
 		ee->engine_id = i;
 
+		/* Refill our page pool before entering atomic section */
+		pool_refill(&compress->pool, ALLOW_FAIL);
+
 		error_record_engine_registers(error, engine, ee);
 		error_record_engine_execlists(engine, ee);
 
@@ -1429,8 +1401,6 @@ static void gem_record_rings(struct i915_gpu_state *error)
 			struct i915_gem_context *ctx = request->gem_context;
 			struct intel_ring *ring = request->ring;
 
-			ee->vm = request->hw_context->vm;
-
 			record_context(&ee->context, ctx);
 
 			/* We need to copy these to an anonymous buffer
@@ -1438,17 +1408,21 @@ static void gem_record_rings(struct i915_gpu_state *error)
 			 * by userspace.
 			 */
 			ee->batchbuffer =
-				i915_error_object_create(i915, request->batch);
+				i915_error_object_create(i915,
+							 request->batch,
+							 compress);
 
 			if (HAS_BROKEN_CS_TLB(i915))
 				ee->wa_batchbuffer =
 				  i915_error_object_create(i915,
-							   engine->gt->scratch);
-			request_record_user_bo(request, ee);
+							   engine->gt->scratch,
+							   compress);
+			request_record_user_bo(request, ee, compress);
 
 			ee->ctx =
 				i915_error_object_create(i915,
-							 request->hw_context->state);
+							 request->hw_context->state,
+							 compress);
 
 			error->simulated |=
 				i915_gem_context_no_error_capture(ctx);
@@ -1460,7 +1434,9 @@ static void gem_record_rings(struct i915_gpu_state *error)
 			ee->cpu_ring_head = ring->head;
 			ee->cpu_ring_tail = ring->tail;
 			ee->ringbuffer =
-				i915_error_object_create(i915, ring->vma);
+				i915_error_object_create(i915,
+							 ring->vma,
+							 compress);
 
 			engine_record_requests(engine, request, ee);
 		}
@@ -1468,89 +1444,21 @@ static void gem_record_rings(struct i915_gpu_state *error)
 
 		ee->hws_page =
 			i915_error_object_create(i915,
-						 engine->status_page.vma);
-
-		ee->wa_ctx = i915_error_object_create(i915, engine->wa_ctx.vma);
-
-		ee->default_state = capture_object(i915, engine->default_state);
-	}
-}
-
-static void gem_capture_vm(struct i915_gpu_state *error,
-			   struct i915_address_space *vm,
-			   int idx)
-{
-	struct drm_i915_error_buffer *active_bo;
-	struct i915_vma *vma;
-	int count;
-
-	count = 0;
-	list_for_each_entry(vma, &vm->bound_list, vm_link)
-		if (i915_vma_is_active(vma))
-			count++;
-
-	active_bo = NULL;
-	if (count)
-		active_bo = kcalloc(count, sizeof(*active_bo), GFP_ATOMIC);
-	if (active_bo)
-		count = capture_error_bo(active_bo,
-					 count, &vm->bound_list,
-					 ACTIVE_ONLY);
-	else
-		count = 0;
+						 engine->status_page.vma,
+						 compress);
 
-	error->active_vm[idx] = vm;
-	error->active_bo[idx] = active_bo;
-	error->active_bo_count[idx] = count;
-}
-
-static void capture_active_buffers(struct i915_gpu_state *error)
-{
-	int cnt = 0, i, j;
-
-	BUILD_BUG_ON(ARRAY_SIZE(error->engine) > ARRAY_SIZE(error->active_bo));
-	BUILD_BUG_ON(ARRAY_SIZE(error->active_bo) != ARRAY_SIZE(error->active_vm));
-	BUILD_BUG_ON(ARRAY_SIZE(error->active_bo) != ARRAY_SIZE(error->active_bo_count));
-
-	/* Scan each engine looking for unique active contexts/vm */
-	for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
-		struct drm_i915_error_engine *ee = &error->engine[i];
-		bool found;
-
-		if (!ee->vm)
-			continue;
+		ee->wa_ctx =
+			i915_error_object_create(i915,
+						 engine->wa_ctx.vma,
+						 compress);
 
-		found = false;
-		for (j = 0; j < i && !found; j++)
-			found = error->engine[j].vm == ee->vm;
-		if (!found)
-			gem_capture_vm(error, ee->vm, cnt++);
+		ee->default_state =
+			capture_object(i915, engine->default_state, compress);
 	}
 }
 
-static void capture_pinned_buffers(struct i915_gpu_state *error)
-{
-	struct i915_address_space *vm = &error->i915->ggtt.vm;
-	struct drm_i915_error_buffer *bo;
-	struct i915_vma *vma;
-	int count;
-
-	count = 0;
-	list_for_each_entry(vma, &vm->bound_list, vm_link)
-		count++;
-
-	bo = NULL;
-	if (count)
-		bo = kcalloc(count, sizeof(*bo), GFP_ATOMIC);
-	if (!bo)
-		return;
-
-	error->pinned_bo_count =
-		capture_error_bo(bo, count, &vm->bound_list, PINNED_ONLY);
-	error->pinned_bo = bo;
-}
-
-static void capture_uc_state(struct i915_gpu_state *error)
+static void
+capture_uc_state(struct i915_gpu_state *error, struct compress *compress)
 {
 	struct drm_i915_private *i915 = error->i915;
 	struct i915_error_uc *error_uc = &error->uc;
@@ -1567,9 +1475,11 @@ static void capture_uc_state(struct i915_gpu_state *error)
 	 * As modparams are generally accesible from the userspace make
 	 * explicit copies of the firmware paths.
 	 */
-	error_uc->guc_fw.path = kstrdup(uc->guc.fw.path, GFP_ATOMIC);
-	error_uc->huc_fw.path = kstrdup(uc->huc.fw.path, GFP_ATOMIC);
-	error_uc->guc_log = i915_error_object_create(i915, uc->guc.log.vma);
+	error_uc->guc_fw.path = kstrdup(uc->guc.fw.path, ALLOW_FAIL);
+	error_uc->huc_fw.path = kstrdup(uc->huc.fw.path, ALLOW_FAIL);
+	error_uc->guc_log = i915_error_object_create(i915,
+						     uc->guc.log.vma,
+						     compress);
 }
 
 /* Capture all registers which don't fit into another category. */
@@ -1753,56 +1663,53 @@ static void capture_finish(struct i915_gpu_state *error)
 	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
 }
 
-static int capture(void *data)
-{
-	struct i915_gpu_state *error = data;
-
-	error->time = ktime_get_real();
-	error->boottime = ktime_get_boottime();
-	error->uptime = ktime_sub(ktime_get(),
-				  error->i915->gt.last_init_time);
-	error->capture = jiffies;
-
-	capture_params(error);
-	capture_gen_state(error);
-	capture_uc_state(error);
-	capture_reg_state(error);
-	gem_record_fences(error);
-	gem_record_rings(error);
-	capture_active_buffers(error);
-	capture_pinned_buffers(error);
-
-	error->overlay = intel_overlay_capture_error_state(error->i915);
-	error->display = intel_display_capture_error_state(error->i915);
-
-	error->epoch = capture_find_epoch(error);
-
-	capture_finish(error);
-	return 0;
-}
-
 #define DAY_AS_SECONDS(x) (24 * 60 * 60 * (x))
 
 struct i915_gpu_state *
 i915_capture_gpu_state(struct drm_i915_private *i915)
 {
 	struct i915_gpu_state *error;
+	struct compress compress;
 
 	/* Check if GPU capture has been disabled */
 	error = READ_ONCE(i915->gpu_error.first_error);
 	if (IS_ERR(error))
 		return error;
 
-	error = kzalloc(sizeof(*error), GFP_ATOMIC);
+	error = kzalloc(sizeof(*error), ALLOW_FAIL);
 	if (!error) {
 		i915_disable_error_state(i915, -ENOMEM);
 		return ERR_PTR(-ENOMEM);
 	}
 
+	if (!compress_init(&compress)) {
+		kfree(error);
+		i915_disable_error_state(i915, -ENOMEM);
+		return ERR_PTR(-ENOMEM);
+	}
+
 	kref_init(&error->ref);
 	error->i915 = i915;
 
-	stop_machine(capture, error, NULL);
+	error->time = ktime_get_real();
+	error->boottime = ktime_get_boottime();
+	error->uptime = ktime_sub(ktime_get(), i915->gt.last_init_time);
+	error->capture = jiffies;
+
+	capture_params(error);
+	capture_gen_state(error);
+	capture_uc_state(error, &compress);
+	capture_reg_state(error);
+	gem_record_fences(error);
+	gem_record_rings(error, &compress);
+
+	error->overlay = intel_overlay_capture_error_state(i915);
+	error->display = intel_display_capture_error_state(i915);
+
+	error->epoch = capture_find_epoch(error);
+
+	capture_finish(error);
+	compress_fini(&compress);
 
 	return error;
 }
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
index 85f06bc5da05..a24c35107d16 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -85,7 +85,6 @@ struct i915_gpu_state {
 		/* Software tracked state */
 		bool idle;
 		unsigned long hangcheck_timestamp;
-		struct i915_address_space *vm;
 		int num_requests;
 		u32 reset_count;
 
@@ -161,22 +160,6 @@ struct i915_gpu_state {
 		} vm_info;
 	} engine[I915_NUM_ENGINES];
 
-	struct drm_i915_error_buffer {
-		u32 size;
-		u32 name;
-		u64 gtt_offset;
-		u32 read_domains;
-		u32 write_domain;
-		s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
-		u32 tiling:2;
-		u32 dirty:1;
-		u32 purgeable:1;
-		u32 userptr:1;
-		u32 cache_level:3;
-	} *active_bo[I915_NUM_ENGINES], *pinned_bo;
-	u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
-	struct i915_address_space *active_vm[I915_NUM_ENGINES];
-
 	struct scatterlist *sgl, *fit;
 };
 
-- 
2.22.0

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

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

* [PATCH 13/20] drm/i915: Teach execbuffer to take the engine wakeref not GT
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (6 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 11/20] drm/i915: Rely on spinlock protection for GPU error capture Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-22 16:03   ` Tvrtko Ursulin
  2019-07-18  7:00 ` [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit Chris Wilson
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

In the next patch, we would like to couple into the engine wakeref to
free the batch pool on idling. The caveat here is that we therefore want
to track the engine wakeref more precisely and to hold it instead of the
broader GT wakeref as we process the ioctl.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 36 ++++++++++++-------
 drivers/gpu/drm/i915/gt/intel_context.h       |  7 ++++
 2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index cbd7c6e3a1f8..8768d436e54b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2138,13 +2138,35 @@ static int eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
 	if (err)
 		return err;
 
+	/*
+	 * Take a local wakeref for preparing to dispatch the execbuf as
+	 * we expect to access the hardware fairly frequently in the
+	 * process. Upon first dispatch, we acquire another prolonged
+	 * wakeref that we hold until the GPU has been idle for at least
+	 * 100ms.
+	 */
+	err = intel_context_timeline_lock(ce);
+	if (err)
+		goto err_unpin;
+
+	intel_context_enter(ce);
+	intel_context_timeline_unlock(ce);
+
 	eb->engine = ce->engine;
 	eb->context = ce;
 	return 0;
+
+err_unpin:
+	intel_context_unpin(ce);
+	return err;
 }
 
 static void eb_unpin_context(struct i915_execbuffer *eb)
 {
+	__intel_context_timeline_lock(eb->context);
+	intel_context_exit(eb->context);
+	intel_context_timeline_unlock(eb->context);
+
 	intel_context_unpin(eb->context);
 }
 
@@ -2425,18 +2447,9 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 	if (unlikely(err))
 		goto err_destroy;
 
-	/*
-	 * Take a local wakeref for preparing to dispatch the execbuf as
-	 * we expect to access the hardware fairly frequently in the
-	 * process. Upon first dispatch, we acquire another prolonged
-	 * wakeref that we hold until the GPU has been idle for at least
-	 * 100ms.
-	 */
-	intel_gt_pm_get(&eb.i915->gt);
-
 	err = i915_mutex_lock_interruptible(dev);
 	if (err)
-		goto err_rpm;
+		goto err_context;
 
 	err = eb_select_engine(&eb, file, args);
 	if (unlikely(err))
@@ -2601,8 +2614,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 	eb_unpin_context(&eb);
 err_unlock:
 	mutex_unlock(&dev->struct_mutex);
-err_rpm:
-	intel_gt_pm_put(&eb.i915->gt);
+err_context:
 	i915_gem_context_put(eb.gem_context);
 err_destroy:
 	eb_destroy(&eb);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 23c7e4c0ce7c..485886d84a56 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -127,6 +127,13 @@ static inline void intel_context_put(struct intel_context *ce)
 	kref_put(&ce->ref, ce->ops->destroy);
 }
 
+static inline void
+__intel_context_timeline_lock(struct intel_context *ce)
+	__acquires(&ce->ring->timeline->mutex)
+{
+	mutex_lock(&ce->ring->timeline->mutex);
+}
+
 static inline int __must_check
 intel_context_timeline_lock(struct intel_context *ce)
 	__acquires(&ce->ring->timeline->mutex)
-- 
2.22.0

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

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

* [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (7 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 13/20] drm/i915: Teach execbuffer to take the engine wakeref not GT Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-22 16:14   ` Tvrtko Ursulin
  2019-07-18  7:00 ` [PATCH 15/20] drm/i915/gt: Convert timeline tracking to spinlock Chris Wilson
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Lift moving the timeline to/from the active_list on enter/exit in order
to shorten the active tracking span in comparison to the existing
pin/unpin.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gem/i915_gem_pm.c        |  1 -
 drivers/gpu/drm/i915/gt/intel_context.c       |  2 +
 drivers/gpu/drm/i915/gt/intel_engine_pm.c     |  1 +
 drivers/gpu/drm/i915/gt/intel_lrc.c           |  4 +
 drivers/gpu/drm/i915/gt/intel_timeline.c      | 98 +++++++------------
 drivers/gpu/drm/i915/gt/intel_timeline.h      |  3 +-
 .../gpu/drm/i915/gt/intel_timeline_types.h    |  1 +
 drivers/gpu/drm/i915/gt/selftest_timeline.c   |  2 -
 8 files changed, 46 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
index 8faf262278ae..195ee6eedac0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
@@ -39,7 +39,6 @@ static void i915_gem_park(struct drm_i915_private *i915)
 		i915_gem_batch_pool_fini(&engine->batch_pool);
 	}
 
-	intel_timelines_park(i915);
 	i915_vma_parked(i915);
 
 	i915_globals_park();
diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 9830edda1ade..87c84cc0f658 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -242,10 +242,12 @@ int __init i915_global_context_init(void)
 void intel_context_enter_engine(struct intel_context *ce)
 {
 	intel_engine_pm_get(ce->engine);
+	intel_timeline_enter(ce->ring->timeline);
 }
 
 void intel_context_exit_engine(struct intel_context *ce)
 {
+	intel_timeline_exit(ce->ring->timeline);
 	intel_engine_pm_put(ce->engine);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index e74fbf04a68d..072f65e6a09e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -89,6 +89,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 
 	/* Check again on the next retirement. */
 	engine->wakeref_serial = engine->serial + 1;
+	intel_timeline_enter(rq->timeline);
 
 	i915_request_add_barriers(rq);
 	__i915_request_commit(rq);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 884dfc1cb033..aceb990ae3b9 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -3253,6 +3253,8 @@ static void virtual_context_enter(struct intel_context *ce)
 
 	for (n = 0; n < ve->num_siblings; n++)
 		intel_engine_pm_get(ve->siblings[n]);
+
+	intel_timeline_enter(ce->ring->timeline);
 }
 
 static void virtual_context_exit(struct intel_context *ce)
@@ -3260,6 +3262,8 @@ static void virtual_context_exit(struct intel_context *ce)
 	struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
 	unsigned int n;
 
+	intel_timeline_exit(ce->ring->timeline);
+
 	for (n = 0; n < ve->num_siblings; n++)
 		intel_engine_pm_put(ve->siblings[n]);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index 6daa9eb59e19..4af0b9801d91 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -278,64 +278,11 @@ void intel_timelines_init(struct drm_i915_private *i915)
 	timelines_init(&i915->gt);
 }
 
-static void timeline_add_to_active(struct intel_timeline *tl)
-{
-	struct intel_gt_timelines *gt = &tl->gt->timelines;
-
-	mutex_lock(&gt->mutex);
-	list_add(&tl->link, &gt->active_list);
-	mutex_unlock(&gt->mutex);
-}
-
-static void timeline_remove_from_active(struct intel_timeline *tl)
-{
-	struct intel_gt_timelines *gt = &tl->gt->timelines;
-
-	mutex_lock(&gt->mutex);
-	list_del(&tl->link);
-	mutex_unlock(&gt->mutex);
-}
-
-static void timelines_park(struct intel_gt *gt)
-{
-	struct intel_gt_timelines *timelines = &gt->timelines;
-	struct intel_timeline *timeline;
-
-	mutex_lock(&timelines->mutex);
-	list_for_each_entry(timeline, &timelines->active_list, 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);
-	}
-	mutex_unlock(&timelines->mutex);
-}
-
-/**
- * intel_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 intel_timelines_park(struct drm_i915_private *i915)
-{
-	timelines_park(&i915->gt);
-}
-
 void intel_timeline_fini(struct intel_timeline *timeline)
 {
 	GEM_BUG_ON(timeline->pin_count);
 	GEM_BUG_ON(!list_empty(&timeline->requests));
 
-	i915_syncmap_free(&timeline->sync);
-
 	if (timeline->hwsp_cacheline)
 		cacheline_free(timeline->hwsp_cacheline);
 	else
@@ -370,6 +317,7 @@ int intel_timeline_pin(struct intel_timeline *tl)
 	if (tl->pin_count++)
 		return 0;
 	GEM_BUG_ON(!tl->pin_count);
+	GEM_BUG_ON(tl->active_count);
 
 	err = i915_vma_pin(tl->hwsp_ggtt, 0, 0, PIN_GLOBAL | PIN_HIGH);
 	if (err)
@@ -380,7 +328,6 @@ int intel_timeline_pin(struct intel_timeline *tl)
 		offset_in_page(tl->hwsp_offset);
 
 	cacheline_acquire(tl->hwsp_cacheline);
-	timeline_add_to_active(tl);
 
 	return 0;
 
@@ -389,6 +336,40 @@ int intel_timeline_pin(struct intel_timeline *tl)
 	return err;
 }
 
+void intel_timeline_enter(struct intel_timeline *tl)
+{
+	struct intel_gt_timelines *timelines = &tl->gt->timelines;
+
+	GEM_BUG_ON(!tl->pin_count);
+	if (tl->active_count++)
+		return;
+	GEM_BUG_ON(!tl->active_count); /* overflow? */
+
+	mutex_lock(&timelines->mutex);
+	list_add(&tl->link, &timelines->active_list);
+	mutex_unlock(&timelines->mutex);
+}
+
+void intel_timeline_exit(struct intel_timeline *tl)
+{
+	struct intel_gt_timelines *timelines = &tl->gt->timelines;
+
+	GEM_BUG_ON(!tl->active_count);
+	if (--tl->active_count)
+		return;
+
+	mutex_lock(&timelines->mutex);
+	list_del(&tl->link);
+	mutex_unlock(&timelines->mutex);
+
+	/*
+	 * Since this timeline is idle, all bariers upon which we were waiting
+	 * must also be complete and so we can discard the last used barriers
+	 * without loss of information.
+	 */
+	i915_syncmap_free(&tl->sync);
+}
+
 static u32 timeline_advance(struct intel_timeline *tl)
 {
 	GEM_BUG_ON(!tl->pin_count);
@@ -546,16 +527,9 @@ void intel_timeline_unpin(struct intel_timeline *tl)
 	if (--tl->pin_count)
 		return;
 
-	timeline_remove_from_active(tl);
+	GEM_BUG_ON(tl->active_count);
 	cacheline_release(tl->hwsp_cacheline);
 
-	/*
-	 * Since this timeline is idle, all bariers upon which we were waiting
-	 * must also be complete and so we can discard the last used barriers
-	 * without loss of information.
-	 */
-	i915_syncmap_free(&tl->sync);
-
 	__i915_vma_unpin(tl->hwsp_ggtt);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h
index e08cebf64833..f583af1ba18d 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.h
@@ -77,9 +77,11 @@ static inline bool intel_timeline_sync_is_later(struct intel_timeline *tl,
 }
 
 int intel_timeline_pin(struct intel_timeline *tl);
+void intel_timeline_enter(struct intel_timeline *tl);
 int intel_timeline_get_seqno(struct intel_timeline *tl,
 			     struct i915_request *rq,
 			     u32 *seqno);
+void intel_timeline_exit(struct intel_timeline *tl);
 void intel_timeline_unpin(struct intel_timeline *tl);
 
 int intel_timeline_read_hwsp(struct i915_request *from,
@@ -87,7 +89,6 @@ int intel_timeline_read_hwsp(struct i915_request *from,
 			     u32 *hwsp_offset);
 
 void intel_timelines_init(struct drm_i915_private *i915);
-void intel_timelines_park(struct drm_i915_private *i915);
 void intel_timelines_fini(struct drm_i915_private *i915);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline_types.h b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
index 9a71aea7a338..b820ee76b7f5 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
@@ -58,6 +58,7 @@ struct intel_timeline {
 	 */
 	struct i915_syncmap *sync;
 
+	unsigned int active_count;
 	struct list_head link;
 	struct intel_gt *gt;
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c
index f0a840030382..d54113697745 100644
--- a/drivers/gpu/drm/i915/gt/selftest_timeline.c
+++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c
@@ -816,8 +816,6 @@ static int live_hwsp_recycle(void *arg)
 
 			if (err)
 				goto out;
-
-			intel_timelines_park(i915); /* Encourage recycling! */
 		} while (!__igt_timeout(end_time, NULL));
 	}
 
-- 
2.22.0

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

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

* [PATCH 15/20] drm/i915/gt: Convert timeline tracking to spinlock
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (8 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:00 ` [PATCH 17/20] drm/i915/gt: Add to timeline requires the timeline mutex Chris Wilson
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Convert the list manipulation of active to use spinlocks so that we can
perform the updates from underneath a quick interrupt callback.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_gt_types.h |  2 +-
 drivers/gpu/drm/i915/gt/intel_reset.c    | 10 ++++++++--
 drivers/gpu/drm/i915/gt/intel_timeline.c | 12 +++++-------
 drivers/gpu/drm/i915/i915_gem.c          | 20 ++++++++++----------
 4 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index 5fd11e361d03..b13f63e52203 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -40,7 +40,7 @@ struct intel_gt {
 	struct intel_uc uc;
 
 	struct intel_gt_timelines {
-		struct mutex mutex; /* protects list */
+		spinlock_t lock; /* protects active_list */
 		struct list_head active_list;
 
 		/* Pack multiple timelines' seqnos into the same page */
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 55e2ddcbd215..7d195a5f7da3 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -813,7 +813,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
 	 *
 	 * No more can be submitted until we reset the wedged bit.
 	 */
-	mutex_lock(&timelines->mutex);
+	spin_lock(&timelines->lock);
 	list_for_each_entry(tl, &timelines->active_list, link) {
 		struct i915_request *rq;
 
@@ -821,6 +821,8 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
 		if (!rq)
 			continue;
 
+		spin_unlock(&timelines->lock);
+
 		/*
 		 * All internal dependencies (i915_requests) will have
 		 * been flushed by the set-wedge, but we may be stuck waiting
@@ -830,8 +832,12 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
 		 */
 		dma_fence_default_wait(&rq->fence, false, MAX_SCHEDULE_TIMEOUT);
 		i915_request_put(rq);
+
+		/* Restart iteration after droping lock */
+		spin_lock(&timelines->lock);
+		tl = list_entry(&timelines->active_list, typeof(*tl), link);
 	}
-	mutex_unlock(&timelines->mutex);
+	spin_unlock(&timelines->lock);
 
 	intel_gt_sanitize(gt, false);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index 4af0b9801d91..355dfc52c804 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -266,7 +266,7 @@ static void timelines_init(struct intel_gt *gt)
 {
 	struct intel_gt_timelines *timelines = &gt->timelines;
 
-	mutex_init(&timelines->mutex);
+	spin_lock_init(&timelines->lock);
 	INIT_LIST_HEAD(&timelines->active_list);
 
 	spin_lock_init(&timelines->hwsp_lock);
@@ -345,9 +345,9 @@ void intel_timeline_enter(struct intel_timeline *tl)
 		return;
 	GEM_BUG_ON(!tl->active_count); /* overflow? */
 
-	mutex_lock(&timelines->mutex);
+	spin_lock(&timelines->lock);
 	list_add(&tl->link, &timelines->active_list);
-	mutex_unlock(&timelines->mutex);
+	spin_unlock(&timelines->lock);
 }
 
 void intel_timeline_exit(struct intel_timeline *tl)
@@ -358,9 +358,9 @@ void intel_timeline_exit(struct intel_timeline *tl)
 	if (--tl->active_count)
 		return;
 
-	mutex_lock(&timelines->mutex);
+	spin_lock(&timelines->lock);
 	list_del(&tl->link);
-	mutex_unlock(&timelines->mutex);
+	spin_unlock(&timelines->lock);
 
 	/*
 	 * Since this timeline is idle, all bariers upon which we were waiting
@@ -548,8 +548,6 @@ static void timelines_fini(struct intel_gt *gt)
 
 	GEM_BUG_ON(!list_empty(&timelines->active_list));
 	GEM_BUG_ON(!list_empty(&timelines->hwsp_free_list));
-
-	mutex_destroy(&timelines->mutex);
 }
 
 void intel_timelines_fini(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a207b90924e4..05dbf54281a8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -909,20 +909,20 @@ static int wait_for_engines(struct intel_gt *gt)
 
 static long
 wait_for_timelines(struct drm_i915_private *i915,
-		   unsigned int flags, long timeout)
+		   unsigned int wait, long timeout)
 {
-	struct intel_gt_timelines *gt = &i915->gt.timelines;
+	struct intel_gt_timelines *timelines = &i915->gt.timelines;
 	struct intel_timeline *tl;
 
-	mutex_lock(&gt->mutex);
-	list_for_each_entry(tl, &gt->active_list, link) {
+	spin_lock(&timelines->lock);
+	list_for_each_entry(tl, &timelines->active_list, link) {
 		struct i915_request *rq;
 
 		rq = i915_active_request_get_unlocked(&tl->last_request);
 		if (!rq)
 			continue;
 
-		mutex_unlock(&gt->mutex);
+		spin_unlock(&timelines->lock);
 
 		/*
 		 * "Race-to-idle".
@@ -933,19 +933,19 @@ wait_for_timelines(struct drm_i915_private *i915,
 		 * want to complete as quickly as possible to avoid prolonged
 		 * stalls, so allow the gpu to boost to maximum clocks.
 		 */
-		if (flags & I915_WAIT_FOR_IDLE_BOOST)
+		if (wait & I915_WAIT_FOR_IDLE_BOOST)
 			gen6_rps_boost(rq);
 
-		timeout = i915_request_wait(rq, flags, timeout);
+		timeout = i915_request_wait(rq, wait, timeout);
 		i915_request_put(rq);
 		if (timeout < 0)
 			return timeout;
 
 		/* restart after reacquiring the lock */
-		mutex_lock(&gt->mutex);
-		tl = list_entry(&gt->active_list, typeof(*tl), link);
+		spin_lock(&timelines->lock);
+		tl = list_entry(&timelines->active_list, typeof(*tl), link);
 	}
-	mutex_unlock(&gt->mutex);
+	spin_unlock(&timelines->lock);
 
 	return timeout;
 }
-- 
2.22.0

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

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

* [PATCH 17/20] drm/i915/gt: Add to timeline requires the timeline mutex
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (9 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 15/20] drm/i915/gt: Convert timeline tracking to spinlock Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:00 ` [PATCH 18/20] drm/i915: Protect request retirement with timeline->mutex Chris Wilson
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Modifying a remote context requires careful serialisation with requests
on that context, and that serialisation requires us to take their
timeline->mutex. Make it so.

Note that while struct_mutex rules, we can't create more than one
request in parallel, but that age is soon coming to an end.

v2: Though it doesn't affect the current users, contexts may share
timelines so check if we already hold the right mutex.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_context.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
index 87c84cc0f658..fe995a797452 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -260,10 +260,18 @@ int intel_context_prepare_remote_request(struct intel_context *ce,
 	/* Only suitable for use in remotely modifying this context */
 	GEM_BUG_ON(rq->hw_context == ce);
 
+	if (rq->timeline != tl) { /* beware timeline sharing */
+		err = mutex_lock_interruptible_nested(&tl->mutex,
+						      SINGLE_DEPTH_NESTING);
+		if (err)
+			return err;
+	}
+	lockdep_assert_held(&tl->mutex);
+
 	/* Queue this switch after all other activity by this context. */
 	err = i915_active_request_set(&tl->last_request, rq);
 	if (err)
-		return err;
+		goto unlock;
 
 	/*
 	 * Guarantee context image and the timeline remains pinned until the
@@ -273,7 +281,12 @@ int intel_context_prepare_remote_request(struct intel_context *ce,
 	 * words transfer the pinned ce object to tracked active request.
 	 */
 	GEM_BUG_ON(i915_active_is_idle(&ce->active));
-	return i915_active_ref(&ce->active, rq->fence.context, rq);
+	err = i915_active_ref(&ce->active, rq->fence.context, rq);
+
+unlock:
+	if (rq->timeline != tl)
+		mutex_unlock(&tl->mutex);
+	return err;
 }
 
 struct i915_request *intel_context_create_request(struct intel_context *ce)
-- 
2.22.0

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

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

* [PATCH 18/20] drm/i915: Protect request retirement with timeline->mutex
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (10 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 17/20] drm/i915/gt: Add to timeline requires the timeline mutex Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:00 ` [PATCH 20/20] drm/i915/gt: Mark context->active_count as protected by timeline->mutex Chris Wilson
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

Forgo the struct_mutex requirement for request retirement as we have
been transitioning over to only using the timeline->mutex for
controlling the lifetime of a request on that timeline.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 192 ++++++++++--------
 drivers/gpu/drm/i915/gt/intel_context.h       |  25 +--
 drivers/gpu/drm/i915/gt/intel_engine_cs.c     |   1 -
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |   2 -
 drivers/gpu/drm/i915/gt/intel_gt.c            |   1 -
 drivers/gpu/drm/i915/gt/intel_gt_types.h      |   2 -
 drivers/gpu/drm/i915/gt/intel_lrc.c           |   1 +
 drivers/gpu/drm/i915/gt/intel_ringbuffer.c    |  13 +-
 drivers/gpu/drm/i915/gt/mock_engine.c         |   1 -
 drivers/gpu/drm/i915/i915_request.c           | 151 +++++++-------
 drivers/gpu/drm/i915/i915_request.h           |   3 -
 11 files changed, 203 insertions(+), 189 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 8768d436e54b..2219184a96dc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -734,63 +734,6 @@ static int eb_select_context(struct i915_execbuffer *eb)
 	return 0;
 }
 
-static struct i915_request *__eb_wait_for_ring(struct intel_ring *ring)
-{
-	struct i915_request *rq;
-
-	/*
-	 * Completely unscientific finger-in-the-air estimates for suitable
-	 * maximum user request size (to avoid blocking) and then backoff.
-	 */
-	if (intel_ring_update_space(ring) >= PAGE_SIZE)
-		return NULL;
-
-	/*
-	 * Find a request that after waiting upon, there will be at least half
-	 * the ring available. The hysteresis allows us to compete for the
-	 * shared ring and should mean that we sleep less often prior to
-	 * claiming our resources, but not so long that the ring completely
-	 * drains before we can submit our next request.
-	 */
-	list_for_each_entry(rq, &ring->request_list, ring_link) {
-		if (__intel_ring_space(rq->postfix,
-				       ring->emit, ring->size) > ring->size / 2)
-			break;
-	}
-	if (&rq->ring_link == &ring->request_list)
-		return NULL; /* weird, we will check again later for real */
-
-	return i915_request_get(rq);
-}
-
-static int eb_wait_for_ring(const struct i915_execbuffer *eb)
-{
-	struct i915_request *rq;
-	int ret = 0;
-
-	/*
-	 * Apply a light amount of backpressure to prevent excessive hogs
-	 * from blocking waiting for space whilst holding struct_mutex and
-	 * keeping all of their resources pinned.
-	 */
-
-	rq = __eb_wait_for_ring(eb->context->ring);
-	if (rq) {
-		mutex_unlock(&eb->i915->drm.struct_mutex);
-
-		if (i915_request_wait(rq,
-				      I915_WAIT_INTERRUPTIBLE,
-				      MAX_SCHEDULE_TIMEOUT) < 0)
-			ret = -EINTR;
-
-		i915_request_put(rq);
-
-		mutex_lock(&eb->i915->drm.struct_mutex);
-	}
-
-	return ret;
-}
-
 static int eb_lookup_vmas(struct i915_execbuffer *eb)
 {
 	struct radix_tree_root *handles_vma = &eb->gem_context->handles_vma;
@@ -2117,10 +2060,75 @@ static const enum intel_engine_id user_ring_map[] = {
 	[I915_EXEC_VEBOX]	= VECS0
 };
 
-static int eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
+static struct i915_request *eb_throttle(struct intel_context *ce)
+{
+	struct intel_ring *ring = ce->ring;
+	struct intel_timeline *tl = ring->timeline;
+	struct i915_request *rq;
+
+	/*
+	 * Completely unscientific finger-in-the-air estimates for suitable
+	 * maximum user request size (to avoid blocking) and then backoff.
+	 */
+	if (intel_ring_update_space(ring) >= PAGE_SIZE)
+		return NULL;
+
+	/*
+	 * Find a request that after waiting upon, there will be at least half
+	 * the ring available. The hysteresis allows us to compete for the
+	 * shared ring and should mean that we sleep less often prior to
+	 * claiming our resources, but not so long that the ring completely
+	 * drains before we can submit our next request.
+	 */
+	list_for_each_entry(rq, &tl->requests, link) {
+		if (rq->ring != ring)
+			continue;
+
+		if (__intel_ring_space(rq->postfix,
+				       ring->emit, ring->size) > ring->size / 2)
+			break;
+	}
+	if (&rq->link == &tl->requests)
+		return NULL; /* weird, we will check again later for real */
+
+	return i915_request_get(rq);
+}
+
+static int
+__eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
 {
 	int err;
 
+	if (likely(atomic_inc_not_zero(&ce->pin_count)))
+		return 0;
+
+	err = mutex_lock_interruptible(&eb->i915->drm.struct_mutex);
+	if (err)
+		return err;
+
+	err = __intel_context_do_pin(ce);
+	mutex_unlock(&eb->i915->drm.struct_mutex);
+
+	return err;
+}
+
+static void
+__eb_unpin_context(struct i915_execbuffer *eb, struct intel_context *ce)
+{
+	if (likely(atomic_add_unless(&ce->pin_count, -1, 1)))
+		return;
+
+	mutex_lock(&eb->i915->drm.struct_mutex);
+	intel_context_unpin(ce);
+	mutex_unlock(&eb->i915->drm.struct_mutex);
+}
+
+static int __eb_pin_engine(struct i915_execbuffer *eb, struct intel_context *ce)
+{
+	struct intel_timeline *tl;
+	struct i915_request *rq;
+	int err;
+
 	/*
 	 * ABI: Before userspace accesses the GPU (e.g. execbuffer), report
 	 * EIO if the GPU is already wedged.
@@ -2134,7 +2142,7 @@ static int eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
 	 * GGTT space, so do this first before we reserve a seqno for
 	 * ourselves.
 	 */
-	err = intel_context_pin(ce);
+	err = __eb_pin_context(eb, ce);
 	if (err)
 		return err;
 
@@ -2145,29 +2153,52 @@ static int eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
 	 * wakeref that we hold until the GPU has been idle for at least
 	 * 100ms.
 	 */
-	err = intel_context_timeline_lock(ce);
-	if (err)
+	tl = intel_context_timeline_lock(ce);
+	if (IS_ERR(tl)) {
+		err = PTR_ERR(tl);
 		goto err_unpin;
+	}
 
 	intel_context_enter(ce);
-	intel_context_timeline_unlock(ce);
+	rq = eb_throttle(ce);
+
+	intel_context_timeline_unlock(tl);
+
+	if (rq) {
+		if (i915_request_wait(rq,
+				      I915_WAIT_INTERRUPTIBLE,
+				      MAX_SCHEDULE_TIMEOUT) < 0) {
+			i915_request_put(rq);
+			err = -EINTR;
+			goto err_exit;
+		}
+
+		i915_request_put(rq);
+	}
 
 	eb->engine = ce->engine;
 	eb->context = ce;
 	return 0;
 
+err_exit:
+	mutex_lock(&tl->mutex);
+	intel_context_exit(ce);
+	intel_context_timeline_unlock(tl);
 err_unpin:
-	intel_context_unpin(ce);
+	__eb_unpin_context(eb, ce);
 	return err;
 }
 
-static void eb_unpin_context(struct i915_execbuffer *eb)
+static void eb_unpin_engine(struct i915_execbuffer *eb)
 {
-	__intel_context_timeline_lock(eb->context);
-	intel_context_exit(eb->context);
-	intel_context_timeline_unlock(eb->context);
+	struct intel_context *ce = eb->context;
+	struct intel_timeline *tl = ce->ring->timeline;
+
+	mutex_lock(&tl->mutex);
+	intel_context_exit(ce);
+	intel_context_timeline_unlock(tl);
 
-	intel_context_unpin(eb->context);
+	__eb_unpin_context(eb, ce);
 }
 
 static unsigned int
@@ -2212,9 +2243,9 @@ eb_select_legacy_ring(struct i915_execbuffer *eb,
 }
 
 static int
-eb_select_engine(struct i915_execbuffer *eb,
-		 struct drm_file *file,
-		 struct drm_i915_gem_execbuffer2 *args)
+eb_pin_engine(struct i915_execbuffer *eb,
+	      struct drm_file *file,
+	      struct drm_i915_gem_execbuffer2 *args)
 {
 	struct intel_context *ce;
 	unsigned int idx;
@@ -2229,7 +2260,7 @@ eb_select_engine(struct i915_execbuffer *eb,
 	if (IS_ERR(ce))
 		return PTR_ERR(ce);
 
-	err = eb_pin_context(eb, ce);
+	err = __eb_pin_engine(eb, ce);
 	intel_context_put(ce);
 
 	return err;
@@ -2447,16 +2478,12 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 	if (unlikely(err))
 		goto err_destroy;
 
-	err = i915_mutex_lock_interruptible(dev);
-	if (err)
-		goto err_context;
-
-	err = eb_select_engine(&eb, file, args);
+	err = eb_pin_engine(&eb, file, args);
 	if (unlikely(err))
-		goto err_unlock;
+		goto err_context;
 
-	err = eb_wait_for_ring(&eb); /* may temporarily drop struct_mutex */
-	if (unlikely(err))
+	err = i915_mutex_lock_interruptible(dev);
+	if (err)
 		goto err_engine;
 
 	err = eb_relocate(&eb);
@@ -2610,10 +2637,9 @@ i915_gem_do_execbuffer(struct drm_device *dev,
 err_vma:
 	if (eb.exec)
 		eb_release_vmas(&eb);
-err_engine:
-	eb_unpin_context(&eb);
-err_unlock:
 	mutex_unlock(&dev->struct_mutex);
+err_engine:
+	eb_unpin_engine(&eb);
 err_context:
 	i915_gem_context_put(eb.gem_context);
 err_destroy:
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 485886d84a56..fc7859f506c2 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include "i915_active.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
+#include "intel_timeline_types.h"
 
 void intel_context_init(struct intel_context *ce,
 			struct i915_gem_context *ctx,
@@ -127,24 +128,24 @@ static inline void intel_context_put(struct intel_context *ce)
 	kref_put(&ce->ref, ce->ops->destroy);
 }
 
-static inline void
-__intel_context_timeline_lock(struct intel_context *ce)
-	__acquires(&ce->ring->timeline->mutex)
-{
-	mutex_lock(&ce->ring->timeline->mutex);
-}
-
-static inline int __must_check
+static inline struct intel_timeline *__must_check
 intel_context_timeline_lock(struct intel_context *ce)
 	__acquires(&ce->ring->timeline->mutex)
 {
-	return mutex_lock_interruptible(&ce->ring->timeline->mutex);
+	struct intel_timeline *tl = ce->ring->timeline;
+	int err;
+
+	err = mutex_lock_interruptible(&tl->mutex);
+	if (err)
+		return ERR_PTR(err);
+
+	return tl;
 }
 
-static inline void intel_context_timeline_unlock(struct intel_context *ce)
-	__releases(&ce->ring->timeline->mutex)
+static inline void intel_context_timeline_unlock(struct intel_timeline *tl)
+	__releases(&tl->mutex)
 {
-	mutex_unlock(&ce->ring->timeline->mutex);
+	mutex_unlock(&tl->mutex);
 }
 
 int intel_context_prepare_remote_request(struct intel_context *ce,
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 2cfe10c82bd9..83a1f7047384 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -745,7 +745,6 @@ static int measure_breadcrumb_dw(struct intel_engine_cs *engine)
 				engine->status_page.vma))
 		goto out_frame;
 
-	INIT_LIST_HEAD(&frame->ring.request_list);
 	frame->ring.timeline = &frame->timeline;
 	frame->ring.vaddr = frame->cs;
 	frame->ring.size = sizeof(frame->cs);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 9c927fa408aa..3c84973275ae 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -70,8 +70,6 @@ struct intel_ring {
 	void *vaddr;
 
 	struct intel_timeline *timeline;
-	struct list_head request_list;
-	struct list_head active_link;
 
 	/*
 	 * As we have two types of rings, one global to the engine used
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index f7e69db4019d..90ed79285ff8 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -14,7 +14,6 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
 	gt->i915 = i915;
 	gt->uncore = &i915->uncore;
 
-	INIT_LIST_HEAD(&gt->active_rings);
 	INIT_LIST_HEAD(&gt->closed_vma);
 
 	spin_lock_init(&gt->closed_lock);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index b13f63e52203..bfdabf49b1e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -48,8 +48,6 @@ struct intel_gt {
 		struct list_head hwsp_free_list;
 	} timelines;
 
-	struct list_head active_rings;
-
 	struct intel_wakeref wakeref;
 
 	struct list_head closed_vma;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index aceb990ae3b9..64858a1ebbc8 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1574,6 +1574,7 @@ static void execlists_context_unpin(struct intel_context *ce)
 {
 	i915_gem_context_unpin_hw_id(ce->gem_context);
 	i915_gem_object_unpin_map(ce->state->obj);
+	intel_ring_reset(ce->ring, ce->ring->tail);
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
index d8efb88f33f3..9d9be5fed9fc 100644
--- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
@@ -1275,7 +1275,7 @@ void intel_ring_unpin(struct intel_ring *ring)
 	GEM_TRACE("ring:%llx unpin\n", ring->timeline->fence_context);
 
 	/* Discard any unused bytes beyond that submitted to hw. */
-	intel_ring_reset(ring, ring->tail);
+	intel_ring_reset(ring, ring->emit);
 
 	i915_vma_unset_ggtt_write(vma);
 	if (i915_vma_is_map_and_fenceable(vma))
@@ -1340,7 +1340,6 @@ intel_engine_create_ring(struct intel_engine_cs *engine,
 		return ERR_PTR(-ENOMEM);
 
 	kref_init(&ring->ref);
-	INIT_LIST_HEAD(&ring->request_list);
 	ring->timeline = intel_timeline_get(timeline);
 
 	ring->size = size;
@@ -1888,21 +1887,25 @@ static int ring_request_alloc(struct i915_request *request)
 
 static noinline int wait_for_space(struct intel_ring *ring, unsigned int bytes)
 {
+	struct intel_timeline *tl = ring->timeline;
 	struct i915_request *target;
 	long timeout;
 
 	if (intel_ring_update_space(ring) >= bytes)
 		return 0;
 
-	GEM_BUG_ON(list_empty(&ring->request_list));
-	list_for_each_entry(target, &ring->request_list, ring_link) {
+	GEM_BUG_ON(list_empty(&tl->requests));
+	list_for_each_entry(target, &tl->requests, link) {
+		if (target->ring != ring)
+			continue;
+
 		/* Would completion of this request free enough space? */
 		if (bytes <= __intel_ring_space(target->postfix,
 						ring->emit, ring->size))
 			break;
 	}
 
-	if (WARN_ON(&target->ring_link == &ring->request_list))
+	if (GEM_WARN_ON(&target->link == &tl->requests))
 		return -ENOSPC;
 
 	timeout = i915_request_wait(target,
diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
index 042b456cde49..42776672c59b 100644
--- a/drivers/gpu/drm/i915/gt/mock_engine.c
+++ b/drivers/gpu/drm/i915/gt/mock_engine.c
@@ -68,7 +68,6 @@ static struct intel_ring *mock_ring(struct intel_engine_cs *engine)
 	ring->base.timeline = &ring->timeline;
 	atomic_set(&ring->base.pin_count, 1);
 
-	INIT_LIST_HEAD(&ring->base.request_list);
 	intel_ring_update_space(&ring->base);
 
 	return &ring->base;
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 8ac7d14ec8c9..92313a59563c 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -180,40 +180,6 @@ i915_request_remove_from_client(struct i915_request *request)
 	spin_unlock(&file_priv->mm.lock);
 }
 
-static void advance_ring(struct i915_request *request)
-{
-	struct intel_ring *ring = request->ring;
-	unsigned int tail;
-
-	/*
-	 * We know the GPU must have read the request to have
-	 * sent us the seqno + interrupt, so use the position
-	 * of tail of the request to update the last known position
-	 * of the GPU head.
-	 *
-	 * Note this requires that we are always called in request
-	 * completion order.
-	 */
-	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
-		 * forwards (to request->wa_tail). We either read the
-		 * current value that was written to hw, or the value that
-		 * is just about to be. Either works, if we miss the last two
-		 * noops - they are safe to be replayed on a reset.
-		 */
-		tail = READ_ONCE(request->tail);
-		list_del(&ring->active_link);
-	} else {
-		tail = request->postfix;
-	}
-	list_del_init(&request->ring_link);
-
-	ring->head = tail;
-}
-
 static void free_capture_list(struct i915_request *request)
 {
 	struct i915_capture_list *capture;
@@ -231,7 +197,7 @@ static bool i915_request_retire(struct i915_request *rq)
 {
 	struct i915_active_request *active, *next;
 
-	lockdep_assert_held(&rq->i915->drm.struct_mutex);
+	lockdep_assert_held(&rq->timeline->mutex);
 	if (!i915_request_completed(rq))
 		return false;
 
@@ -243,7 +209,17 @@ static bool i915_request_retire(struct i915_request *rq)
 	GEM_BUG_ON(!i915_sw_fence_signaled(&rq->submit));
 	trace_i915_request_retire(rq);
 
-	advance_ring(rq);
+	/*
+	 * We know the GPU must have read the request to have
+	 * sent us the seqno + interrupt, so use the position
+	 * of tail of the request to update the last known position
+	 * of the GPU head.
+	 *
+	 * Note this requires that we are always called in request
+	 * completion order.
+	 */
+	GEM_BUG_ON(!list_is_first(&rq->link, &rq->timeline->requests));
+	rq->ring->head = rq->postfix;
 
 	/*
 	 * Walk through the active list, calling retire on each. This allows
@@ -320,7 +296,7 @@ static bool i915_request_retire(struct i915_request *rq)
 
 void i915_request_retire_upto(struct i915_request *rq)
 {
-	struct intel_ring *ring = rq->ring;
+	struct intel_timeline * const tl = rq->timeline;
 	struct i915_request *tmp;
 
 	GEM_TRACE("%s fence %llx:%lld, current %d\n",
@@ -328,15 +304,11 @@ void i915_request_retire_upto(struct i915_request *rq)
 		  rq->fence.context, rq->fence.seqno,
 		  hwsp_seqno(rq));
 
-	lockdep_assert_held(&rq->i915->drm.struct_mutex);
+	lockdep_assert_held(&tl->mutex);
 	GEM_BUG_ON(!i915_request_completed(rq));
 
-	if (list_empty(&rq->ring_link))
-		return;
-
 	do {
-		tmp = list_first_entry(&ring->request_list,
-				       typeof(*tmp), ring_link);
+		tmp = list_first_entry(&tl->requests, typeof(*tmp), link);
 	} while (i915_request_retire(tmp) && tmp != rq);
 }
 
@@ -563,29 +535,28 @@ semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
 	return NOTIFY_DONE;
 }
 
-static void ring_retire_requests(struct intel_ring *ring)
+static void retire_requests(struct intel_timeline *tl)
 {
 	struct i915_request *rq, *rn;
 
-	list_for_each_entry_safe(rq, rn, &ring->request_list, ring_link)
+	list_for_each_entry_safe(rq, rn, &tl->requests, link)
 		if (!i915_request_retire(rq))
 			break;
 }
 
 static noinline struct i915_request *
-request_alloc_slow(struct intel_context *ce, gfp_t gfp)
+request_alloc_slow(struct intel_timeline *tl, gfp_t gfp)
 {
-	struct intel_ring *ring = ce->ring;
 	struct i915_request *rq;
 
-	if (list_empty(&ring->request_list))
+	if (list_empty(&tl->requests))
 		goto out;
 
 	if (!gfpflags_allow_blocking(gfp))
 		goto out;
 
 	/* Move our oldest request to the slab-cache (if not in use!) */
-	rq = list_first_entry(&ring->request_list, typeof(*rq), ring_link);
+	rq = list_first_entry(&tl->requests, typeof(*rq), link);
 	i915_request_retire(rq);
 
 	rq = kmem_cache_alloc(global.slab_requests,
@@ -594,11 +565,11 @@ request_alloc_slow(struct intel_context *ce, gfp_t gfp)
 		return rq;
 
 	/* Ratelimit ourselves to prevent oom from malicious clients */
-	rq = list_last_entry(&ring->request_list, typeof(*rq), ring_link);
+	rq = list_last_entry(&tl->requests, typeof(*rq), link);
 	cond_synchronize_rcu(rq->rcustate);
 
 	/* Retire our old requests in the hope that we free some */
-	ring_retire_requests(ring);
+	retire_requests(tl);
 
 out:
 	return kmem_cache_alloc(global.slab_requests, gfp);
@@ -649,7 +620,7 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp)
 	rq = kmem_cache_alloc(global.slab_requests,
 			      gfp | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
 	if (unlikely(!rq)) {
-		rq = request_alloc_slow(ce, gfp);
+		rq = request_alloc_slow(tl, gfp);
 		if (!rq) {
 			ret = -ENOMEM;
 			goto err_unreserve;
@@ -741,15 +712,15 @@ struct i915_request *
 i915_request_create(struct intel_context *ce)
 {
 	struct i915_request *rq;
-	int err;
+	struct intel_timeline *tl;
 
-	err = intel_context_timeline_lock(ce);
-	if (err)
-		return ERR_PTR(err);
+	tl = intel_context_timeline_lock(ce);
+	if (IS_ERR(tl))
+		return ERR_CAST(tl);
 
 	/* Move our oldest request to the slab-cache (if not in use!) */
-	rq = list_first_entry(&ce->ring->request_list, typeof(*rq), ring_link);
-	if (!list_is_last(&rq->ring_link, &ce->ring->request_list))
+	rq = list_first_entry(&tl->requests, typeof(*rq), link);
+	if (!list_is_last(&rq->link, &tl->requests))
 		i915_request_retire(rq);
 
 	intel_context_enter(ce);
@@ -759,22 +730,22 @@ i915_request_create(struct intel_context *ce)
 		goto err_unlock;
 
 	/* Check that we do not interrupt ourselves with a new request */
-	rq->cookie = lockdep_pin_lock(&ce->ring->timeline->mutex);
+	rq->cookie = lockdep_pin_lock(&tl->mutex);
 
 	return rq;
 
 err_unlock:
-	intel_context_timeline_unlock(ce);
+	intel_context_timeline_unlock(tl);
 	return rq;
 }
 
 static int
 i915_request_await_start(struct i915_request *rq, struct i915_request *signal)
 {
-	if (list_is_first(&signal->ring_link, &signal->ring->request_list))
+	if (list_is_first(&signal->link, &signal->ring->timeline->requests))
 		return 0;
 
-	signal = list_prev_entry(signal, ring_link);
+	signal = list_prev_entry(signal, link);
 	if (intel_timeline_sync_is_later(rq->timeline, &signal->fence))
 		return 0;
 
@@ -1167,6 +1138,7 @@ struct i915_request *__i915_request_commit(struct i915_request *rq)
 	 */
 	GEM_BUG_ON(rq->reserved_space > ring->space);
 	rq->reserved_space = 0;
+	rq->emitted_jiffies = jiffies;
 
 	/*
 	 * Record the position of the start of the breadcrumb so that
@@ -1180,11 +1152,6 @@ struct i915_request *__i915_request_commit(struct i915_request *rq)
 
 	prev = __i915_request_add_to_timeline(rq);
 
-	list_add_tail(&rq->ring_link, &ring->request_list);
-	if (list_is_first(&rq->ring_link, &ring->request_list))
-		list_add(&ring->active_link, &rq->i915->gt.active_rings);
-	rq->emitted_jiffies = jiffies;
-
 	/*
 	 * Let the backend know a new request has arrived that may need
 	 * to adjust the existing execution schedule due to a high priority
@@ -1237,10 +1204,11 @@ struct i915_request *__i915_request_commit(struct i915_request *rq)
 
 void i915_request_add(struct i915_request *rq)
 {
+	struct intel_timeline * const tl = rq->timeline;
 	struct i915_request *prev;
 
-	lockdep_assert_held(&rq->timeline->mutex);
-	lockdep_unpin_lock(&rq->timeline->mutex, rq->cookie);
+	lockdep_assert_held(&tl->mutex);
+	lockdep_unpin_lock(&tl->mutex, rq->cookie);
 
 	trace_i915_request_add(rq);
 
@@ -1263,10 +1231,10 @@ void i915_request_add(struct i915_request *rq)
 	 * work on behalf of others -- but instead we should benefit from
 	 * improved resource management. (Well, that's the theory at least.)
 	 */
-	if (prev && i915_request_completed(prev))
+	if (prev && i915_request_completed(prev) && prev->timeline == tl)
 		i915_request_retire_upto(prev);
 
-	mutex_unlock(&rq->timeline->mutex);
+	mutex_unlock(&tl->mutex);
 }
 
 static unsigned long local_clock_us(unsigned int *cpu)
@@ -1486,18 +1454,43 @@ long i915_request_wait(struct i915_request *rq,
 
 bool i915_retire_requests(struct drm_i915_private *i915)
 {
-	struct intel_ring *ring, *tmp;
+	struct intel_gt_timelines *timelines = &i915->gt.timelines;
+	struct intel_timeline *tl, *tn;
+	LIST_HEAD(free);
+
+	spin_lock(&timelines->lock);
+	list_for_each_entry_safe(tl, tn, &timelines->active_list, link) {
+		if (!mutex_trylock(&tl->mutex))
+			continue;
+
+		intel_timeline_get(tl);
+		GEM_BUG_ON(!tl->active_count);
+		tl->active_count++; /* pin the list element */
+		spin_unlock(&timelines->lock);
 
-	lockdep_assert_held(&i915->drm.struct_mutex);
+		retire_requests(tl);
 
-	list_for_each_entry_safe(ring, tmp,
-				 &i915->gt.active_rings, active_link) {
-		intel_ring_get(ring); /* last rq holds reference! */
-		ring_retire_requests(ring);
-		intel_ring_put(ring);
+		spin_lock(&timelines->lock);
+
+		/* Restart iteration after dropping lock */
+		list_safe_reset_next(tl, tn, link);
+		if (!--tl->active_count)
+			list_del(&tl->link);
+
+		mutex_unlock(&tl->mutex);
+
+		/* Defer the final release to after the spinlock */
+		if (refcount_dec_and_test(&tl->kref.refcount)) {
+			GEM_BUG_ON(tl->active_count);
+			list_add(&tl->link, &free);
+		}
 	}
+	spin_unlock(&timelines->lock);
+
+	list_for_each_entry_safe(tl, tn, &free, link)
+		__intel_timeline_free(&tl->kref);
 
-	return !list_empty(&i915->gt.active_rings);
+	return !list_empty(&timelines->active_list);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index 313df3c37158..22e506e960e0 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -223,9 +223,6 @@ struct i915_request {
 	/** timeline->request entry for this request */
 	struct list_head link;
 
-	/** ring->request_list entry for this request */
-	struct list_head ring_link;
-
 	struct drm_i915_file_private *file_priv;
 	/** file_priv list entry for this request */
 	struct list_head client_link;
-- 
2.22.0

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

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

* [PATCH 20/20] drm/i915/gt: Mark context->active_count as protected by timeline->mutex
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (11 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 18/20] drm/i915: Protect request retirement with timeline->mutex Chris Wilson
@ 2019-07-18  7:00 ` Chris Wilson
  2019-07-18  7:16 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt Patchwork
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-18  7:00 UTC (permalink / raw)
  To: intel-gfx

We use timeline->mutex to protect modifications to
context->active_count, and the associated enable/disable callbacks.
Due to complications with engine-pm barrier there is a path where we used
a "superlock" to provide serialised protect and so could not
unconditionally assert with lockdep that it was always held. However,
we can mark the mutex as taken (noting that we may be nested underneath
ourselves) which means we can be reassured the right timeline->mutex is
always treated as held and let lockdep roam free.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
---
 drivers/gpu/drm/i915/gt/intel_context.h       |  3 +++
 drivers/gpu/drm/i915/gt/intel_context_types.h |  2 +-
 drivers/gpu/drm/i915/gt/intel_engine_pm.c     | 12 ++++++++++++
 drivers/gpu/drm/i915/gt/intel_timeline.c      |  4 ++++
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index fc7859f506c2..020139bfe3a9 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -89,17 +89,20 @@ void intel_context_exit_engine(struct intel_context *ce);
 
 static inline void intel_context_enter(struct intel_context *ce)
 {
+	lockdep_assert_held(&ce->ring->timeline->mutex);
 	if (!ce->active_count++)
 		ce->ops->enter(ce);
 }
 
 static inline void intel_context_mark_active(struct intel_context *ce)
 {
+	lockdep_assert_held(&ce->ring->timeline->mutex);
 	++ce->active_count;
 }
 
 static inline void intel_context_exit(struct intel_context *ce)
 {
+	lockdep_assert_held(&ce->ring->timeline->mutex);
 	GEM_BUG_ON(!ce->active_count);
 	if (!--ce->active_count)
 		ce->ops->exit(ce);
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 68a7e979b1a9..92afc207ec80 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -55,7 +55,7 @@ struct intel_context {
 	u32 *lrc_reg_state;
 	u64 lrc_desc;
 
-	unsigned int active_count; /* notionally protected by timeline->mutex */
+	unsigned int active_count; /* protected by timeline->mutex */
 
 	atomic_t pin_count;
 	struct mutex pin_mutex; /* guards pinning and associated on-gpuing */
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
index 76c828d11b05..1218b7d53b88 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -59,6 +59,16 @@ void intel_engine_park(struct intel_engine_cs *engine)
 	}
 }
 
+static inline void __timeline_mark_lock(struct intel_context *ce)
+{
+	mutex_acquire(&ce->ring->timeline->mutex.dep_map, 2, 0, _THIS_IP_);
+}
+
+static inline void __timeline_mark_unlock(struct intel_context *ce)
+{
+	mutex_release(&ce->ring->timeline->mutex.dep_map, 0, _THIS_IP_);
+}
+
 static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 {
 	struct i915_request *rq;
@@ -83,6 +93,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 	 * retiring the last request, thus all rings should be empty and
 	 * all timelines idle.
 	 */
+	__timeline_mark_lock(engine->kernel_context);
 	rq = __i915_request_create(engine->kernel_context, GFP_NOWAIT);
 	if (IS_ERR(rq))
 		/* Context switch failed, hope for the best! Maybe reset? */
@@ -94,6 +105,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
 
 	i915_request_add_barriers(rq);
 	__i915_request_commit(rq);
+	__timeline_mark_unlock(engine->kernel_context);
 
 	return false;
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
index 7b476cd55dac..eafd94d5e211 100644
--- a/drivers/gpu/drm/i915/gt/intel_timeline.c
+++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
@@ -338,6 +338,8 @@ void intel_timeline_enter(struct intel_timeline *tl)
 {
 	struct intel_gt_timelines *timelines = &tl->gt->timelines;
 
+	lockdep_assert_held(&tl->mutex);
+
 	GEM_BUG_ON(!atomic_read(&tl->pin_count));
 	if (tl->active_count++)
 		return;
@@ -352,6 +354,8 @@ void intel_timeline_exit(struct intel_timeline *tl)
 {
 	struct intel_gt_timelines *timelines = &tl->gt->timelines;
 
+	lockdep_assert_held(&tl->mutex);
+
 	GEM_BUG_ON(!tl->active_count);
 	if (--tl->active_count)
 		return;
-- 
2.22.0

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

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

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (12 preceding siblings ...)
  2019-07-18  7:00 ` [PATCH 20/20] drm/i915/gt: Mark context->active_count as protected by timeline->mutex Chris Wilson
@ 2019-07-18  7:16 ` Patchwork
  2019-07-18  7:25 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2019-07-18  7:16 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
URL   : https://patchwork.freedesktop.org/series/63857/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
3052e16a851c drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
1684f3a8d94e drm/i915/gt: Hook up intel_context_fini()
d2060ed71f61 drm/i915/gt: Provde a local intel_context.vm
f6813d8e65f0 drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine
7e180af1cb48 drm/i915: Hide unshrinkable context objects from the shrinker
c7d76267ac52 drm/i915: Remove obsolete engine cleanup
a61f9122ac61 drm/i915/gt: Move the [class][inst] lookup for engines onto the GT
-:222: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#222: 
new file mode 100644

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

-:228: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#228: FILE: drivers/gpu/drm/i915/gt/intel_engine_user.c:2:
+ * SPDX-License-Identifier: MIT

-:299: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#299: FILE: drivers/gpu/drm/i915/gt/intel_engine_user.h:1:
+/*

-:300: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#300: FILE: drivers/gpu/drm/i915/gt/intel_engine_user.h:2:
+ * SPDX-License-Identifier: MIT

total: 0 errors, 5 warnings, 0 checks, 415 lines checked
3261a51b15e0 drm/i915: Introduce for_each_user_engine()
-:215: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'engine__' - possible side-effects?
#215: FILE: drivers/gpu/drm/i915/i915_drv.h:1921:
+#define for_each_user_engine(engine__, i915__) \
+	for ((engine__) = rb_to_uabi_engine(rb_first(&(i915__)->uabi_engines));\
+	     (engine__); \
+	     (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))

total: 0 errors, 0 warnings, 1 checks, 187 lines checked
c9f4cfe20812 drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc
f5d82fdf1f10 drm/i915: Isolate i915_getparam_ioctl()
-:235: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#235: 
new file mode 100644

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

-:241: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#241: FILE: drivers/gpu/drm/i915/i915_getparam.c:2:
+ * SPDX-License-Identifier: MIT

total: 0 errors, 3 warnings, 0 checks, 374 lines checked
36fbf18b8bbc drm/i915: Rely on spinlock protection for GPU error capture
dab6a7647b6d drm/i915: Only include active engines in the capture state
ea58bbcbcc0d drm/i915: Teach execbuffer to take the engine wakeref not GT
ffd4a96993ad drm/i915/gt: Track timeline activeness in enter/exit
9ae34c3eea1b drm/i915/gt: Convert timeline tracking to spinlock
4dc0ccc95ef6 drm/i915/gt: Guard timeline pinning with its own mutex
2a2c98f24a90 drm/i915/gt: Add to timeline requires the timeline mutex
fd3f9ca3ba1d drm/i915: Protect request retirement with timeline->mutex
cfc5c6c2edf2 drm/i915: Replace struct_mutex for batch pool serialisation
-:305: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#305: 
new file mode 100644

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

-:311: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#311: FILE: drivers/gpu/drm/i915/gt/intel_engine_pool.c:2:
+ * SPDX-License-Identifier: MIT

-:493: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#493: FILE: drivers/gpu/drm/i915/gt/intel_engine_pool.h:1:
+/*

-:494: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#494: FILE: drivers/gpu/drm/i915/gt/intel_engine_pool.h:2:
+ * SPDX-License-Identifier: MIT

-:533: WARNING:SPDX_LICENSE_TAG: Missing or malformed SPDX-License-Identifier tag in line 1
#533: FILE: drivers/gpu/drm/i915/gt/intel_engine_pool_types.h:1:
+/*

-:534: WARNING:SPDX_LICENSE_TAG: Misplaced SPDX-License-Identifier tag - use line 1 instead
#534: FILE: drivers/gpu/drm/i915/gt/intel_engine_pool_types.h:2:
+ * SPDX-License-Identifier: MIT

-:550: CHECK:UNCOMMENTED_DEFINITION: spinlock_t definition without comment
#550: FILE: drivers/gpu/drm/i915/gt/intel_engine_pool_types.h:18:
+	spinlock_t lock;

total: 0 errors, 7 warnings, 1 checks, 604 lines checked
3bc0b1b684ae drm/i915/gt: Mark context->active_count as protected by timeline->mutex

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

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

* ✗ Fi.CI.SPARSE: warning for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (13 preceding siblings ...)
  2019-07-18  7:16 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt Patchwork
@ 2019-07-18  7:25 ` Patchwork
  2019-07-18  7:48 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2019-07-18  7:25 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
URL   : https://patchwork.freedesktop.org/series/63857/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
Okay!

Commit: drm/i915/gt: Hook up intel_context_fini()
Okay!

Commit: drm/i915/gt: Provde a local intel_context.vm
Okay!

Commit: drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine
Okay!

Commit: drm/i915: Hide unshrinkable context objects from the shrinker
Okay!

Commit: drm/i915: Remove obsolete engine cleanup
Okay!

Commit: drm/i915/gt: Move the [class][inst] lookup for engines onto the GT
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from constant value (8000000000000000 becomes 0)

Commit: drm/i915: Introduce for_each_user_engine()
Okay!

Commit: drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc
Okay!

Commit: drm/i915: Isolate i915_getparam_ioctl()
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from constant value (8000000000000000 becomes 0)

Commit: drm/i915: Rely on spinlock protection for GPU error capture
-O:drivers/gpu/drm/i915/i915_gpu_error.c:1007:21: warning: expression using sizeof(void)
-O:drivers/gpu/drm/i915/i915_gpu_error.c:1007:21: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/i915_gpu_error.c:1017:21: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/i915_gpu_error.c:1017:21: warning: expression using sizeof(void)
-./include/linux/slab.h:666:13: error: not a function <noident>
-./include/linux/slab.h:666:13: error: not a function <noident>

Commit: drm/i915: Only include active engines in the capture state
-drivers/gpu/drm/i915/i915_gpu_error.c:983:21: warning: expression using sizeof(void)
-drivers/gpu/drm/i915/i915_gpu_error.c:983:21: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/i915_gpu_error.c:983:21: warning: expression using sizeof(void)
+drivers/gpu/drm/i915/i915_gpu_error.c:983:21: warning: expression using sizeof(void)

Commit: drm/i915: Teach execbuffer to take the engine wakeref not GT
Okay!

Commit: drm/i915/gt: Track timeline activeness in enter/exit
Okay!

Commit: drm/i915/gt: Convert timeline tracking to spinlock
Okay!

Commit: drm/i915/gt: Guard timeline pinning with its own mutex
Okay!

Commit: drm/i915/gt: Add to timeline requires the timeline mutex
Okay!

Commit: drm/i915: Protect request retirement with timeline->mutex
Okay!

Commit: drm/i915: Replace struct_mutex for batch pool serialisation
+./include/uapi/linux/perf_event.h:147:56: warning: cast truncates bits from constant value (8000000000000000 becomes 0)

Commit: drm/i915/gt: Mark context->active_count as protected by timeline->mutex
Okay!

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

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

* ✓ Fi.CI.BAT: success for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (14 preceding siblings ...)
  2019-07-18  7:25 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-07-18  7:48 ` Patchwork
  2019-07-18 10:05 ` ✓ Fi.CI.IGT: " Patchwork
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2019-07-18  7:48 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
URL   : https://patchwork.freedesktop.org/series/63857/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6503 -> Patchwork_13679
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/

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

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

### IGT changes ###

#### Issues hit ####

  * igt@core_auth@basic-auth:
    - fi-icl-u3:          [PASS][1] -> [DMESG-WARN][2] ([fdo#107724])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-icl-u3/igt@core_auth@basic-auth.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-icl-u3/igt@core_auth@basic-auth.html

  * igt@gem_exec_parallel@basic:
    - fi-icl-dsi:         [PASS][3] -> [INCOMPLETE][4] ([fdo#107713])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-icl-dsi/igt@gem_exec_parallel@basic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-icl-dsi/igt@gem_exec_parallel@basic.html

  * igt@i915_selftest@live_contexts:
    - fi-skl-iommu:       [PASS][5] -> [INCOMPLETE][6] ([fdo#111050])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-skl-iommu/igt@i915_selftest@live_contexts.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-skl-iommu/igt@i915_selftest@live_contexts.html

  * igt@i915_selftest@live_execlists:
    - fi-skl-gvtdvm:      [PASS][7] -> [DMESG-FAIL][8] ([fdo#111108])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-skl-gvtdvm/igt@i915_selftest@live_execlists.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-skl-gvtdvm/igt@i915_selftest@live_execlists.html

  * igt@i915_selftest@live_reset:
    - fi-icl-u3:          [PASS][9] -> [INCOMPLETE][10] ([fdo#107713])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-icl-u3/igt@i915_selftest@live_reset.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-icl-u3/igt@i915_selftest@live_reset.html

  * igt@kms_busy@basic-flip-c:
    - fi-skl-6770hq:      [PASS][11] -> [SKIP][12] ([fdo#109271] / [fdo#109278]) +2 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-skl-6770hq/igt@kms_busy@basic-flip-c.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-skl-6770hq/igt@kms_busy@basic-flip-c.html

  * igt@kms_chamelium@dp-edid-read:
    - fi-cml-u2:          [PASS][13] -> [FAIL][14] ([fdo#109483])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-cml-u2/igt@kms_chamelium@dp-edid-read.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-cml-u2/igt@kms_chamelium@dp-edid-read.html

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-skl-6770hq:      [PASS][15] -> [SKIP][16] ([fdo#109271]) +23 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-dpms.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-dpms.html

  * igt@prime_vgem@basic-fence-flip:
    - fi-ilk-650:         [PASS][17] -> [DMESG-WARN][18] ([fdo#106387]) +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-ilk-650/igt@prime_vgem@basic-fence-flip.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-ilk-650/igt@prime_vgem@basic-fence-flip.html

  
#### Possible fixes ####

  * igt@i915_hangman@error-state-basic:
    - fi-bsw-kefka:       [SKIP][19] ([fdo#109271]) -> [PASS][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-bsw-kefka/igt@i915_hangman@error-state-basic.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-bsw-kefka/igt@i915_hangman@error-state-basic.html
    - fi-bsw-n3050:       [SKIP][21] ([fdo#109271]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-bsw-n3050/igt@i915_hangman@error-state-basic.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-bsw-n3050/igt@i915_hangman@error-state-basic.html

  * igt@kms_busy@basic-flip-c:
    - {fi-icl-u4}:        [DMESG-WARN][23] ([fdo#105602]) -> [PASS][24] +5 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-icl-u4/igt@kms_busy@basic-flip-c.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-icl-u4/igt@kms_busy@basic-flip-c.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-kbl-7500u:       [FAIL][25] ([fdo#109485]) -> [PASS][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html

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

  [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
  [fdo#106387]: https://bugs.freedesktop.org/show_bug.cgi?id=106387
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109483]: https://bugs.freedesktop.org/show_bug.cgi?id=109483
  [fdo#109485]: https://bugs.freedesktop.org/show_bug.cgi?id=109485
  [fdo#111045]: https://bugs.freedesktop.org/show_bug.cgi?id=111045
  [fdo#111050]: https://bugs.freedesktop.org/show_bug.cgi?id=111050
  [fdo#111108]: https://bugs.freedesktop.org/show_bug.cgi?id=111108


Participating hosts (53 -> 46)
------------------------------

  Additional (2): fi-byt-j1900 fi-cml-u 
  Missing    (9): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-pnv-d510 fi-icl-y fi-byt-clapper fi-bdw-samus 


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

  * Linux: CI_DRM_6503 -> Patchwork_13679

  CI_DRM_6503: 40ef4755f8a1f2fc49001b67358dc83c71492d4b @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5102: 6038ace76016d8892f4d13aef5301f71ca1a6e2d @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_13679: 3bc0b1b684ae485f1d92da6f0d1bf175f04c45c2 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

3bc0b1b684ae drm/i915/gt: Mark context->active_count as protected by timeline->mutex
cfc5c6c2edf2 drm/i915: Replace struct_mutex for batch pool serialisation
fd3f9ca3ba1d drm/i915: Protect request retirement with timeline->mutex
2a2c98f24a90 drm/i915/gt: Add to timeline requires the timeline mutex
4dc0ccc95ef6 drm/i915/gt: Guard timeline pinning with its own mutex
9ae34c3eea1b drm/i915/gt: Convert timeline tracking to spinlock
ffd4a96993ad drm/i915/gt: Track timeline activeness in enter/exit
ea58bbcbcc0d drm/i915: Teach execbuffer to take the engine wakeref not GT
dab6a7647b6d drm/i915: Only include active engines in the capture state
36fbf18b8bbc drm/i915: Rely on spinlock protection for GPU error capture
f5d82fdf1f10 drm/i915: Isolate i915_getparam_ioctl()
c9f4cfe20812 drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc
3261a51b15e0 drm/i915: Introduce for_each_user_engine()
a61f9122ac61 drm/i915/gt: Move the [class][inst] lookup for engines onto the GT
c7d76267ac52 drm/i915: Remove obsolete engine cleanup
7e180af1cb48 drm/i915: Hide unshrinkable context objects from the shrinker
f6813d8e65f0 drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine
d2060ed71f61 drm/i915/gt: Provde a local intel_context.vm
1684f3a8d94e drm/i915/gt: Hook up intel_context_fini()
3052e16a851c drm/i915: Move aliasing_ppgtt underneath its i915_ggtt

== Logs ==

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

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

* ✓ Fi.CI.IGT: success for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
       [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
                   ` (15 preceding siblings ...)
  2019-07-18  7:48 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-07-18 10:05 ` Patchwork
       [not found] ` <20190718070024.21781-3-chris@chris-wilson.co.uk>
       [not found] ` <20190718070024.21781-10-chris@chris-wilson.co.uk>
  18 siblings, 0 replies; 32+ messages in thread
From: Patchwork @ 2019-07-18 10:05 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt
URL   : https://patchwork.freedesktop.org/series/63857/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6503_full -> Patchwork_13679_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][1] -> [SKIP][2] ([fdo#110854])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb1/igt@gem_exec_balancer@smoke.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb3/igt@gem_exec_balancer@smoke.html

  * igt@kms_flip@flip-vs-expired-vblank:
    - shard-skl:          [PASS][3] -> [FAIL][4] ([fdo#105363])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-skl4/igt@kms_flip@flip-vs-expired-vblank.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-skl4/igt@kms_flip@flip-vs-expired-vblank.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-skl:          [PASS][5] -> [INCOMPLETE][6] ([fdo#109507])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-skl6/igt@kms_flip@flip-vs-suspend.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-skl5/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_flip@plain-flip-ts-check-interruptible:
    - shard-glk:          [PASS][7] -> [FAIL][8] ([fdo#100368])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-glk3/igt@kms_flip@plain-flip-ts-check-interruptible.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-glk2/igt@kms_flip@plain-flip-ts-check-interruptible.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [PASS][9] -> [DMESG-WARN][10] ([fdo#108566]) +4 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-kbl2/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-kbl2/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw:
    - shard-iclb:         [PASS][11] -> [FAIL][12] ([fdo#103167])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb3/igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-pri-indfb-multidraw.html

  * igt@kms_plane@pixel-format-pipe-c-planes-source-clamping:
    - shard-iclb:         [PASS][13] -> [INCOMPLETE][14] ([fdo#107713] / [fdo#110036 ]) +1 similar issue
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb2/igt@kms_plane@pixel-format-pipe-c-planes-source-clamping.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb8/igt@kms_plane@pixel-format-pipe-c-planes-source-clamping.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [PASS][15] -> [FAIL][16] ([fdo#108145] / [fdo#110403])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-skl9/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-skl9/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr2_su@frontbuffer:
    - shard-iclb:         [PASS][17] -> [SKIP][18] ([fdo#109642] / [fdo#111068])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb2/igt@kms_psr2_su@frontbuffer.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb4/igt@kms_psr2_su@frontbuffer.html

  * igt@kms_setmode@basic:
    - shard-kbl:          [PASS][19] -> [FAIL][20] ([fdo#99912])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-kbl2/igt@kms_setmode@basic.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-kbl2/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-b-ts-continuation-suspend:
    - shard-apl:          [PASS][21] -> [DMESG-WARN][22] ([fdo#108566]) +1 similar issue
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-apl1/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-apl8/igt@kms_vblank@pipe-b-ts-continuation-suspend.html

  * igt@kms_vblank@pipe-c-query-busy-hang:
    - shard-iclb:         [PASS][23] -> [INCOMPLETE][24] ([fdo#107713])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb6/igt@kms_vblank@pipe-c-query-busy-hang.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb7/igt@kms_vblank@pipe-c-query-busy-hang.html

  * igt@perf@blocking:
    - shard-skl:          [PASS][25] -> [FAIL][26] ([fdo#110728])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-skl2/igt@perf@blocking.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-skl10/igt@perf@blocking.html

  
#### Possible fixes ####

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-kbl:          [DMESG-WARN][27] ([fdo#108566]) -> [PASS][28] +2 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-kbl2/igt@gem_ctx_isolation@rcs0-s3.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-kbl6/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
    - shard-hsw:          [FAIL][29] ([fdo#105767]) -> [PASS][30]
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-hsw8/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-hsw1/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-hsw:          [INCOMPLETE][31] ([fdo#103540]) -> [PASS][32]
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-hsw4/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-hsw6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_flip@2x-flip-vs-expired-vblank:
    - shard-hsw:          [FAIL][33] ([fdo#102887]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-hsw7/igt@kms_flip@2x-flip-vs-expired-vblank.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-hsw7/igt@kms_flip@2x-flip-vs-expired-vblank.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible:
    - shard-skl:          [FAIL][35] ([fdo#105363]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-skl8/igt@kms_flip@flip-vs-expired-vblank-interruptible.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-skl5/igt@kms_flip@flip-vs-expired-vblank-interruptible.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-snb:          [INCOMPLETE][37] ([fdo#105411]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-snb1/igt@kms_flip@flip-vs-suspend-interruptible.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-snb6/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_flip@plain-flip-ts-check-interruptible:
    - shard-apl:          [FAIL][39] ([fdo#100368]) -> [PASS][40]
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-apl7/igt@kms_flip@plain-flip-ts-check-interruptible.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-apl3/igt@kms_flip@plain-flip-ts-check-interruptible.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt:
    - shard-iclb:         [FAIL][41] ([fdo#103167]) -> [PASS][42] +3 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes:
    - shard-apl:          [DMESG-WARN][43] ([fdo#108566]) -> [PASS][44] +1 similar issue
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-apl8/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-apl1/igt@kms_plane@plane-panning-bottom-right-suspend-pipe-a-planes.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [FAIL][45] ([fdo#108145]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-skl8/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-skl5/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_psr@psr2_cursor_mmap_cpu:
    - shard-iclb:         [SKIP][47] ([fdo#109441]) -> [PASS][48] +3 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-iclb8/igt@kms_psr@psr2_cursor_mmap_cpu.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-iclb2/igt@kms_psr@psr2_cursor_mmap_cpu.html

  * igt@kms_setmode@basic:
    - shard-apl:          [FAIL][49] ([fdo#99912]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6503/shard-apl5/igt@kms_setmode@basic.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_13679/shard-apl4/igt@kms_setmode@basic.html

  
  [fdo#100368]: https://bugs.freedesktop.org/show_bug.cgi?id=100368
  [fdo#102887]: https://bugs.freedesktop.org/show_bug.cgi?id=102887
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
  [fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
  [fdo#105411]: https://bugs.freedesktop.org/show_bug.cgi?id=105411
  [fdo#105767]: https://bugs.freedesktop.org/show_bug.cgi?id=105767
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109507]: https://bugs.freedesktop.org/show_bug.cgi?id=109507
  [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642
  [fdo#110036 ]: https://bugs.freedesktop.org/show_bug.cgi?id=110036 
  [fdo#110403]: https://bugs.freedesktop.org/show_bug.cgi?id=110403
  [fdo#110728]: https://bugs.freedesktop.org/show_bug.cgi?id=110728
  [fdo#110854]: https://bugs.freedesktop.org/show_bug.cgi?id=110854
  [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068
  [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


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

  * Linux: CI_DRM_6503 -> Patchwork_13679

  CI_DRM_6503: 40ef4755f8a1f2fc49001b67358dc83c71492d4b @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5102: 6038ace76016d8892f4d13aef5301f71ca1a6e2d @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_13679: 3bc0b1b684ae485f1d92da6f0d1bf175f04c45c2 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

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

* Re: [PATCH 02/20] drm/i915/gt: Hook up intel_context_fini()
  2019-07-18  7:00 ` [PATCH 02/20] drm/i915/gt: Hook up intel_context_fini() Chris Wilson
@ 2019-07-22 12:22   ` Tvrtko Ursulin
  0 siblings, 0 replies; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 12:22 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> Prior to freeing the struct, call the fini function to cleanup the
> common members. Currently this only calls the debug functions to mark
> the structs as destroyed, but may be extended to real work in future.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/gt/intel_context.c    | 6 ++++++
>   drivers/gpu/drm/i915/gt/intel_context.h    | 1 +
>   drivers/gpu/drm/i915/gt/intel_lrc.c        | 2 ++
>   drivers/gpu/drm/i915/gt/intel_ringbuffer.c | 1 +
>   drivers/gpu/drm/i915/gt/mock_engine.c      | 1 +
>   5 files changed, 11 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index b667e2b35804..9292b6ca5e9c 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -204,6 +204,12 @@ intel_context_init(struct intel_context *ce,
>   			 __intel_context_active, __intel_context_retire);
>   }
>   
> +void intel_context_fini(struct intel_context *ce)
> +{
> +	mutex_destroy(&ce->pin_mutex);
> +	i915_active_fini(&ce->active);
> +}
> +
>   static void i915_global_context_shrink(void)
>   {
>   	kmem_cache_shrink(global.slab_ce);
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
> index b41c610c2ce6..23c7e4c0ce7c 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context.h
> @@ -16,6 +16,7 @@
>   void intel_context_init(struct intel_context *ce,
>   			struct i915_gem_context *ctx,
>   			struct intel_engine_cs *engine);
> +void intel_context_fini(struct intel_context *ce);
>   
>   struct intel_context *
>   intel_context_create(struct i915_gem_context *ctx,
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index d076d9148b6d..f95a042a92c6 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -1553,6 +1553,7 @@ static void execlists_context_destroy(struct kref *kref)
>   	if (ce->state)
>   		__execlists_context_fini(ce);
>   
> +	intel_context_fini(ce);
>   	intel_context_free(ce);
>   }
>   
> @@ -3186,6 +3187,7 @@ static void virtual_context_destroy(struct kref *kref)
>   
>   	if (ve->context.state)
>   		__execlists_context_fini(&ve->context);
> +	intel_context_fini(&ve->context);
>   
>   	kfree(ve->bonds);
>   	kfree(ve);
> diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
> index 901ce1a94664..b056f25c66f2 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
> @@ -1388,6 +1388,7 @@ static void ring_context_destroy(struct kref *ref)
>   	if (ce->state)
>   		__ring_context_fini(ce);
>   
> +	intel_context_fini(ce);
>   	intel_context_free(ce);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/gt/mock_engine.c b/drivers/gpu/drm/i915/gt/mock_engine.c
> index 490ebd121f4c..10cb312462e5 100644
> --- a/drivers/gpu/drm/i915/gt/mock_engine.c
> +++ b/drivers/gpu/drm/i915/gt/mock_engine.c
> @@ -142,6 +142,7 @@ static void mock_context_destroy(struct kref *ref)
>   	if (ce->ring)
>   		mock_ring_free(ce->ring);
>   
> +	intel_context_fini(ce);
>   	intel_context_free(ce);
>   }
>   
> 

The patch which builds upon this looks like a good direction.

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

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

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

* Re: [PATCH 03/20] drm/i915/gt: Provde a local intel_context.vm
       [not found] ` <20190718070024.21781-3-chris@chris-wilson.co.uk>
@ 2019-07-22 12:33   ` Tvrtko Ursulin
  2019-07-22 16:28     ` Chris Wilson
  0 siblings, 1 reply; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 12:33 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> Track the currently bound address space used by the HW context. Minor
> conversions to use the local intel_context.vm are made, leaving behind
> some more surgery required to make intel_context the primary through the
> selftests.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/gem/i915_gem_client_blt.c |  4 +---
>   drivers/gpu/drm/i915/gem/i915_gem_context.c    | 13 ++++++++++---
>   drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 11 +++--------
>   drivers/gpu/drm/i915/gem/i915_gem_object_blt.c |  6 +-----
>   drivers/gpu/drm/i915/gt/intel_context.c        |  4 ++++
>   drivers/gpu/drm/i915/gt/intel_context_types.h  |  4 +++-
>   drivers/gpu/drm/i915/gt/intel_ringbuffer.c     |  6 +++---
>   drivers/gpu/drm/i915/i915_gpu_error.c          |  2 +-
>   8 files changed, 26 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/i915_gem_client_blt.c
> index 6f537e8e4dea..2312a0c6af89 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_client_blt.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_client_blt.c
> @@ -250,13 +250,11 @@ int i915_gem_schedule_fill_pages_blt(struct drm_i915_gem_object *obj,
>   				     u32 value)
>   {
>   	struct drm_i915_private *i915 = to_i915(obj->base.dev);
> -	struct i915_gem_context *ctx = ce->gem_context;
> -	struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
>   	struct clear_pages_work *work;
>   	struct i915_sleeve *sleeve;
>   	int err;
>   
> -	sleeve = create_sleeve(vm, obj, pages, page_sizes);
> +	sleeve = create_sleeve(ce->vm, obj, pages, page_sizes);
>   	if (IS_ERR(sleeve))
>   		return PTR_ERR(sleeve);
>   
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 0f6b0678f548..de9bb7aaef22 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -475,10 +475,18 @@ static struct i915_address_space *
>   __set_ppgtt(struct i915_gem_context *ctx, struct i915_address_space *vm)
>   {
>   	struct i915_address_space *old = ctx->vm;
> +	struct i915_gem_engines_iter it;
> +	struct intel_context *ce;
>   
>   	ctx->vm = i915_vm_get(vm);
>   	ctx->desc_template = default_desc_template(ctx->i915, vm);
>   
> +	for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> +		i915_vm_put(ce->vm);
> +		ce->vm = i915_vm_get(vm);
> +	}
> +	i915_gem_context_unlock_engines(ctx);
> +
>   	return old;
>   }
>   
> @@ -1113,9 +1121,8 @@ static int set_ppgtt(struct drm_i915_file_private *file_priv,
>   				   set_ppgtt_barrier,
>   				   old);
>   	if (err) {
> -		ctx->vm = old;
> -		ctx->desc_template = default_desc_template(ctx->i915, old);
> -		i915_vm_put(vm);
> +		i915_vm_put(__set_ppgtt(ctx, old));
> +		i915_vm_put(old);

Shouldn't this still be i915_vm_out(vm), for the extra vm reference the 
function did further up?

>   	}
>   
>   unlock:
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index 8a2047c4e7c3..cbd7c6e3a1f8 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -223,7 +223,6 @@ struct i915_execbuffer {
>   	struct intel_engine_cs *engine; /** engine to queue the request to */
>   	struct intel_context *context; /* logical state for the request */
>   	struct i915_gem_context *gem_context; /** caller's context */
> -	struct i915_address_space *vm; /** GTT and vma for the request */
>   
>   	struct i915_request *request; /** our request to build */
>   	struct i915_vma *batch; /** identity of the batch obj/vma */
> @@ -697,7 +696,7 @@ static int eb_reserve(struct i915_execbuffer *eb)
>   
>   		case 1:
>   			/* Too fragmented, unbind everything and retry */
> -			err = i915_gem_evict_vm(eb->vm);
> +			err = i915_gem_evict_vm(eb->context->vm);
>   			if (err)
>   				return err;
>   			break;
> @@ -725,12 +724,8 @@ static int eb_select_context(struct i915_execbuffer *eb)
>   		return -ENOENT;
>   
>   	eb->gem_context = ctx;
> -	if (ctx->vm) {
> -		eb->vm = ctx->vm;
> +	if (ctx->vm)
>   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> -	} else {
> -		eb->vm = &eb->i915->ggtt.vm;
> -	}
>   
>   	eb->context_flags = 0;
>   	if (test_bit(UCONTEXT_NO_ZEROMAP, &ctx->user_flags))
> @@ -832,7 +827,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
>   			goto err_vma;
>   		}
>   
> -		vma = i915_vma_instance(obj, eb->vm, NULL);
> +		vma = i915_vma_instance(obj, eb->context->vm, NULL);
>   		if (IS_ERR(vma)) {
>   			err = PTR_ERR(vma);
>   			goto err_obj;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c
> index cb42e3a312e2..685064af32d1 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_blt.c
> @@ -47,15 +47,11 @@ int i915_gem_object_fill_blt(struct drm_i915_gem_object *obj,
>   			     struct intel_context *ce,
>   			     u32 value)
>   {
> -	struct drm_i915_private *i915 = to_i915(obj->base.dev);
> -	struct i915_gem_context *ctx = ce->gem_context;
> -	struct i915_address_space *vm = ctx->vm ?: &i915->ggtt.vm;
>   	struct i915_request *rq;
>   	struct i915_vma *vma;
>   	int err;
>   
> -	/* XXX: ce->vm please */
> -	vma = i915_vma_instance(obj, vm, NULL);
> +	vma = i915_vma_instance(obj, ce->vm, NULL);
>   	if (IS_ERR(vma))
>   		return PTR_ERR(vma);
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index 9292b6ca5e9c..9e4f51ce52ff 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -191,6 +191,8 @@ intel_context_init(struct intel_context *ce,
>   	kref_init(&ce->ref);
>   
>   	ce->gem_context = ctx;
> +	ce->vm = i915_vm_get(ctx->vm ?: &engine->gt->ggtt->vm);
> +
>   	ce->engine = engine;
>   	ce->ops = engine->cops;
>   	ce->sseu = engine->sseu;
> @@ -206,6 +208,8 @@ intel_context_init(struct intel_context *ce,
>   
>   void intel_context_fini(struct intel_context *ce)
>   {
> +	i915_vm_put(ce->vm);
> +
>   	mutex_destroy(&ce->pin_mutex);
>   	i915_active_fini(&ce->active);
>   }
> diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
> index 4c0e211c715d..68a7e979b1a9 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
> @@ -36,7 +36,6 @@ struct intel_context_ops {
>   struct intel_context {
>   	struct kref ref;
>   
> -	struct i915_gem_context *gem_context;
>   	struct intel_engine_cs *engine;
>   	struct intel_engine_cs *inflight;
>   #define intel_context_inflight(ce) ptr_mask_bits((ce)->inflight, 2)
> @@ -44,6 +43,9 @@ struct intel_context {
>   #define intel_context_inflight_inc(ce) ptr_count_inc(&(ce)->inflight)
>   #define intel_context_inflight_dec(ce) ptr_count_dec(&(ce)->inflight)
>   
> +	struct i915_address_space *vm;
> +	struct i915_gem_context *gem_context;
> +
>   	struct list_head signal_link;
>   	struct list_head signals;
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
> index b056f25c66f2..38ec11ae6ed7 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ringbuffer.c
> @@ -1396,9 +1396,9 @@ static struct i915_address_space *vm_alias(struct intel_context *ce)
>   {
>   	struct i915_address_space *vm;
>   
> -	vm = ce->gem_context->vm;
> -	if (!vm)
> -		vm = &ce->engine->gt->ggtt->alias->vm;
> +	vm = ce->vm;
> +	if (i915_is_ggtt(vm))
> +		vm = &i915_vm_to_ggtt(vm)->alias->vm;
>   
>   	return vm;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index c5b89bf4d616..24835be300bc 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -1429,7 +1429,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
>   			struct i915_gem_context *ctx = request->gem_context;
>   			struct intel_ring *ring = request->ring;
>   
> -			ee->vm = ctx->vm ?: &engine->gt->ggtt->vm;
> +			ee->vm = request->hw_context->vm;
>   
>   			record_context(&ee->context, ctx);
>   
> 

Rest looks fine.

Regards,

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

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

* Re: [PATCH 06/20] drm/i915: Remove obsolete engine cleanup
  2019-07-18  7:00 ` [PATCH 06/20] drm/i915: Remove obsolete engine cleanup Chris Wilson
@ 2019-07-22 12:46   ` Tvrtko Ursulin
  2019-07-22 16:29     ` Chris Wilson
  0 siblings, 1 reply; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 12:46 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> Remove the outer layer cleanup of engine stubs; as i915_drv itself no
> longer tries to preallocate and so is not responsible for either the
> allocation or free. By the time we call the cleanup function, we already
> have cleaned up the engines.
> 
> v2: Lack of symmetry between mmio_probe and mmio_release for handling
> the error cleanup. engine->destroy() is a compound function that is
> called earlier in the normal release as it ties together other bits of
> state.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.c | 15 ++-------------
>   1 file changed, 2 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 7c209743e478..d1c3499c8e03 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -848,15 +848,6 @@ static int i915_workqueues_init(struct drm_i915_private *dev_priv)
>   	return -ENOMEM;
>   }
>   
> -static void i915_engines_cleanup(struct drm_i915_private *i915)
> -{
> -	struct intel_engine_cs *engine;
> -	enum intel_engine_id id;
> -
> -	for_each_engine(engine, i915, id)
> -		kfree(engine);
> -}
> -
>   static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
>   {
>   	destroy_workqueue(dev_priv->hotplug.dp_wq);
> @@ -928,7 +919,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
>   
>   	ret = i915_workqueues_init(dev_priv);
>   	if (ret < 0)
> -		goto err_engines;
> +		return ret;
>   
>   	intel_gt_init_early(&dev_priv->gt, dev_priv);
>   
> @@ -961,8 +952,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
>   	i915_gem_cleanup_early(dev_priv);
>   err_workqueues:
>   	i915_workqueues_cleanup(dev_priv);
> -err_engines:
> -	i915_engines_cleanup(dev_priv);
>   	return ret;
>   }
>   
> @@ -978,7 +967,6 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv)
>   	intel_uc_cleanup_early(&dev_priv->gt.uc);
>   	i915_gem_cleanup_early(dev_priv);
>   	i915_workqueues_cleanup(dev_priv);
> -	i915_engines_cleanup(dev_priv);
>   
>   	pm_qos_remove_request(&dev_priv->sb_qos);
>   	mutex_destroy(&dev_priv->sb_lock);
> @@ -1039,6 +1027,7 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv)
>    */
>   static void i915_driver_mmio_release(struct drm_i915_private *dev_priv)
>   {
> +	intel_engines_cleanup(dev_priv);
>   	intel_teardown_mchbar(dev_priv);
>   	intel_uncore_fini_mmio(&dev_priv->uncore);
>   	pci_dev_put(dev_priv->bridge_dev);
> 

Okay, looks okay. But do I dare to say that after all the efforts to 
make things more logical in the init/release paths we are still not 
there? :)

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

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

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

* Re: [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc
  2019-07-18  7:00 ` [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc Chris Wilson
@ 2019-07-22 12:49   ` Tvrtko Ursulin
  2019-07-22 16:34     ` Chris Wilson
  0 siblings, 1 reply; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 12:49 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> Use the same mechanism to determine if a backend engine exists for a
> uabi mapping as used internally.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.c | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index d1c3499c8e03..367bdc4689f1 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -61,6 +61,7 @@
>   
>   #include "gem/i915_gem_context.h"
>   #include "gem/i915_gem_ioctls.h"
> +#include "gt/intel_engine_user.h"
>   #include "gt/intel_gt.h"
>   #include "gt/intel_gt_pm.h"
>   #include "gt/intel_reset.h"
> @@ -371,16 +372,20 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
>   		value = dev_priv->overlay ? 1 : 0;
>   		break;
>   	case I915_PARAM_HAS_BSD:
> -		value = !!dev_priv->engine[VCS0];
> +		value = !!intel_engine_lookup_user(dev_priv,
> +						   I915_ENGINE_CLASS_VIDEO, 0);
>   		break;
>   	case I915_PARAM_HAS_BLT:
> -		value = !!dev_priv->engine[BCS0];
> +		value = !!intel_engine_lookup_user(dev_priv,
> +						   I915_ENGINE_CLASS_COPY, 0);
>   		break;
>   	case I915_PARAM_HAS_VEBOX:
> -		value = !!dev_priv->engine[VECS0];
> +		value = !!intel_engine_lookup_user(dev_priv,
> +						   I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
>   		break;
>   	case I915_PARAM_HAS_BSD2:
> -		value = !!dev_priv->engine[VCS1];
> +		value = !!intel_engine_lookup_user(dev_priv,
> +						   I915_ENGINE_CLASS_VIDEO, 1);
>   		break;
>   	case I915_PARAM_HAS_LLC:
>   		value = HAS_LLC(dev_priv);
> 

How do you see ABI semantics of these get_params - "GPU has engine X, or 
I915_EXEC_X will work"?

Regards,

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

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

* Re: [PATCH 10/20] drm/i915: Isolate i915_getparam_ioctl()
       [not found] ` <20190718070024.21781-10-chris@chris-wilson.co.uk>
@ 2019-07-22 12:53   ` Tvrtko Ursulin
  2019-07-22 16:04   ` Tvrtko Ursulin
  1 sibling, 0 replies; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 12:53 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> This giant switch has tendrils over other the struct and does not fit
> into the rest of the driver bring up and control of i915_drv.c. Push it
> to one side so that it can grow in peace.

No complaints on this one so acked.

Regards,

Tvrtko

> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/Makefile        |   1 +
>   drivers/gpu/drm/i915/i915_drv.c      | 169 ---------------------------
>   drivers/gpu/drm/i915/i915_drv.h      |   3 +
>   drivers/gpu/drm/i915/i915_getparam.c | 168 ++++++++++++++++++++++++++
>   4 files changed, 172 insertions(+), 169 deletions(-)
>   create mode 100644 drivers/gpu/drm/i915/i915_getparam.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index fafc3763dc2d..d2c1dcda20a1 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -42,6 +42,7 @@ subdir-ccflags-y += -I$(srctree)/$(src)
>   # core driver code
>   i915-y += i915_drv.o \
>   	  i915_irq.o \
> +	  i915_getparam.o \
>   	  i915_params.o \
>   	  i915_pci.o \
>   	  i915_scatterlist.o \
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 367bdc4689f1..c998af138689 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -61,22 +61,15 @@
>   
>   #include "gem/i915_gem_context.h"
>   #include "gem/i915_gem_ioctls.h"
> -#include "gt/intel_engine_user.h"
>   #include "gt/intel_gt.h"
>   #include "gt/intel_gt_pm.h"
> -#include "gt/intel_reset.h"
> -#include "gt/intel_workarounds.h"
> -#include "gt/uc/intel_uc.h"
>   
>   #include "i915_debugfs.h"
>   #include "i915_drv.h"
>   #include "i915_irq.h"
> -#include "i915_pmu.h"
>   #include "i915_query.h"
> -#include "i915_trace.h"
>   #include "i915_vgpu.h"
>   #include "intel_csr.h"
> -#include "intel_drv.h"
>   #include "intel_pm.h"
>   
>   static struct drm_driver driver;
> @@ -343,168 +336,6 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
>   	pci_dev_put(pch);
>   }
>   
> -static int i915_getparam_ioctl(struct drm_device *dev, void *data,
> -			       struct drm_file *file_priv)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct pci_dev *pdev = dev_priv->drm.pdev;
> -	const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
> -	drm_i915_getparam_t *param = data;
> -	int value;
> -
> -	switch (param->param) {
> -	case I915_PARAM_IRQ_ACTIVE:
> -	case I915_PARAM_ALLOW_BATCHBUFFER:
> -	case I915_PARAM_LAST_DISPATCH:
> -	case I915_PARAM_HAS_EXEC_CONSTANTS:
> -		/* Reject all old ums/dri params. */
> -		return -ENODEV;
> -	case I915_PARAM_CHIPSET_ID:
> -		value = pdev->device;
> -		break;
> -	case I915_PARAM_REVISION:
> -		value = pdev->revision;
> -		break;
> -	case I915_PARAM_NUM_FENCES_AVAIL:
> -		value = dev_priv->ggtt.num_fences;
> -		break;
> -	case I915_PARAM_HAS_OVERLAY:
> -		value = dev_priv->overlay ? 1 : 0;
> -		break;
> -	case I915_PARAM_HAS_BSD:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_VIDEO, 0);
> -		break;
> -	case I915_PARAM_HAS_BLT:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_COPY, 0);
> -		break;
> -	case I915_PARAM_HAS_VEBOX:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
> -		break;
> -	case I915_PARAM_HAS_BSD2:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_VIDEO, 1);
> -		break;
> -	case I915_PARAM_HAS_LLC:
> -		value = HAS_LLC(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_WT:
> -		value = HAS_WT(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_ALIASING_PPGTT:
> -		value = INTEL_PPGTT(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_SEMAPHORES:
> -		value = !!(dev_priv->caps.scheduler & I915_SCHEDULER_CAP_SEMAPHORES);
> -		break;
> -	case I915_PARAM_HAS_SECURE_BATCHES:
> -		value = capable(CAP_SYS_ADMIN);
> -		break;
> -	case I915_PARAM_CMD_PARSER_VERSION:
> -		value = i915_cmd_parser_get_version(dev_priv);
> -		break;
> -	case I915_PARAM_SUBSLICE_TOTAL:
> -		value = intel_sseu_subslice_total(sseu);
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_EU_TOTAL:
> -		value = sseu->eu_total;
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_HAS_GPU_RESET:
> -		value = i915_modparams.enable_hangcheck &&
> -			intel_has_gpu_reset(dev_priv);
> -		if (value && intel_has_reset_engine(dev_priv))
> -			value = 2;
> -		break;
> -	case I915_PARAM_HAS_RESOURCE_STREAMER:
> -		value = 0;
> -		break;
> -	case I915_PARAM_HAS_POOLED_EU:
> -		value = HAS_POOLED_EU(dev_priv);
> -		break;
> -	case I915_PARAM_MIN_EU_IN_POOL:
> -		value = sseu->min_eu_in_pool;
> -		break;
> -	case I915_PARAM_HUC_STATUS:
> -		value = intel_huc_check_status(&dev_priv->gt.uc.huc);
> -		if (value < 0)
> -			return value;
> -		break;
> -	case I915_PARAM_MMAP_GTT_VERSION:
> -		/* Though we've started our numbering from 1, and so class all
> -		 * earlier versions as 0, in effect their value is undefined as
> -		 * the ioctl will report EINVAL for the unknown param!
> -		 */
> -		value = i915_gem_mmap_gtt_version();
> -		break;
> -	case I915_PARAM_HAS_SCHEDULER:
> -		value = dev_priv->caps.scheduler;
> -		break;
> -
> -	case I915_PARAM_MMAP_VERSION:
> -		/* Remember to bump this if the version changes! */
> -	case I915_PARAM_HAS_GEM:
> -	case I915_PARAM_HAS_PAGEFLIPPING:
> -	case I915_PARAM_HAS_EXECBUF2: /* depends on GEM */
> -	case I915_PARAM_HAS_RELAXED_FENCING:
> -	case I915_PARAM_HAS_COHERENT_RINGS:
> -	case I915_PARAM_HAS_RELAXED_DELTA:
> -	case I915_PARAM_HAS_GEN7_SOL_RESET:
> -	case I915_PARAM_HAS_WAIT_TIMEOUT:
> -	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
> -	case I915_PARAM_HAS_PINNED_BATCHES:
> -	case I915_PARAM_HAS_EXEC_NO_RELOC:
> -	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
> -	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
> -	case I915_PARAM_HAS_EXEC_SOFTPIN:
> -	case I915_PARAM_HAS_EXEC_ASYNC:
> -	case I915_PARAM_HAS_EXEC_FENCE:
> -	case I915_PARAM_HAS_EXEC_CAPTURE:
> -	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
> -	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
> -	case I915_PARAM_HAS_EXEC_SUBMIT_FENCE:
> -		/* For the time being all of these are always true;
> -		 * if some supported hardware does not have one of these
> -		 * features this value needs to be provided from
> -		 * INTEL_INFO(), a feature macro, or similar.
> -		 */
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_CONTEXT_ISOLATION:
> -		value = intel_engines_has_context_isolation(dev_priv);
> -		break;
> -	case I915_PARAM_SLICE_MASK:
> -		value = sseu->slice_mask;
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_SUBSLICE_MASK:
> -		value = sseu->subslice_mask[0];
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_CS_TIMESTAMP_FREQUENCY:
> -		value = 1000 * RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz;
> -		break;
> -	case I915_PARAM_MMAP_GTT_COHERENT:
> -		value = INTEL_INFO(dev_priv)->has_coherent_ggtt;
> -		break;
> -	default:
> -		DRM_DEBUG("Unknown parameter %d\n", param->param);
> -		return -EINVAL;
> -	}
> -
> -	if (put_user(value, param->value))
> -		return -EFAULT;
> -
> -	return 0;
> -}
> -
>   static int i915_get_bridge_dev(struct drm_i915_private *dev_priv)
>   {
>   	int domain = pci_domain_nr(dev_priv->drm.pdev->bus);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8d1ad27b132d..dff28f5058bc 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2407,6 +2407,9 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
>   	return dev_priv->vgpu.active;
>   }
>   
> +int i915_getparam_ioctl(struct drm_device *dev, void *data,
> +			struct drm_file *file_priv);
> +
>   /* i915_gem.c */
>   int i915_gem_init_userptr(struct drm_i915_private *dev_priv);
>   void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c b/drivers/gpu/drm/i915/i915_getparam.c
> new file mode 100644
> index 000000000000..5d9101376a3d
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -0,0 +1,168 @@
> +/*
> + * SPDX-License-Identifier: MIT
> + */
> +
> +#include "gt/intel_engine_user.h"
> +
> +#include "i915_drv.h"
> +
> +int i915_getparam_ioctl(struct drm_device *dev, void *data,
> +			struct drm_file *file_priv)
> +{
> +	struct drm_i915_private *i915 = to_i915(dev);
> +	const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu;
> +	drm_i915_getparam_t *param = data;
> +	int value;
> +
> +	switch (param->param) {
> +	case I915_PARAM_IRQ_ACTIVE:
> +	case I915_PARAM_ALLOW_BATCHBUFFER:
> +	case I915_PARAM_LAST_DISPATCH:
> +	case I915_PARAM_HAS_EXEC_CONSTANTS:
> +		/* Reject all old ums/dri params. */
> +		return -ENODEV;
> +	case I915_PARAM_CHIPSET_ID:
> +		value = i915->drm.pdev->device;
> +		break;
> +	case I915_PARAM_REVISION:
> +		value = i915->drm.pdev->revision;
> +		break;
> +	case I915_PARAM_NUM_FENCES_AVAIL:
> +		value = i915->ggtt.num_fences;
> +		break;
> +	case I915_PARAM_HAS_OVERLAY:
> +		value = !!i915->overlay;
> +		break;
> +	case I915_PARAM_HAS_BSD:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_VIDEO, 0);
> +		break;
> +	case I915_PARAM_HAS_BLT:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_COPY, 0);
> +		break;
> +	case I915_PARAM_HAS_VEBOX:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
> +		break;
> +	case I915_PARAM_HAS_BSD2:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_VIDEO, 1);
> +		break;
> +	case I915_PARAM_HAS_LLC:
> +		value = HAS_LLC(i915);
> +		break;
> +	case I915_PARAM_HAS_WT:
> +		value = HAS_WT(i915);
> +		break;
> +	case I915_PARAM_HAS_ALIASING_PPGTT:
> +		value = INTEL_PPGTT(i915);
> +		break;
> +	case I915_PARAM_HAS_SEMAPHORES:
> +		value = !!(i915->caps.scheduler & I915_SCHEDULER_CAP_SEMAPHORES);
> +		break;
> +	case I915_PARAM_HAS_SECURE_BATCHES:
> +		value = capable(CAP_SYS_ADMIN);
> +		break;
> +	case I915_PARAM_CMD_PARSER_VERSION:
> +		value = i915_cmd_parser_get_version(i915);
> +		break;
> +	case I915_PARAM_SUBSLICE_TOTAL:
> +		value = intel_sseu_subslice_total(sseu);
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_EU_TOTAL:
> +		value = sseu->eu_total;
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_HAS_GPU_RESET:
> +		value = i915_modparams.enable_hangcheck &&
> +			intel_has_gpu_reset(i915);
> +		if (value && intel_has_reset_engine(i915))
> +			value = 2;
> +		break;
> +	case I915_PARAM_HAS_RESOURCE_STREAMER:
> +		value = 0;
> +		break;
> +	case I915_PARAM_HAS_POOLED_EU:
> +		value = HAS_POOLED_EU(i915);
> +		break;
> +	case I915_PARAM_MIN_EU_IN_POOL:
> +		value = sseu->min_eu_in_pool;
> +		break;
> +	case I915_PARAM_HUC_STATUS:
> +		value = intel_huc_check_status(&i915->gt.uc.huc);
> +		if (value < 0)
> +			return value;
> +		break;
> +	case I915_PARAM_MMAP_GTT_VERSION:
> +		/* Though we've started our numbering from 1, and so class all
> +		 * earlier versions as 0, in effect their value is undefined as
> +		 * the ioctl will report EINVAL for the unknown param!
> +		 */
> +		value = i915_gem_mmap_gtt_version();
> +		break;
> +	case I915_PARAM_HAS_SCHEDULER:
> +		value = i915->caps.scheduler;
> +		break;
> +
> +	case I915_PARAM_MMAP_VERSION:
> +		/* Remember to bump this if the version changes! */
> +	case I915_PARAM_HAS_GEM:
> +	case I915_PARAM_HAS_PAGEFLIPPING:
> +	case I915_PARAM_HAS_EXECBUF2: /* depends on GEM */
> +	case I915_PARAM_HAS_RELAXED_FENCING:
> +	case I915_PARAM_HAS_COHERENT_RINGS:
> +	case I915_PARAM_HAS_RELAXED_DELTA:
> +	case I915_PARAM_HAS_GEN7_SOL_RESET:
> +	case I915_PARAM_HAS_WAIT_TIMEOUT:
> +	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
> +	case I915_PARAM_HAS_PINNED_BATCHES:
> +	case I915_PARAM_HAS_EXEC_NO_RELOC:
> +	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
> +	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
> +	case I915_PARAM_HAS_EXEC_SOFTPIN:
> +	case I915_PARAM_HAS_EXEC_ASYNC:
> +	case I915_PARAM_HAS_EXEC_FENCE:
> +	case I915_PARAM_HAS_EXEC_CAPTURE:
> +	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
> +	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
> +	case I915_PARAM_HAS_EXEC_SUBMIT_FENCE:
> +		/* For the time being all of these are always true;
> +		 * if some supported hardware does not have one of these
> +		 * features this value needs to be provided from
> +		 * INTEL_INFO(), a feature macro, or similar.
> +		 */
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_CONTEXT_ISOLATION:
> +		value = intel_engines_has_context_isolation(i915);
> +		break;
> +	case I915_PARAM_SLICE_MASK:
> +		value = sseu->slice_mask;
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_SUBSLICE_MASK:
> +		value = sseu->subslice_mask[0];
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_CS_TIMESTAMP_FREQUENCY:
> +		value = 1000 * RUNTIME_INFO(i915)->cs_timestamp_frequency_khz;
> +		break;
> +	case I915_PARAM_MMAP_GTT_COHERENT:
> +		value = INTEL_INFO(i915)->has_coherent_ggtt;
> +		break;
> +	default:
> +		DRM_DEBUG("Unknown parameter %d\n", param->param);
> +		return -EINVAL;
> +	}
> +
> +	if (put_user(value, param->value))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 11/20] drm/i915: Rely on spinlock protection for GPU error capture
  2019-07-18  7:00 ` [PATCH 11/20] drm/i915: Rely on spinlock protection for GPU error capture Chris Wilson
@ 2019-07-22 13:40   ` Tvrtko Ursulin
  0 siblings, 0 replies; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 13:40 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> Trust that we now have adequate protection over the low level structures
> via the engine->active.lock to allow ourselves to capture the GPU error
> state without the heavy hammer of stop_machine(). Sadly this does mean
> that we have to forgo some of the lesser used information (not derived
> from the active state) that is not controlled by the active locks. This
> includes the list of buffers in the ppGTT and pinned globally in the
> GGTT. Originally this was used to manually verify relocations, but
> hasn't been required for sometime and modern mesa now has the habit of
> ensuring that all interesting buffers within a batch are captured in their
> entirety (that are the auxiliary state buffers, but not the textures).
> 
> A useful side-effect is that this allows us to restore error capturing
> for Braswell and Broxton.
> 
> v2: Use pagevec for a typical random number
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_gem_gtt.c   |   5 -
>   drivers/gpu/drm/i915/i915_gpu_error.c | 499 +++++++++++---------------
>   drivers/gpu/drm/i915/i915_gpu_error.h |  17 -
>   3 files changed, 203 insertions(+), 318 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 8f33d3e52b9e..500f3cdcc4b3 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -2966,11 +2966,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
>   		ggtt->vm.insert_page    = bxt_vtd_ggtt_insert_page__BKL;
>   		if (ggtt->vm.clear_range != nop_clear_range)
>   			ggtt->vm.clear_range = bxt_vtd_ggtt_clear_range__BKL;
> -
> -		/* Prevent recursively calling stop_machine() and deadlocks. */
> -		dev_info(dev_priv->drm.dev,
> -			 "Disabling error capture for VT-d workaround\n");
> -		i915_disable_error_state(dev_priv, -ENODEV);
>   	}
>   
>   	ggtt->invalidate = gen6_ggtt_invalidate;
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
> index 24835be300bc..131a52c428de 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.c
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.c
> @@ -29,8 +29,8 @@
>   
>   #include <linux/ascii85.h>
>   #include <linux/nmi.h>
> +#include <linux/pagevec.h>
>   #include <linux/scatterlist.h>
> -#include <linux/stop_machine.h>
>   #include <linux/utsname.h>
>   #include <linux/zlib.h>
>   
> @@ -46,6 +46,9 @@
>   #include "i915_scatterlist.h"
>   #include "intel_csr.h"
>   
> +#define ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
> +#define ATOMIC_MAYFAIL (GFP_ATOMIC | __GFP_NOWARN)
> +
>   static inline const struct intel_engine_cs *
>   engine_lookup(const struct drm_i915_private *i915, unsigned int id)
>   {
> @@ -67,26 +70,6 @@ engine_name(const struct drm_i915_private *i915, unsigned int id)
>   	return __engine_name(engine_lookup(i915, id));
>   }
>   
> -static const char *tiling_flag(int tiling)
> -{
> -	switch (tiling) {
> -	default:
> -	case I915_TILING_NONE: return "";
> -	case I915_TILING_X: return " X";
> -	case I915_TILING_Y: return " Y";
> -	}
> -}
> -
> -static const char *dirty_flag(int dirty)
> -{
> -	return dirty ? " dirty" : "";
> -}
> -
> -static const char *purgeable_flag(int purgeable)
> -{
> -	return purgeable ? " purgeable" : "";
> -}
> -
>   static void __sg_set_buf(struct scatterlist *sg,
>   			 void *addr, unsigned int len, loff_t it)
>   {
> @@ -114,7 +97,7 @@ static bool __i915_error_grow(struct drm_i915_error_state_buf *e, size_t len)
>   	if (e->cur == e->end) {
>   		struct scatterlist *sgl;
>   
> -		sgl = (typeof(sgl))__get_free_page(GFP_KERNEL);
> +		sgl = (typeof(sgl))__get_free_page(ALLOW_FAIL);
>   		if (!sgl) {
>   			e->err = -ENOMEM;
>   			return false;
> @@ -134,7 +117,7 @@ static bool __i915_error_grow(struct drm_i915_error_state_buf *e, size_t len)
>   	}
>   
>   	e->size = ALIGN(len + 1, SZ_64K);
> -	e->buf = kmalloc(e->size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
> +	e->buf = kmalloc(e->size, ALLOW_FAIL);
>   	if (!e->buf) {
>   		e->size = PAGE_ALIGN(len + 1);
>   		e->buf = kmalloc(e->size, GFP_KERNEL);
> @@ -211,47 +194,125 @@ i915_error_printer(struct drm_i915_error_state_buf *e)
>   	return p;
>   }
>   
> +/* single threaded page allocator with a reserved stash for emergencies */
> +static void *__alloc_page(gfp_t gfp)
> +{
> +	return (void *)__get_free_page(gfp);
> +}
> +
> +static void pool_fini(struct pagevec *pv)
> +{
> +	pagevec_release(pv);
> +}
> +
> +static int pool_refill(struct pagevec *pv, gfp_t gfp)
> +{
> +	while (pagevec_space(pv)) {
> +		struct page *p;
> +
> +		p = alloc_page(gfp);
> +		if (!p)
> +			return -ENOMEM;
> +
> +		pagevec_add(pv, p);
> +	}
> +
> +	return 0;
> +}
> +
> +static int pool_init(struct pagevec *pv, gfp_t gfp)
> +{
> +	int err;
> +
> +	pagevec_init(pv);
> +
> +	err = pool_refill(pv, gfp);
> +	if (err)
> +		pool_fini(pv);
> +
> +	return err;
> +}
> +
> +static void *pool_alloc(struct pagevec *pv, gfp_t gfp)
> +{
> +	void *ptr;
> +
> +	ptr = __alloc_page(gfp);
> +	if (ptr)
> +		return ptr;
> +
> +	if (!pagevec_count(pv))
> +		return NULL;
> +
> +	return page_address(pv->pages[--pv->nr]);
> +}
> +
> +static void pool_free(struct pagevec *pv, void *addr)
> +{
> +	struct page *p = virt_to_page(addr);
> +
> +	if (pagevec_space(pv)) {
> +		pv->pages[pv->nr++] = p;

pagevec_add(pv, p)

> +		return;
> +	}
> +
> +	__free_pages(p, 0);

if-else would probably me more readable, instead of if-return. Also 
could use __free_page to avoid ", 0".

> +}
> +
>   #ifdef CONFIG_DRM_I915_COMPRESS_ERROR
>   
>   struct compress {
> +	struct pagevec pool;
>   	struct z_stream_s zstream;
>   	void *tmp;
>   };
>   
>   static bool compress_init(struct compress *c)
>   {
> -	struct z_stream_s *zstream = memset(&c->zstream, 0, sizeof(c->zstream));
> +	struct z_stream_s *zstream = &c->zstream;
>   
> -	zstream->workspace =
> -		kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
> -			GFP_ATOMIC | __GFP_NOWARN);
> -	if (!zstream->workspace)
> +	if (pool_init(&c->pool, ALLOW_FAIL))
>   		return false;
>   
> -	if (zlib_deflateInit(zstream, Z_DEFAULT_COMPRESSION) != Z_OK) {
> -		kfree(zstream->workspace);
> +	zstream->workspace =
> +		kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
> +			ALLOW_FAIL);
> +	if (!zstream->workspace) {
> +		pool_fini(&c->pool);
>   		return false;
>   	}
>   
>   	c->tmp = NULL;
>   	if (i915_has_memcpy_from_wc())
> -		c->tmp = (void *)__get_free_page(GFP_ATOMIC | __GFP_NOWARN);
> +		c->tmp = pool_alloc(&c->pool, ALLOW_FAIL);
>   
>   	return true;
>   }
>   
> -static void *compress_next_page(struct drm_i915_error_object *dst)
> +static bool compress_start(struct compress *c)
>   {
> -	unsigned long page;
> +	struct z_stream_s *zstream = &c->zstream;
> +	void *workspace = zstream->workspace;
> +
> +	memset(zstream, 0, sizeof(*zstream));
> +	zstream->workspace = workspace;
> +
> +	return zlib_deflateInit(zstream, Z_DEFAULT_COMPRESSION) == Z_OK;
> +}
> +
> +static void *compress_next_page(struct compress *c,
> +				struct drm_i915_error_object *dst)
> +{
> +	void *page;
>   
>   	if (dst->page_count >= dst->num_pages)
>   		return ERR_PTR(-ENOSPC);
>   
> -	page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
> +	page = pool_alloc(&c->pool, ATOMIC_MAYFAIL);
>   	if (!page)
>   		return ERR_PTR(-ENOMEM);
>   
> -	return dst->pages[dst->page_count++] = (void *)page;
> +	return dst->pages[dst->page_count++] = page;
>   }
>   
>   static int compress_page(struct compress *c,
> @@ -267,7 +328,7 @@ static int compress_page(struct compress *c,
>   
>   	do {
>   		if (zstream->avail_out == 0) {
> -			zstream->next_out = compress_next_page(dst);
> +			zstream->next_out = compress_next_page(c, dst);
>   			if (IS_ERR(zstream->next_out))
>   				return PTR_ERR(zstream->next_out);
>   
> @@ -295,7 +356,7 @@ static int compress_flush(struct compress *c,
>   	do {
>   		switch (zlib_deflate(zstream, Z_FINISH)) {
>   		case Z_OK: /* more space requested */
> -			zstream->next_out = compress_next_page(dst);
> +			zstream->next_out = compress_next_page(c, dst);
>   			if (IS_ERR(zstream->next_out))
>   				return PTR_ERR(zstream->next_out);
>   
> @@ -316,15 +377,17 @@ static int compress_flush(struct compress *c,
>   	return 0;
>   }
>   
> -static void compress_fini(struct compress *c,
> -			  struct drm_i915_error_object *dst)
> +static void compress_finish(struct compress *c)
>   {
> -	struct z_stream_s *zstream = &c->zstream;
> +	zlib_deflateEnd(&c->zstream);
> +}
>   
> -	zlib_deflateEnd(zstream);
> -	kfree(zstream->workspace);
> +static void compress_fini(struct compress *c)
> +{
> +	kfree(c->zstream.workspace);
>   	if (c->tmp)
> -		free_page((unsigned long)c->tmp);
> +		pool_free(&c->pool, c->tmp);
> +	pool_fini(&c->pool);
>   }
>   
>   static void err_compression_marker(struct drm_i915_error_state_buf *m)
> @@ -335,9 +398,15 @@ static void err_compression_marker(struct drm_i915_error_state_buf *m)
>   #else
>   
>   struct compress {
> +	struct pagevec pool;
>   };
>   
>   static bool compress_init(struct compress *c)
> +{
> +	return pool_init(&c->pool, ALLOW_FAIL) == 0;
> +}
> +
> +static bool compress_start(struct compress *c)
>   {
>   	return true;
>   }
> @@ -346,14 +415,12 @@ static int compress_page(struct compress *c,
>   			 void *src,
>   			 struct drm_i915_error_object *dst)
>   {
> -	unsigned long page;
>   	void *ptr;
>   
> -	page = __get_free_page(GFP_ATOMIC | __GFP_NOWARN);
> -	if (!page)
> +	ptr = pool_alloc(&c->pool, ATOMIC_MAYFAIL);
> +	if (!ptr)
>   		return -ENOMEM;
>   
> -	ptr = (void *)page;
>   	if (!i915_memcpy_from_wc(ptr, src, PAGE_SIZE))
>   		memcpy(ptr, src, PAGE_SIZE);
>   	dst->pages[dst->page_count++] = ptr;
> @@ -367,9 +434,13 @@ static int compress_flush(struct compress *c,
>   	return 0;
>   }
>   
> -static void compress_fini(struct compress *c,
> -			  struct drm_i915_error_object *dst)
> +static void compress_finish(struct compress *c)
> +{
> +}
> +
> +static void compress_fini(struct compress *c)
>   {
> +	pool_fini(&c->pool);
>   }
>   
>   static void err_compression_marker(struct drm_i915_error_state_buf *m)
> @@ -379,36 +450,6 @@ static void err_compression_marker(struct drm_i915_error_state_buf *m)
>   
>   #endif
>   
> -static void print_error_buffers(struct drm_i915_error_state_buf *m,
> -				const char *name,
> -				struct drm_i915_error_buffer *err,
> -				int count)
> -{
> -	err_printf(m, "%s [%d]:\n", name, count);
> -
> -	while (count--) {
> -		err_printf(m, "    %08x_%08x %8u %02x %02x",
> -			   upper_32_bits(err->gtt_offset),
> -			   lower_32_bits(err->gtt_offset),
> -			   err->size,
> -			   err->read_domains,
> -			   err->write_domain);
> -		err_puts(m, tiling_flag(err->tiling));
> -		err_puts(m, dirty_flag(err->dirty));
> -		err_puts(m, purgeable_flag(err->purgeable));
> -		err_puts(m, err->userptr ? " userptr" : "");
> -		err_puts(m, i915_cache_level_str(m->i915, err->cache_level));
> -
> -		if (err->name)
> -			err_printf(m, " (name: %d)", err->name);
> -		if (err->fence_reg != I915_FENCE_REG_NONE)
> -			err_printf(m, " (fence: %d)", err->fence_reg);
> -
> -		err_puts(m, "\n");
> -		err++;
> -	}
> -}
> -
>   static void error_print_instdone(struct drm_i915_error_state_buf *m,
>   				 const struct drm_i915_error_engine *ee)
>   {
> @@ -734,33 +775,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
>   			error_print_engine(m, &error->engine[i], error->epoch);
>   	}
>   
> -	for (i = 0; i < ARRAY_SIZE(error->active_vm); i++) {
> -		char buf[128];
> -		int len, first = 1;
> -
> -		if (!error->active_vm[i])
> -			break;
> -
> -		len = scnprintf(buf, sizeof(buf), "Active (");
> -		for (j = 0; j < ARRAY_SIZE(error->engine); j++) {
> -			if (error->engine[j].vm != error->active_vm[i])
> -				continue;
> -
> -			len += scnprintf(buf + len, sizeof(buf), "%s%s",
> -					 first ? "" : ", ",
> -					 m->i915->engine[j]->name);
> -			first = 0;
> -		}
> -		scnprintf(buf + len, sizeof(buf), ")");
> -		print_error_buffers(m, buf,
> -				    error->active_bo[i],
> -				    error->active_bo_count[i]);
> -	}
> -
> -	print_error_buffers(m, "Pinned (global)",
> -			    error->pinned_bo,
> -			    error->pinned_bo_count);
> -
>   	for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
>   		const struct drm_i915_error_engine *ee = &error->engine[i];
>   
> @@ -974,10 +988,6 @@ void __i915_gpu_state_free(struct kref *error_ref)
>   		kfree(ee->requests);
>   	}
>   
> -	for (i = 0; i < ARRAY_SIZE(error->active_bo); i++)
> -		kfree(error->active_bo[i]);
> -	kfree(error->pinned_bo);
> -
>   	kfree(error->overlay);
>   	kfree(error->display);
>   
> @@ -990,12 +1000,12 @@ void __i915_gpu_state_free(struct kref *error_ref)
>   
>   static struct drm_i915_error_object *
>   i915_error_object_create(struct drm_i915_private *i915,
> -			 struct i915_vma *vma)
> +			 struct i915_vma *vma,
> +			 struct compress *compress)
>   {
>   	struct i915_ggtt *ggtt = &i915->ggtt;
>   	const u64 slot = ggtt->error_capture.start;
>   	struct drm_i915_error_object *dst;
> -	struct compress compress;
>   	unsigned long num_pages;
>   	struct sgt_iter iter;
>   	dma_addr_t dma;
> @@ -1006,22 +1016,21 @@ i915_error_object_create(struct drm_i915_private *i915,
>   
>   	num_pages = min_t(u64, vma->size, vma->obj->base.size) >> PAGE_SHIFT;
>   	num_pages = DIV_ROUND_UP(10 * num_pages, 8); /* worstcase zlib growth */
> -	dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *),
> -		      GFP_ATOMIC | __GFP_NOWARN);
> +	dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), ATOMIC_MAYFAIL);
>   	if (!dst)
>   		return NULL;
>   
> +	if (!compress_start(compress)) {
> +		kfree(dst);
> +		return NULL;
> +	}
> +
>   	dst->gtt_offset = vma->node.start;
>   	dst->gtt_size = vma->node.size;
>   	dst->num_pages = num_pages;
>   	dst->page_count = 0;
>   	dst->unused = 0;
>   
> -	if (!compress_init(&compress)) {
> -		kfree(dst);
> -		return NULL;
> -	}
> -
>   	ret = -EINVAL;
>   	for_each_sgt_dma(dma, iter, vma->pages) {
>   		void __iomem *s;
> @@ -1029,69 +1038,23 @@ i915_error_object_create(struct drm_i915_private *i915,
>   		ggtt->vm.insert_page(&ggtt->vm, dma, slot, I915_CACHE_NONE, 0);
>   
>   		s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
> -		ret = compress_page(&compress, (void  __force *)s, dst);
> +		ret = compress_page(compress, (void  __force *)s, dst);
>   		io_mapping_unmap_atomic(s);
>   		if (ret)
>   			break;
>   	}
>   
> -	if (ret || compress_flush(&compress, dst)) {
> +	if (ret || compress_flush(compress, dst)) {
>   		while (dst->page_count--)
> -			free_page((unsigned long)dst->pages[dst->page_count]);
> +			pool_free(&compress->pool, dst->pages[dst->page_count]);
>   		kfree(dst);
>   		dst = NULL;
>   	}
> +	compress_finish(compress);
>   
> -	compress_fini(&compress, dst);
>   	return dst;
>   }
>   
> -static void capture_bo(struct drm_i915_error_buffer *err,
> -		       struct i915_vma *vma)
> -{
> -	struct drm_i915_gem_object *obj = vma->obj;
> -
> -	err->size = obj->base.size;
> -	err->name = obj->base.name;
> -
> -	err->gtt_offset = vma->node.start;
> -	err->read_domains = obj->read_domains;
> -	err->write_domain = obj->write_domain;
> -	err->fence_reg = vma->fence ? vma->fence->id : -1;
> -	err->tiling = i915_gem_object_get_tiling(obj);
> -	err->dirty = obj->mm.dirty;
> -	err->purgeable = obj->mm.madv != I915_MADV_WILLNEED;
> -	err->userptr = obj->userptr.mm != NULL;
> -	err->cache_level = obj->cache_level;
> -}
> -
> -static u32 capture_error_bo(struct drm_i915_error_buffer *err,
> -			    int count, struct list_head *head,
> -			    unsigned int flags)
> -#define ACTIVE_ONLY BIT(0)
> -#define PINNED_ONLY BIT(1)
> -{
> -	struct i915_vma *vma;
> -	int i = 0;
> -
> -	list_for_each_entry(vma, head, vm_link) {
> -		if (!vma->obj)
> -			continue;
> -
> -		if (flags & ACTIVE_ONLY && !i915_vma_is_active(vma))
> -			continue;
> -
> -		if (flags & PINNED_ONLY && !i915_vma_is_pinned(vma))
> -			continue;
> -
> -		capture_bo(err++, vma);
> -		if (++i == count)
> -			break;
> -	}
> -
> -	return i;
> -}
> -
>   /*
>    * Generate a semi-unique error code. The code is not meant to have meaning, The
>    * code's only purpose is to try to prevent false duplicated bug reports by
> @@ -1281,7 +1244,7 @@ static void engine_record_requests(struct intel_engine_cs *engine,
>   	if (!count)
>   		return;
>   
> -	ee->requests = kcalloc(count, sizeof(*ee->requests), GFP_ATOMIC);
> +	ee->requests = kcalloc(count, sizeof(*ee->requests), ATOMIC_MAYFAIL);
>   	if (!ee->requests)
>   		return;
>   
> @@ -1349,8 +1312,10 @@ static void record_context(struct drm_i915_error_context *e,
>   	e->active = atomic_read(&ctx->active_count);
>   }
>   
> -static void request_record_user_bo(struct i915_request *request,
> -				   struct drm_i915_error_engine *ee)
> +static void
> +request_record_user_bo(struct i915_request *request,
> +		       struct drm_i915_error_engine *ee,
> +		       struct compress *compress)
>   {
>   	struct i915_capture_list *c;
>   	struct drm_i915_error_object **bo;
> @@ -1362,18 +1327,20 @@ static void request_record_user_bo(struct i915_request *request,
>   	if (!max)
>   		return;
>   
> -	bo = kmalloc_array(max, sizeof(*bo), GFP_ATOMIC);
> +	bo = kmalloc_array(max, sizeof(*bo), ATOMIC_MAYFAIL);
>   	if (!bo) {
>   		/* If we can't capture everything, try to capture something. */
>   		max = min_t(long, max, PAGE_SIZE / sizeof(*bo));
> -		bo = kmalloc_array(max, sizeof(*bo), GFP_ATOMIC);
> +		bo = kmalloc_array(max, sizeof(*bo), ATOMIC_MAYFAIL);
>   	}
>   	if (!bo)
>   		return;
>   
>   	count = 0;
>   	for (c = request->capture_list; c; c = c->next) {
> -		bo[count] = i915_error_object_create(request->i915, c->vma);
> +		bo[count] = i915_error_object_create(request->i915,
> +						     c->vma,
> +						     compress);
>   		if (!bo[count])
>   			break;
>   		if (++count == max)
> @@ -1386,7 +1353,8 @@ static void request_record_user_bo(struct i915_request *request,
>   
>   static struct drm_i915_error_object *
>   capture_object(struct drm_i915_private *dev_priv,
> -	       struct drm_i915_gem_object *obj)
> +	       struct drm_i915_gem_object *obj,
> +	       struct compress *compress)
>   {
>   	if (obj && i915_gem_object_has_pages(obj)) {
>   		struct i915_vma fake = {
> @@ -1396,13 +1364,14 @@ capture_object(struct drm_i915_private *dev_priv,
>   			.obj = obj,
>   		};
>   
> -		return i915_error_object_create(dev_priv, &fake);
> +		return i915_error_object_create(dev_priv, &fake, compress);
>   	} else {
>   		return NULL;
>   	}
>   }
>   
> -static void gem_record_rings(struct i915_gpu_state *error)
> +static void
> +gem_record_rings(struct i915_gpu_state *error, struct compress *compress)
>   {
>   	struct drm_i915_private *i915 = error->i915;
>   	int i;
> @@ -1420,6 +1389,9 @@ static void gem_record_rings(struct i915_gpu_state *error)
>   
>   		ee->engine_id = i;
>   
> +		/* Refill our page pool before entering atomic section */
> +		pool_refill(&compress->pool, ALLOW_FAIL);
> +
>   		error_record_engine_registers(error, engine, ee);
>   		error_record_engine_execlists(engine, ee);
>   
> @@ -1429,8 +1401,6 @@ static void gem_record_rings(struct i915_gpu_state *error)
>   			struct i915_gem_context *ctx = request->gem_context;
>   			struct intel_ring *ring = request->ring;
>   
> -			ee->vm = request->hw_context->vm;
> -
>   			record_context(&ee->context, ctx);
>   
>   			/* We need to copy these to an anonymous buffer
> @@ -1438,17 +1408,21 @@ static void gem_record_rings(struct i915_gpu_state *error)
>   			 * by userspace.
>   			 */
>   			ee->batchbuffer =
> -				i915_error_object_create(i915, request->batch);
> +				i915_error_object_create(i915,
> +							 request->batch,
> +							 compress);
>   
>   			if (HAS_BROKEN_CS_TLB(i915))
>   				ee->wa_batchbuffer =
>   				  i915_error_object_create(i915,
> -							   engine->gt->scratch);
> -			request_record_user_bo(request, ee);
> +							   engine->gt->scratch,
> +							   compress);
> +			request_record_user_bo(request, ee, compress);
>   
>   			ee->ctx =
>   				i915_error_object_create(i915,
> -							 request->hw_context->state);
> +							 request->hw_context->state,
> +							 compress);
>   
>   			error->simulated |=
>   				i915_gem_context_no_error_capture(ctx);
> @@ -1460,7 +1434,9 @@ static void gem_record_rings(struct i915_gpu_state *error)
>   			ee->cpu_ring_head = ring->head;
>   			ee->cpu_ring_tail = ring->tail;
>   			ee->ringbuffer =
> -				i915_error_object_create(i915, ring->vma);
> +				i915_error_object_create(i915,
> +							 ring->vma,
> +							 compress);
>   
>   			engine_record_requests(engine, request, ee);
>   		}
> @@ -1468,89 +1444,21 @@ static void gem_record_rings(struct i915_gpu_state *error)
>   
>   		ee->hws_page =
>   			i915_error_object_create(i915,
> -						 engine->status_page.vma);
> -
> -		ee->wa_ctx = i915_error_object_create(i915, engine->wa_ctx.vma);
> -
> -		ee->default_state = capture_object(i915, engine->default_state);
> -	}
> -}
> -
> -static void gem_capture_vm(struct i915_gpu_state *error,
> -			   struct i915_address_space *vm,
> -			   int idx)
> -{
> -	struct drm_i915_error_buffer *active_bo;
> -	struct i915_vma *vma;
> -	int count;
> -
> -	count = 0;
> -	list_for_each_entry(vma, &vm->bound_list, vm_link)
> -		if (i915_vma_is_active(vma))
> -			count++;
> -
> -	active_bo = NULL;
> -	if (count)
> -		active_bo = kcalloc(count, sizeof(*active_bo), GFP_ATOMIC);
> -	if (active_bo)
> -		count = capture_error_bo(active_bo,
> -					 count, &vm->bound_list,
> -					 ACTIVE_ONLY);
> -	else
> -		count = 0;
> +						 engine->status_page.vma,
> +						 compress);
>   
> -	error->active_vm[idx] = vm;
> -	error->active_bo[idx] = active_bo;
> -	error->active_bo_count[idx] = count;
> -}
> -
> -static void capture_active_buffers(struct i915_gpu_state *error)
> -{
> -	int cnt = 0, i, j;
> -
> -	BUILD_BUG_ON(ARRAY_SIZE(error->engine) > ARRAY_SIZE(error->active_bo));
> -	BUILD_BUG_ON(ARRAY_SIZE(error->active_bo) != ARRAY_SIZE(error->active_vm));
> -	BUILD_BUG_ON(ARRAY_SIZE(error->active_bo) != ARRAY_SIZE(error->active_bo_count));
> -
> -	/* Scan each engine looking for unique active contexts/vm */
> -	for (i = 0; i < ARRAY_SIZE(error->engine); i++) {
> -		struct drm_i915_error_engine *ee = &error->engine[i];
> -		bool found;
> -
> -		if (!ee->vm)
> -			continue;
> +		ee->wa_ctx =
> +			i915_error_object_create(i915,
> +						 engine->wa_ctx.vma,
> +						 compress);
>   
> -		found = false;
> -		for (j = 0; j < i && !found; j++)
> -			found = error->engine[j].vm == ee->vm;
> -		if (!found)
> -			gem_capture_vm(error, ee->vm, cnt++);
> +		ee->default_state =
> +			capture_object(i915, engine->default_state, compress);
>   	}
>   }
>   
> -static void capture_pinned_buffers(struct i915_gpu_state *error)
> -{
> -	struct i915_address_space *vm = &error->i915->ggtt.vm;
> -	struct drm_i915_error_buffer *bo;
> -	struct i915_vma *vma;
> -	int count;
> -
> -	count = 0;
> -	list_for_each_entry(vma, &vm->bound_list, vm_link)
> -		count++;
> -
> -	bo = NULL;
> -	if (count)
> -		bo = kcalloc(count, sizeof(*bo), GFP_ATOMIC);
> -	if (!bo)
> -		return;
> -
> -	error->pinned_bo_count =
> -		capture_error_bo(bo, count, &vm->bound_list, PINNED_ONLY);
> -	error->pinned_bo = bo;
> -}
> -
> -static void capture_uc_state(struct i915_gpu_state *error)
> +static void
> +capture_uc_state(struct i915_gpu_state *error, struct compress *compress)
>   {
>   	struct drm_i915_private *i915 = error->i915;
>   	struct i915_error_uc *error_uc = &error->uc;
> @@ -1567,9 +1475,11 @@ static void capture_uc_state(struct i915_gpu_state *error)
>   	 * As modparams are generally accesible from the userspace make
>   	 * explicit copies of the firmware paths.
>   	 */
> -	error_uc->guc_fw.path = kstrdup(uc->guc.fw.path, GFP_ATOMIC);
> -	error_uc->huc_fw.path = kstrdup(uc->huc.fw.path, GFP_ATOMIC);
> -	error_uc->guc_log = i915_error_object_create(i915, uc->guc.log.vma);
> +	error_uc->guc_fw.path = kstrdup(uc->guc.fw.path, ALLOW_FAIL);
> +	error_uc->huc_fw.path = kstrdup(uc->huc.fw.path, ALLOW_FAIL);
> +	error_uc->guc_log = i915_error_object_create(i915,
> +						     uc->guc.log.vma,
> +						     compress);
>   }
>   
>   /* Capture all registers which don't fit into another category. */
> @@ -1753,56 +1663,53 @@ static void capture_finish(struct i915_gpu_state *error)
>   	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
>   }
>   
> -static int capture(void *data)
> -{
> -	struct i915_gpu_state *error = data;
> -
> -	error->time = ktime_get_real();
> -	error->boottime = ktime_get_boottime();
> -	error->uptime = ktime_sub(ktime_get(),
> -				  error->i915->gt.last_init_time);
> -	error->capture = jiffies;
> -
> -	capture_params(error);
> -	capture_gen_state(error);
> -	capture_uc_state(error);
> -	capture_reg_state(error);
> -	gem_record_fences(error);
> -	gem_record_rings(error);
> -	capture_active_buffers(error);
> -	capture_pinned_buffers(error);
> -
> -	error->overlay = intel_overlay_capture_error_state(error->i915);
> -	error->display = intel_display_capture_error_state(error->i915);
> -
> -	error->epoch = capture_find_epoch(error);
> -
> -	capture_finish(error);
> -	return 0;
> -}
> -
>   #define DAY_AS_SECONDS(x) (24 * 60 * 60 * (x))
>   
>   struct i915_gpu_state *
>   i915_capture_gpu_state(struct drm_i915_private *i915)
>   {
>   	struct i915_gpu_state *error;
> +	struct compress compress;
>   
>   	/* Check if GPU capture has been disabled */
>   	error = READ_ONCE(i915->gpu_error.first_error);
>   	if (IS_ERR(error))
>   		return error;
>   
> -	error = kzalloc(sizeof(*error), GFP_ATOMIC);
> +	error = kzalloc(sizeof(*error), ALLOW_FAIL);
>   	if (!error) {
>   		i915_disable_error_state(i915, -ENOMEM);
>   		return ERR_PTR(-ENOMEM);
>   	}
>   
> +	if (!compress_init(&compress)) {
> +		kfree(error);
> +		i915_disable_error_state(i915, -ENOMEM);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
>   	kref_init(&error->ref);
>   	error->i915 = i915;
>   
> -	stop_machine(capture, error, NULL);
> +	error->time = ktime_get_real();
> +	error->boottime = ktime_get_boottime();
> +	error->uptime = ktime_sub(ktime_get(), i915->gt.last_init_time);
> +	error->capture = jiffies;
> +
> +	capture_params(error);
> +	capture_gen_state(error);
> +	capture_uc_state(error, &compress);
> +	capture_reg_state(error);
> +	gem_record_fences(error);
> +	gem_record_rings(error, &compress);
> +
> +	error->overlay = intel_overlay_capture_error_state(i915);
> +	error->display = intel_display_capture_error_state(i915);
> +
> +	error->epoch = capture_find_epoch(error);
> +
> +	capture_finish(error);
> +	compress_fini(&compress);
>   
>   	return error;
>   }
> diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h
> index 85f06bc5da05..a24c35107d16 100644
> --- a/drivers/gpu/drm/i915/i915_gpu_error.h
> +++ b/drivers/gpu/drm/i915/i915_gpu_error.h
> @@ -85,7 +85,6 @@ struct i915_gpu_state {
>   		/* Software tracked state */
>   		bool idle;
>   		unsigned long hangcheck_timestamp;
> -		struct i915_address_space *vm;
>   		int num_requests;
>   		u32 reset_count;
>   
> @@ -161,22 +160,6 @@ struct i915_gpu_state {
>   		} vm_info;
>   	} engine[I915_NUM_ENGINES];
>   
> -	struct drm_i915_error_buffer {
> -		u32 size;
> -		u32 name;
> -		u64 gtt_offset;
> -		u32 read_domains;
> -		u32 write_domain;
> -		s32 fence_reg:I915_MAX_NUM_FENCE_BITS;
> -		u32 tiling:2;
> -		u32 dirty:1;
> -		u32 purgeable:1;
> -		u32 userptr:1;
> -		u32 cache_level:3;
> -	} *active_bo[I915_NUM_ENGINES], *pinned_bo;
> -	u32 active_bo_count[I915_NUM_ENGINES], pinned_bo_count;
> -	struct i915_address_space *active_vm[I915_NUM_ENGINES];
> -
>   	struct scatterlist *sgl, *fit;
>   };
>   
> 

Otherwise;

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

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

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

* Re: [PATCH 13/20] drm/i915: Teach execbuffer to take the engine wakeref not GT
  2019-07-18  7:00 ` [PATCH 13/20] drm/i915: Teach execbuffer to take the engine wakeref not GT Chris Wilson
@ 2019-07-22 16:03   ` Tvrtko Ursulin
  0 siblings, 0 replies; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 16:03 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> In the next patch, we would like to couple into the engine wakeref to
> free the batch pool on idling. The caveat here is that we therefore want
> to track the engine wakeref more precisely and to hold it instead of the
> broader GT wakeref as we process the ioctl.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 36 ++++++++++++-------
>   drivers/gpu/drm/i915/gt/intel_context.h       |  7 ++++
>   2 files changed, 31 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index cbd7c6e3a1f8..8768d436e54b 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -2138,13 +2138,35 @@ static int eb_pin_context(struct i915_execbuffer *eb, struct intel_context *ce)
>   	if (err)
>   		return err;
>   
> +	/*
> +	 * Take a local wakeref for preparing to dispatch the execbuf as
> +	 * we expect to access the hardware fairly frequently in the
> +	 * process. Upon first dispatch, we acquire another prolonged
> +	 * wakeref that we hold until the GPU has been idle for at least
> +	 * 100ms.

Old comment but slightly not business of this layer to talk about 100ms.

> +	 */
> +	err = intel_context_timeline_lock(ce);
> +	if (err)
> +		goto err_unpin;
> +
> +	intel_context_enter(ce);
> +	intel_context_timeline_unlock(ce);
> +
>   	eb->engine = ce->engine;
>   	eb->context = ce;
>   	return 0;
> +
> +err_unpin:
> +	intel_context_unpin(ce);
> +	return err;
>   }
>   
>   static void eb_unpin_context(struct i915_execbuffer *eb)
>   {
> +	__intel_context_timeline_lock(eb->context);

Slight misuse of established semantics for underscores. (I'd expect no 
locking, or something along those lines, not a difference between 
interruptible and non-interruptible.)

> +	intel_context_exit(eb->context);
> +	intel_context_timeline_unlock(eb->context);
> +
>   	intel_context_unpin(eb->context);
>   }
>   
> @@ -2425,18 +2447,9 @@ i915_gem_do_execbuffer(struct drm_device *dev,
>   	if (unlikely(err))
>   		goto err_destroy;
>   
> -	/*
> -	 * Take a local wakeref for preparing to dispatch the execbuf as
> -	 * we expect to access the hardware fairly frequently in the
> -	 * process. Upon first dispatch, we acquire another prolonged
> -	 * wakeref that we hold until the GPU has been idle for at least
> -	 * 100ms.
> -	 */
> -	intel_gt_pm_get(&eb.i915->gt);
> -
>   	err = i915_mutex_lock_interruptible(dev);
>   	if (err)
> -		goto err_rpm;
> +		goto err_context;
>   
>   	err = eb_select_engine(&eb, file, args);
>   	if (unlikely(err))
> @@ -2601,8 +2614,7 @@ i915_gem_do_execbuffer(struct drm_device *dev,
>   	eb_unpin_context(&eb);
>   err_unlock:
>   	mutex_unlock(&dev->struct_mutex);
> -err_rpm:
> -	intel_gt_pm_put(&eb.i915->gt);
> +err_context:
>   	i915_gem_context_put(eb.gem_context);
>   err_destroy:
>   	eb_destroy(&eb);
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
> index 23c7e4c0ce7c..485886d84a56 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context.h
> @@ -127,6 +127,13 @@ static inline void intel_context_put(struct intel_context *ce)
>   	kref_put(&ce->ref, ce->ops->destroy);
>   }
>   
> +static inline void
> +__intel_context_timeline_lock(struct intel_context *ce)
> +	__acquires(&ce->ring->timeline->mutex)
> +{
> +	mutex_lock(&ce->ring->timeline->mutex);
> +}
> +
>   static inline int __must_check
>   intel_context_timeline_lock(struct intel_context *ce)
>   	__acquires(&ce->ring->timeline->mutex)
> 

But passable.

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

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

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

* Re: [PATCH 10/20] drm/i915: Isolate i915_getparam_ioctl()
       [not found] ` <20190718070024.21781-10-chris@chris-wilson.co.uk>
  2019-07-22 12:53   ` [PATCH 10/20] drm/i915: Isolate i915_getparam_ioctl() Tvrtko Ursulin
@ 2019-07-22 16:04   ` Tvrtko Ursulin
  2019-07-22 16:16     ` Chris Wilson
  1 sibling, 1 reply; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 16:04 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Forgot to say...

On 18/07/2019 08:00, Chris Wilson wrote:
> This giant switch has tendrils over other the struct and does not fit

... "over the struct"? Over something else I think, just can't guess 
what you wanted to say. :)

Regards,

Tvrtko

> into the rest of the driver bring up and control of i915_drv.c. Push it
> to one side so that it can grow in peace.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/Makefile        |   1 +
>   drivers/gpu/drm/i915/i915_drv.c      | 169 ---------------------------
>   drivers/gpu/drm/i915/i915_drv.h      |   3 +
>   drivers/gpu/drm/i915/i915_getparam.c | 168 ++++++++++++++++++++++++++
>   4 files changed, 172 insertions(+), 169 deletions(-)
>   create mode 100644 drivers/gpu/drm/i915/i915_getparam.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index fafc3763dc2d..d2c1dcda20a1 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -42,6 +42,7 @@ subdir-ccflags-y += -I$(srctree)/$(src)
>   # core driver code
>   i915-y += i915_drv.o \
>   	  i915_irq.o \
> +	  i915_getparam.o \
>   	  i915_params.o \
>   	  i915_pci.o \
>   	  i915_scatterlist.o \
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 367bdc4689f1..c998af138689 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -61,22 +61,15 @@
>   
>   #include "gem/i915_gem_context.h"
>   #include "gem/i915_gem_ioctls.h"
> -#include "gt/intel_engine_user.h"
>   #include "gt/intel_gt.h"
>   #include "gt/intel_gt_pm.h"
> -#include "gt/intel_reset.h"
> -#include "gt/intel_workarounds.h"
> -#include "gt/uc/intel_uc.h"
>   
>   #include "i915_debugfs.h"
>   #include "i915_drv.h"
>   #include "i915_irq.h"
> -#include "i915_pmu.h"
>   #include "i915_query.h"
> -#include "i915_trace.h"
>   #include "i915_vgpu.h"
>   #include "intel_csr.h"
> -#include "intel_drv.h"
>   #include "intel_pm.h"
>   
>   static struct drm_driver driver;
> @@ -343,168 +336,6 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
>   	pci_dev_put(pch);
>   }
>   
> -static int i915_getparam_ioctl(struct drm_device *dev, void *data,
> -			       struct drm_file *file_priv)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct pci_dev *pdev = dev_priv->drm.pdev;
> -	const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
> -	drm_i915_getparam_t *param = data;
> -	int value;
> -
> -	switch (param->param) {
> -	case I915_PARAM_IRQ_ACTIVE:
> -	case I915_PARAM_ALLOW_BATCHBUFFER:
> -	case I915_PARAM_LAST_DISPATCH:
> -	case I915_PARAM_HAS_EXEC_CONSTANTS:
> -		/* Reject all old ums/dri params. */
> -		return -ENODEV;
> -	case I915_PARAM_CHIPSET_ID:
> -		value = pdev->device;
> -		break;
> -	case I915_PARAM_REVISION:
> -		value = pdev->revision;
> -		break;
> -	case I915_PARAM_NUM_FENCES_AVAIL:
> -		value = dev_priv->ggtt.num_fences;
> -		break;
> -	case I915_PARAM_HAS_OVERLAY:
> -		value = dev_priv->overlay ? 1 : 0;
> -		break;
> -	case I915_PARAM_HAS_BSD:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_VIDEO, 0);
> -		break;
> -	case I915_PARAM_HAS_BLT:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_COPY, 0);
> -		break;
> -	case I915_PARAM_HAS_VEBOX:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
> -		break;
> -	case I915_PARAM_HAS_BSD2:
> -		value = !!intel_engine_lookup_user(dev_priv,
> -						   I915_ENGINE_CLASS_VIDEO, 1);
> -		break;
> -	case I915_PARAM_HAS_LLC:
> -		value = HAS_LLC(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_WT:
> -		value = HAS_WT(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_ALIASING_PPGTT:
> -		value = INTEL_PPGTT(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_SEMAPHORES:
> -		value = !!(dev_priv->caps.scheduler & I915_SCHEDULER_CAP_SEMAPHORES);
> -		break;
> -	case I915_PARAM_HAS_SECURE_BATCHES:
> -		value = capable(CAP_SYS_ADMIN);
> -		break;
> -	case I915_PARAM_CMD_PARSER_VERSION:
> -		value = i915_cmd_parser_get_version(dev_priv);
> -		break;
> -	case I915_PARAM_SUBSLICE_TOTAL:
> -		value = intel_sseu_subslice_total(sseu);
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_EU_TOTAL:
> -		value = sseu->eu_total;
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_HAS_GPU_RESET:
> -		value = i915_modparams.enable_hangcheck &&
> -			intel_has_gpu_reset(dev_priv);
> -		if (value && intel_has_reset_engine(dev_priv))
> -			value = 2;
> -		break;
> -	case I915_PARAM_HAS_RESOURCE_STREAMER:
> -		value = 0;
> -		break;
> -	case I915_PARAM_HAS_POOLED_EU:
> -		value = HAS_POOLED_EU(dev_priv);
> -		break;
> -	case I915_PARAM_MIN_EU_IN_POOL:
> -		value = sseu->min_eu_in_pool;
> -		break;
> -	case I915_PARAM_HUC_STATUS:
> -		value = intel_huc_check_status(&dev_priv->gt.uc.huc);
> -		if (value < 0)
> -			return value;
> -		break;
> -	case I915_PARAM_MMAP_GTT_VERSION:
> -		/* Though we've started our numbering from 1, and so class all
> -		 * earlier versions as 0, in effect their value is undefined as
> -		 * the ioctl will report EINVAL for the unknown param!
> -		 */
> -		value = i915_gem_mmap_gtt_version();
> -		break;
> -	case I915_PARAM_HAS_SCHEDULER:
> -		value = dev_priv->caps.scheduler;
> -		break;
> -
> -	case I915_PARAM_MMAP_VERSION:
> -		/* Remember to bump this if the version changes! */
> -	case I915_PARAM_HAS_GEM:
> -	case I915_PARAM_HAS_PAGEFLIPPING:
> -	case I915_PARAM_HAS_EXECBUF2: /* depends on GEM */
> -	case I915_PARAM_HAS_RELAXED_FENCING:
> -	case I915_PARAM_HAS_COHERENT_RINGS:
> -	case I915_PARAM_HAS_RELAXED_DELTA:
> -	case I915_PARAM_HAS_GEN7_SOL_RESET:
> -	case I915_PARAM_HAS_WAIT_TIMEOUT:
> -	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
> -	case I915_PARAM_HAS_PINNED_BATCHES:
> -	case I915_PARAM_HAS_EXEC_NO_RELOC:
> -	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
> -	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
> -	case I915_PARAM_HAS_EXEC_SOFTPIN:
> -	case I915_PARAM_HAS_EXEC_ASYNC:
> -	case I915_PARAM_HAS_EXEC_FENCE:
> -	case I915_PARAM_HAS_EXEC_CAPTURE:
> -	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
> -	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
> -	case I915_PARAM_HAS_EXEC_SUBMIT_FENCE:
> -		/* For the time being all of these are always true;
> -		 * if some supported hardware does not have one of these
> -		 * features this value needs to be provided from
> -		 * INTEL_INFO(), a feature macro, or similar.
> -		 */
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_CONTEXT_ISOLATION:
> -		value = intel_engines_has_context_isolation(dev_priv);
> -		break;
> -	case I915_PARAM_SLICE_MASK:
> -		value = sseu->slice_mask;
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_SUBSLICE_MASK:
> -		value = sseu->subslice_mask[0];
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_CS_TIMESTAMP_FREQUENCY:
> -		value = 1000 * RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz;
> -		break;
> -	case I915_PARAM_MMAP_GTT_COHERENT:
> -		value = INTEL_INFO(dev_priv)->has_coherent_ggtt;
> -		break;
> -	default:
> -		DRM_DEBUG("Unknown parameter %d\n", param->param);
> -		return -EINVAL;
> -	}
> -
> -	if (put_user(value, param->value))
> -		return -EFAULT;
> -
> -	return 0;
> -}
> -
>   static int i915_get_bridge_dev(struct drm_i915_private *dev_priv)
>   {
>   	int domain = pci_domain_nr(dev_priv->drm.pdev->bus);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8d1ad27b132d..dff28f5058bc 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2407,6 +2407,9 @@ static inline bool intel_vgpu_active(struct drm_i915_private *dev_priv)
>   	return dev_priv->vgpu.active;
>   }
>   
> +int i915_getparam_ioctl(struct drm_device *dev, void *data,
> +			struct drm_file *file_priv);
> +
>   /* i915_gem.c */
>   int i915_gem_init_userptr(struct drm_i915_private *dev_priv);
>   void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/i915_getparam.c b/drivers/gpu/drm/i915/i915_getparam.c
> new file mode 100644
> index 000000000000..5d9101376a3d
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/i915_getparam.c
> @@ -0,0 +1,168 @@
> +/*
> + * SPDX-License-Identifier: MIT
> + */
> +
> +#include "gt/intel_engine_user.h"
> +
> +#include "i915_drv.h"
> +
> +int i915_getparam_ioctl(struct drm_device *dev, void *data,
> +			struct drm_file *file_priv)
> +{
> +	struct drm_i915_private *i915 = to_i915(dev);
> +	const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu;
> +	drm_i915_getparam_t *param = data;
> +	int value;
> +
> +	switch (param->param) {
> +	case I915_PARAM_IRQ_ACTIVE:
> +	case I915_PARAM_ALLOW_BATCHBUFFER:
> +	case I915_PARAM_LAST_DISPATCH:
> +	case I915_PARAM_HAS_EXEC_CONSTANTS:
> +		/* Reject all old ums/dri params. */
> +		return -ENODEV;
> +	case I915_PARAM_CHIPSET_ID:
> +		value = i915->drm.pdev->device;
> +		break;
> +	case I915_PARAM_REVISION:
> +		value = i915->drm.pdev->revision;
> +		break;
> +	case I915_PARAM_NUM_FENCES_AVAIL:
> +		value = i915->ggtt.num_fences;
> +		break;
> +	case I915_PARAM_HAS_OVERLAY:
> +		value = !!i915->overlay;
> +		break;
> +	case I915_PARAM_HAS_BSD:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_VIDEO, 0);
> +		break;
> +	case I915_PARAM_HAS_BLT:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_COPY, 0);
> +		break;
> +	case I915_PARAM_HAS_VEBOX:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
> +		break;
> +	case I915_PARAM_HAS_BSD2:
> +		value = !!intel_engine_lookup_user(i915,
> +						   I915_ENGINE_CLASS_VIDEO, 1);
> +		break;
> +	case I915_PARAM_HAS_LLC:
> +		value = HAS_LLC(i915);
> +		break;
> +	case I915_PARAM_HAS_WT:
> +		value = HAS_WT(i915);
> +		break;
> +	case I915_PARAM_HAS_ALIASING_PPGTT:
> +		value = INTEL_PPGTT(i915);
> +		break;
> +	case I915_PARAM_HAS_SEMAPHORES:
> +		value = !!(i915->caps.scheduler & I915_SCHEDULER_CAP_SEMAPHORES);
> +		break;
> +	case I915_PARAM_HAS_SECURE_BATCHES:
> +		value = capable(CAP_SYS_ADMIN);
> +		break;
> +	case I915_PARAM_CMD_PARSER_VERSION:
> +		value = i915_cmd_parser_get_version(i915);
> +		break;
> +	case I915_PARAM_SUBSLICE_TOTAL:
> +		value = intel_sseu_subslice_total(sseu);
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_EU_TOTAL:
> +		value = sseu->eu_total;
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_HAS_GPU_RESET:
> +		value = i915_modparams.enable_hangcheck &&
> +			intel_has_gpu_reset(i915);
> +		if (value && intel_has_reset_engine(i915))
> +			value = 2;
> +		break;
> +	case I915_PARAM_HAS_RESOURCE_STREAMER:
> +		value = 0;
> +		break;
> +	case I915_PARAM_HAS_POOLED_EU:
> +		value = HAS_POOLED_EU(i915);
> +		break;
> +	case I915_PARAM_MIN_EU_IN_POOL:
> +		value = sseu->min_eu_in_pool;
> +		break;
> +	case I915_PARAM_HUC_STATUS:
> +		value = intel_huc_check_status(&i915->gt.uc.huc);
> +		if (value < 0)
> +			return value;
> +		break;
> +	case I915_PARAM_MMAP_GTT_VERSION:
> +		/* Though we've started our numbering from 1, and so class all
> +		 * earlier versions as 0, in effect their value is undefined as
> +		 * the ioctl will report EINVAL for the unknown param!
> +		 */
> +		value = i915_gem_mmap_gtt_version();
> +		break;
> +	case I915_PARAM_HAS_SCHEDULER:
> +		value = i915->caps.scheduler;
> +		break;
> +
> +	case I915_PARAM_MMAP_VERSION:
> +		/* Remember to bump this if the version changes! */
> +	case I915_PARAM_HAS_GEM:
> +	case I915_PARAM_HAS_PAGEFLIPPING:
> +	case I915_PARAM_HAS_EXECBUF2: /* depends on GEM */
> +	case I915_PARAM_HAS_RELAXED_FENCING:
> +	case I915_PARAM_HAS_COHERENT_RINGS:
> +	case I915_PARAM_HAS_RELAXED_DELTA:
> +	case I915_PARAM_HAS_GEN7_SOL_RESET:
> +	case I915_PARAM_HAS_WAIT_TIMEOUT:
> +	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
> +	case I915_PARAM_HAS_PINNED_BATCHES:
> +	case I915_PARAM_HAS_EXEC_NO_RELOC:
> +	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
> +	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
> +	case I915_PARAM_HAS_EXEC_SOFTPIN:
> +	case I915_PARAM_HAS_EXEC_ASYNC:
> +	case I915_PARAM_HAS_EXEC_FENCE:
> +	case I915_PARAM_HAS_EXEC_CAPTURE:
> +	case I915_PARAM_HAS_EXEC_BATCH_FIRST:
> +	case I915_PARAM_HAS_EXEC_FENCE_ARRAY:
> +	case I915_PARAM_HAS_EXEC_SUBMIT_FENCE:
> +		/* For the time being all of these are always true;
> +		 * if some supported hardware does not have one of these
> +		 * features this value needs to be provided from
> +		 * INTEL_INFO(), a feature macro, or similar.
> +		 */
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_CONTEXT_ISOLATION:
> +		value = intel_engines_has_context_isolation(i915);
> +		break;
> +	case I915_PARAM_SLICE_MASK:
> +		value = sseu->slice_mask;
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_SUBSLICE_MASK:
> +		value = sseu->subslice_mask[0];
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_CS_TIMESTAMP_FREQUENCY:
> +		value = 1000 * RUNTIME_INFO(i915)->cs_timestamp_frequency_khz;
> +		break;
> +	case I915_PARAM_MMAP_GTT_COHERENT:
> +		value = INTEL_INFO(i915)->has_coherent_ggtt;
> +		break;
> +	default:
> +		DRM_DEBUG("Unknown parameter %d\n", param->param);
> +		return -EINVAL;
> +	}
> +
> +	if (put_user(value, param->value))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit
  2019-07-18  7:00 ` [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit Chris Wilson
@ 2019-07-22 16:14   ` Tvrtko Ursulin
  2019-07-22 16:42     ` Chris Wilson
  0 siblings, 1 reply; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-22 16:14 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 18/07/2019 08:00, Chris Wilson wrote:
> Lift moving the timeline to/from the active_list on enter/exit in order
> to shorten the active tracking span in comparison to the existing
> pin/unpin.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/gem/i915_gem_pm.c        |  1 -
>   drivers/gpu/drm/i915/gt/intel_context.c       |  2 +
>   drivers/gpu/drm/i915/gt/intel_engine_pm.c     |  1 +
>   drivers/gpu/drm/i915/gt/intel_lrc.c           |  4 +
>   drivers/gpu/drm/i915/gt/intel_timeline.c      | 98 +++++++------------
>   drivers/gpu/drm/i915/gt/intel_timeline.h      |  3 +-
>   .../gpu/drm/i915/gt/intel_timeline_types.h    |  1 +
>   drivers/gpu/drm/i915/gt/selftest_timeline.c   |  2 -
>   8 files changed, 46 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
> index 8faf262278ae..195ee6eedac0 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c
> @@ -39,7 +39,6 @@ static void i915_gem_park(struct drm_i915_private *i915)
>   		i915_gem_batch_pool_fini(&engine->batch_pool);
>   	}
>   
> -	intel_timelines_park(i915);
>   	i915_vma_parked(i915);
>   
>   	i915_globals_park();
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index 9830edda1ade..87c84cc0f658 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -242,10 +242,12 @@ int __init i915_global_context_init(void)
>   void intel_context_enter_engine(struct intel_context *ce)
>   {
>   	intel_engine_pm_get(ce->engine);
> +	intel_timeline_enter(ce->ring->timeline);
>   }
>   
>   void intel_context_exit_engine(struct intel_context *ce)
>   {
> +	intel_timeline_exit(ce->ring->timeline);
>   	intel_engine_pm_put(ce->engine);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> index e74fbf04a68d..072f65e6a09e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
> @@ -89,6 +89,7 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
>   
>   	/* Check again on the next retirement. */
>   	engine->wakeref_serial = engine->serial + 1;
> +	intel_timeline_enter(rq->timeline);
>   
>   	i915_request_add_barriers(rq);
>   	__i915_request_commit(rq);
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index 884dfc1cb033..aceb990ae3b9 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -3253,6 +3253,8 @@ static void virtual_context_enter(struct intel_context *ce)
>   
>   	for (n = 0; n < ve->num_siblings; n++)
>   		intel_engine_pm_get(ve->siblings[n]);
> +
> +	intel_timeline_enter(ce->ring->timeline);

Here we couldn't enter all sibling contexts instead? Would be a bit 
wasteful I guess. And there must be a place where it is already done. 
But can't be on picking the engine, where is it?

>   }
>   
>   static void virtual_context_exit(struct intel_context *ce)
> @@ -3260,6 +3262,8 @@ static void virtual_context_exit(struct intel_context *ce)
>   	struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
>   	unsigned int n;
>   
> +	intel_timeline_exit(ce->ring->timeline);
> +
>   	for (n = 0; n < ve->num_siblings; n++)
>   		intel_engine_pm_put(ve->siblings[n]);
>   }
> diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
> index 6daa9eb59e19..4af0b9801d91 100644
> --- a/drivers/gpu/drm/i915/gt/intel_timeline.c
> +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
> @@ -278,64 +278,11 @@ void intel_timelines_init(struct drm_i915_private *i915)
>   	timelines_init(&i915->gt);
>   }
>   
> -static void timeline_add_to_active(struct intel_timeline *tl)
> -{
> -	struct intel_gt_timelines *gt = &tl->gt->timelines;
> -
> -	mutex_lock(&gt->mutex);
> -	list_add(&tl->link, &gt->active_list);
> -	mutex_unlock(&gt->mutex);
> -}
> -
> -static void timeline_remove_from_active(struct intel_timeline *tl)
> -{
> -	struct intel_gt_timelines *gt = &tl->gt->timelines;
> -
> -	mutex_lock(&gt->mutex);
> -	list_del(&tl->link);
> -	mutex_unlock(&gt->mutex);
> -}
> -
> -static void timelines_park(struct intel_gt *gt)
> -{
> -	struct intel_gt_timelines *timelines = &gt->timelines;
> -	struct intel_timeline *timeline;
> -
> -	mutex_lock(&timelines->mutex);
> -	list_for_each_entry(timeline, &timelines->active_list, 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);
> -	}
> -	mutex_unlock(&timelines->mutex);
> -}
> -
> -/**
> - * intel_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 intel_timelines_park(struct drm_i915_private *i915)
> -{
> -	timelines_park(&i915->gt);
> -}
> -
>   void intel_timeline_fini(struct intel_timeline *timeline)
>   {
>   	GEM_BUG_ON(timeline->pin_count);
>   	GEM_BUG_ON(!list_empty(&timeline->requests));
>   
> -	i915_syncmap_free(&timeline->sync);
> -
>   	if (timeline->hwsp_cacheline)
>   		cacheline_free(timeline->hwsp_cacheline);
>   	else
> @@ -370,6 +317,7 @@ int intel_timeline_pin(struct intel_timeline *tl)
>   	if (tl->pin_count++)
>   		return 0;
>   	GEM_BUG_ON(!tl->pin_count);
> +	GEM_BUG_ON(tl->active_count);
>   
>   	err = i915_vma_pin(tl->hwsp_ggtt, 0, 0, PIN_GLOBAL | PIN_HIGH);
>   	if (err)
> @@ -380,7 +328,6 @@ int intel_timeline_pin(struct intel_timeline *tl)
>   		offset_in_page(tl->hwsp_offset);
>   
>   	cacheline_acquire(tl->hwsp_cacheline);
> -	timeline_add_to_active(tl);
>   
>   	return 0;
>   
> @@ -389,6 +336,40 @@ int intel_timeline_pin(struct intel_timeline *tl)
>   	return err;
>   }
>   
> +void intel_timeline_enter(struct intel_timeline *tl)
> +{
> +	struct intel_gt_timelines *timelines = &tl->gt->timelines;
> +
> +	GEM_BUG_ON(!tl->pin_count);
> +	if (tl->active_count++)
> +		return;
> +	GEM_BUG_ON(!tl->active_count); /* overflow? */
> +
> +	mutex_lock(&timelines->mutex);
> +	list_add(&tl->link, &timelines->active_list);
> +	mutex_unlock(&timelines->mutex);
> +}
> +
> +void intel_timeline_exit(struct intel_timeline *tl)
> +{
> +	struct intel_gt_timelines *timelines = &tl->gt->timelines;
> +
> +	GEM_BUG_ON(!tl->active_count);
> +	if (--tl->active_count)
> +		return;
> +
> +	mutex_lock(&timelines->mutex);
> +	list_del(&tl->link);
> +	mutex_unlock(&timelines->mutex);

So we end up with one lock protecting tl->active_count and another for 
the list of active timelines?

> +
> +	/*
> +	 * Since this timeline is idle, all bariers upon which we were waiting
> +	 * must also be complete and so we can discard the last used barriers
> +	 * without loss of information.
> +	 */
> +	i915_syncmap_free(&tl->sync);
> +}
> +
>   static u32 timeline_advance(struct intel_timeline *tl)
>   {
>   	GEM_BUG_ON(!tl->pin_count);
> @@ -546,16 +527,9 @@ void intel_timeline_unpin(struct intel_timeline *tl)
>   	if (--tl->pin_count)
>   		return;
>   
> -	timeline_remove_from_active(tl);
> +	GEM_BUG_ON(tl->active_count);
>   	cacheline_release(tl->hwsp_cacheline);
>   
> -	/*
> -	 * Since this timeline is idle, all bariers upon which we were waiting
> -	 * must also be complete and so we can discard the last used barriers
> -	 * without loss of information.
> -	 */
> -	i915_syncmap_free(&tl->sync);
> -
>   	__i915_vma_unpin(tl->hwsp_ggtt);
>   }
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.h b/drivers/gpu/drm/i915/gt/intel_timeline.h
> index e08cebf64833..f583af1ba18d 100644
> --- a/drivers/gpu/drm/i915/gt/intel_timeline.h
> +++ b/drivers/gpu/drm/i915/gt/intel_timeline.h
> @@ -77,9 +77,11 @@ static inline bool intel_timeline_sync_is_later(struct intel_timeline *tl,
>   }
>   
>   int intel_timeline_pin(struct intel_timeline *tl);
> +void intel_timeline_enter(struct intel_timeline *tl);
>   int intel_timeline_get_seqno(struct intel_timeline *tl,
>   			     struct i915_request *rq,
>   			     u32 *seqno);
> +void intel_timeline_exit(struct intel_timeline *tl);
>   void intel_timeline_unpin(struct intel_timeline *tl);
>   
>   int intel_timeline_read_hwsp(struct i915_request *from,
> @@ -87,7 +89,6 @@ int intel_timeline_read_hwsp(struct i915_request *from,
>   			     u32 *hwsp_offset);
>   
>   void intel_timelines_init(struct drm_i915_private *i915);
> -void intel_timelines_park(struct drm_i915_private *i915);
>   void intel_timelines_fini(struct drm_i915_private *i915);
>   
>   #endif
> diff --git a/drivers/gpu/drm/i915/gt/intel_timeline_types.h b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
> index 9a71aea7a338..b820ee76b7f5 100644
> --- a/drivers/gpu/drm/i915/gt/intel_timeline_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
> @@ -58,6 +58,7 @@ struct intel_timeline {
>   	 */
>   	struct i915_syncmap *sync;
>   
> +	unsigned int active_count;

Is it becoming non-obvious what is pin_count and what is active_count? I 
suggest some comments dropped along the members here.

>   	struct list_head link;
>   	struct intel_gt *gt;
>   
> diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c
> index f0a840030382..d54113697745 100644
> --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c
> +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c
> @@ -816,8 +816,6 @@ static int live_hwsp_recycle(void *arg)
>   
>   			if (err)
>   				goto out;
> -
> -			intel_timelines_park(i915); /* Encourage recycling! */
>   		} while (!__igt_timeout(end_time, NULL));
>   	}
>   
> 

Regards,

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

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

* Re: [PATCH 10/20] drm/i915: Isolate i915_getparam_ioctl()
  2019-07-22 16:04   ` Tvrtko Ursulin
@ 2019-07-22 16:16     ` Chris Wilson
  0 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-22 16:16 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-07-22 17:04:54)
> Forgot to say...
> 
> On 18/07/2019 08:00, Chris Wilson wrote:
> > This giant switch has tendrils over other the struct and does not fit
> 
> ... "over the struct"? Over something else I think, just can't guess 
> what you wanted to say. :)

All over. Very confused.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/20] drm/i915/gt: Provde a local intel_context.vm
  2019-07-22 12:33   ` [PATCH 03/20] drm/i915/gt: Provde a local intel_context.vm Tvrtko Ursulin
@ 2019-07-22 16:28     ` Chris Wilson
  2019-07-23 13:44       ` Tvrtko Ursulin
  0 siblings, 1 reply; 32+ messages in thread
From: Chris Wilson @ 2019-07-22 16:28 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-07-22 13:33:14)
> 
> On 18/07/2019 08:00, Chris Wilson wrote:
> > @@ -1113,9 +1121,8 @@ static int set_ppgtt(struct drm_i915_file_private *file_priv,
> >                                  set_ppgtt_barrier,
> >                                  old);
> >       if (err) {
> > -             ctx->vm = old;
> > -             ctx->desc_template = default_desc_template(ctx->i915, old);
> > -             i915_vm_put(vm);
> > +             i915_vm_put(__set_ppgtt(ctx, old));
> > +             i915_vm_put(old);
> 
> Shouldn't this still be i915_vm_out(vm), for the extra vm reference the 
> function did further up?

__set_ppgtt() returns the vm, so this is
	i915_vm_put(vm);
	i915_vm_put(old); /* since we just acquired a ref to old again */
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/20] drm/i915: Remove obsolete engine cleanup
  2019-07-22 12:46   ` Tvrtko Ursulin
@ 2019-07-22 16:29     ` Chris Wilson
  0 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-22 16:29 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-07-22 13:46:06)
> 
> On 18/07/2019 08:00, Chris Wilson wrote:
> >   static void i915_driver_mmio_release(struct drm_i915_private *dev_priv)
> >   {
> > +     intel_engines_cleanup(dev_priv);
> >       intel_teardown_mchbar(dev_priv);
> >       intel_uncore_fini_mmio(&dev_priv->uncore);
> >       pci_dev_put(dev_priv->bridge_dev);
> > 
> 
> Okay, looks okay. But do I dare to say that after all the efforts to 
> make things more logical in the init/release paths we are still not 
> there? :)

intel_engines_* are all placeholders for intel_gt_foo_bar :)
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc
  2019-07-22 12:49   ` Tvrtko Ursulin
@ 2019-07-22 16:34     ` Chris Wilson
  0 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-22 16:34 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-07-22 13:49:54)
> 
> On 18/07/2019 08:00, Chris Wilson wrote:
> > Use the same mechanism to determine if a backend engine exists for a
> > uabi mapping as used internally.
> > 
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> >   drivers/gpu/drm/i915/i915_drv.c | 13 +++++++++----
> >   1 file changed, 9 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> > index d1c3499c8e03..367bdc4689f1 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.c
> > +++ b/drivers/gpu/drm/i915/i915_drv.c
> > @@ -61,6 +61,7 @@
> >   
> >   #include "gem/i915_gem_context.h"
> >   #include "gem/i915_gem_ioctls.h"
> > +#include "gt/intel_engine_user.h"
> >   #include "gt/intel_gt.h"
> >   #include "gt/intel_gt_pm.h"
> >   #include "gt/intel_reset.h"
> > @@ -371,16 +372,20 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data,
> >               value = dev_priv->overlay ? 1 : 0;
> >               break;
> >       case I915_PARAM_HAS_BSD:
> > -             value = !!dev_priv->engine[VCS0];
> > +             value = !!intel_engine_lookup_user(dev_priv,
> > +                                                I915_ENGINE_CLASS_VIDEO, 0);
> >               break;
> >       case I915_PARAM_HAS_BLT:
> > -             value = !!dev_priv->engine[BCS0];
> > +             value = !!intel_engine_lookup_user(dev_priv,
> > +                                                I915_ENGINE_CLASS_COPY, 0);
> >               break;
> >       case I915_PARAM_HAS_VEBOX:
> > -             value = !!dev_priv->engine[VECS0];
> > +             value = !!intel_engine_lookup_user(dev_priv,
> > +                                                I915_ENGINE_CLASS_VIDEO_ENHANCE, 0);
> >               break;
> >       case I915_PARAM_HAS_BSD2:
> > -             value = !!dev_priv->engine[VCS1];
> > +             value = !!intel_engine_lookup_user(dev_priv,
> > +                                                I915_ENGINE_CLASS_VIDEO, 1);
> >               break;
> >       case I915_PARAM_HAS_LLC:
> >               value = HAS_LLC(dev_priv);
> > 
> 
> How do you see ABI semantics of these get_params - "GPU has engine X, or 
> I915_EXEC_X will work"?

I wish they never existed. I don't think we want to be any more
prescriptive than:

	if !HAS_foo: then I915_EXEC_foo (no ctx->engines[]) returns -EINVAL

so I think there's a link here with whatever default_engines() becomes.
May be best to punt these next to default_engines so we can try and keep
them in sync.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit
  2019-07-22 16:14   ` Tvrtko Ursulin
@ 2019-07-22 16:42     ` Chris Wilson
  0 siblings, 0 replies; 32+ messages in thread
From: Chris Wilson @ 2019-07-22 16:42 UTC (permalink / raw)
  To: Tvrtko Ursulin, intel-gfx

Quoting Tvrtko Ursulin (2019-07-22 17:14:23)
> 
> On 18/07/2019 08:00, Chris Wilson wrote:
> > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> > index 884dfc1cb033..aceb990ae3b9 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> > @@ -3253,6 +3253,8 @@ static void virtual_context_enter(struct intel_context *ce)
> >   
> >       for (n = 0; n < ve->num_siblings; n++)
> >               intel_engine_pm_get(ve->siblings[n]);
> > +
> > +     intel_timeline_enter(ce->ring->timeline);
> 
> Here we couldn't enter all sibling contexts instead? Would be a bit 
> wasteful I guess. And there must be a place where it is already done. 
> But can't be on picking the engine, where is it?

There's only the one context (ring, and timeline).

> > +void intel_timeline_enter(struct intel_timeline *tl)
> > +{
> > +     struct intel_gt_timelines *timelines = &tl->gt->timelines;
> > +
> > +     GEM_BUG_ON(!tl->pin_count);
> > +     if (tl->active_count++)
> > +             return;
> > +     GEM_BUG_ON(!tl->active_count); /* overflow? */
> > +
> > +     mutex_lock(&timelines->mutex);
> > +     list_add(&tl->link, &timelines->active_list);
> > +     mutex_unlock(&timelines->mutex);
> > +}
> > +
> > +void intel_timeline_exit(struct intel_timeline *tl)
> > +{
> > +     struct intel_gt_timelines *timelines = &tl->gt->timelines;
> > +
> > +     GEM_BUG_ON(!tl->active_count);
> > +     if (--tl->active_count)
> > +             return;
> > +
> > +     mutex_lock(&timelines->mutex);
> > +     list_del(&tl->link);
> > +     mutex_unlock(&timelines->mutex);
> 
> So we end up with one lock protecting tl->active_count and another for 
> the list of active timelines?

tl->active_count is local to the timeline
tl->link/ gt->timelines.active_list is on the GT.

So yes, we have separate locks so that we can submit to multiple
independent contexts and engines concurrently.

> > diff --git a/drivers/gpu/drm/i915/gt/intel_timeline_types.h b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
> > index 9a71aea7a338..b820ee76b7f5 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_timeline_types.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_timeline_types.h
> > @@ -58,6 +58,7 @@ struct intel_timeline {
> >        */
> >       struct i915_syncmap *sync;
> >   
> > +     unsigned int active_count;
> 
> Is it becoming non-obvious what is pin_count and what is active_count? I 
> suggest some comments dropped along the members here.

pin_count is for the pinning, and active_count is for activity :)
Thanks to the need for perma-pinned contexts, we have the two layers
where we would have hoped for one.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/20] drm/i915/gt: Provde a local intel_context.vm
  2019-07-22 16:28     ` Chris Wilson
@ 2019-07-23 13:44       ` Tvrtko Ursulin
  0 siblings, 0 replies; 32+ messages in thread
From: Tvrtko Ursulin @ 2019-07-23 13:44 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx


On 22/07/2019 17:28, Chris Wilson wrote:
> Quoting Tvrtko Ursulin (2019-07-22 13:33:14)
>>
>> On 18/07/2019 08:00, Chris Wilson wrote:
>>> @@ -1113,9 +1121,8 @@ static int set_ppgtt(struct drm_i915_file_private *file_priv,
>>>                                   set_ppgtt_barrier,
>>>                                   old);
>>>        if (err) {
>>> -             ctx->vm = old;
>>> -             ctx->desc_template = default_desc_template(ctx->i915, old);
>>> -             i915_vm_put(vm);
>>> +             i915_vm_put(__set_ppgtt(ctx, old));
>>> +             i915_vm_put(old);
>>
>> Shouldn't this still be i915_vm_out(vm), for the extra vm reference the
>> function did further up?
> 
> __set_ppgtt() returns the vm, so this is
> 	i915_vm_put(vm);
> 	i915_vm_put(old); /* since we just acquired a ref to old again */

get(old), put(vm), put(old) - okay, you seem to be right indeed.

Fix a typo in subject and:

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko

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

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

end of thread, other threads:[~2019-07-23 13:44 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20190718070024.21781-1-chris@chris-wilson.co.uk>
2019-07-18  7:00 ` [PATCH 02/20] drm/i915/gt: Hook up intel_context_fini() Chris Wilson
2019-07-22 12:22   ` Tvrtko Ursulin
2019-07-18  7:00 ` [PATCH 04/20] drm/i915/execlists: Cancel breadcrumb on preempting the virtual engine Chris Wilson
2019-07-18  7:00 ` [PATCH 05/20] drm/i915: Hide unshrinkable context objects from the shrinker Chris Wilson
2019-07-18  7:00 ` [PATCH 06/20] drm/i915: Remove obsolete engine cleanup Chris Wilson
2019-07-22 12:46   ` Tvrtko Ursulin
2019-07-22 16:29     ` Chris Wilson
2019-07-18  7:00 ` [PATCH 07/20] drm/i915/gt: Move the [class][inst] lookup for engines onto the GT Chris Wilson
2019-07-18  7:00 ` [PATCH 09/20] drm/i915: Use intel_engine_lookup_user for probing HAS_BSD etc Chris Wilson
2019-07-22 12:49   ` Tvrtko Ursulin
2019-07-22 16:34     ` Chris Wilson
2019-07-18  7:00 ` [PATCH 11/20] drm/i915: Rely on spinlock protection for GPU error capture Chris Wilson
2019-07-22 13:40   ` Tvrtko Ursulin
2019-07-18  7:00 ` [PATCH 13/20] drm/i915: Teach execbuffer to take the engine wakeref not GT Chris Wilson
2019-07-22 16:03   ` Tvrtko Ursulin
2019-07-18  7:00 ` [PATCH 14/20] drm/i915/gt: Track timeline activeness in enter/exit Chris Wilson
2019-07-22 16:14   ` Tvrtko Ursulin
2019-07-22 16:42     ` Chris Wilson
2019-07-18  7:00 ` [PATCH 15/20] drm/i915/gt: Convert timeline tracking to spinlock Chris Wilson
2019-07-18  7:00 ` [PATCH 17/20] drm/i915/gt: Add to timeline requires the timeline mutex Chris Wilson
2019-07-18  7:00 ` [PATCH 18/20] drm/i915: Protect request retirement with timeline->mutex Chris Wilson
2019-07-18  7:00 ` [PATCH 20/20] drm/i915/gt: Mark context->active_count as protected by timeline->mutex Chris Wilson
2019-07-18  7:16 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/20] drm/i915: Move aliasing_ppgtt underneath its i915_ggtt Patchwork
2019-07-18  7:25 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-07-18  7:48 ` ✓ Fi.CI.BAT: success " Patchwork
2019-07-18 10:05 ` ✓ Fi.CI.IGT: " Patchwork
     [not found] ` <20190718070024.21781-3-chris@chris-wilson.co.uk>
2019-07-22 12:33   ` [PATCH 03/20] drm/i915/gt: Provde a local intel_context.vm Tvrtko Ursulin
2019-07-22 16:28     ` Chris Wilson
2019-07-23 13:44       ` Tvrtko Ursulin
     [not found] ` <20190718070024.21781-10-chris@chris-wilson.co.uk>
2019-07-22 12:53   ` [PATCH 10/20] drm/i915: Isolate i915_getparam_ioctl() Tvrtko Ursulin
2019-07-22 16:04   ` Tvrtko Ursulin
2019-07-22 16:16     ` 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.