[PATCH 60/62] active-rings

Chris Wilson chris at chris-wilson.co.uk
Tue Feb 5 11:23:27 UTC 2019


---
 drivers/gpu/drm/i915/i915_drv.h               |  1 -
 drivers/gpu/drm/i915/i915_gem.c               |  2 -
 drivers/gpu/drm/i915/i915_gem_context.c       | 56 +++++++------------
 drivers/gpu/drm/i915/i915_request.c           | 33 ++++++++---
 drivers/gpu/drm/i915/intel_ringbuffer.h       |  1 -
 .../gpu/drm/i915/selftests/mock_gem_device.c  |  1 -
 6 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d0f48cd8ada8..121199c3c749 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1981,7 +1981,6 @@ struct drm_i915_private {
 			struct list_head hwsp_free_list;
 		} timelines;
 
-		struct list_head active_rings;
 		struct list_head closed_vma;
 		unsigned long active_engines;
 		unsigned long idle_barriers;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index fdca0976f25a..c7c1c6276e1f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -110,7 +110,6 @@ static u32 __i915_gem_park(struct drm_i915_private *i915)
 	lockdep_assert_held(&i915->drm.struct_mutex);
 	GEM_BUG_ON(i915->gt.active_requests);
 	GEM_BUG_ON(i915->gt.idle_barriers);
-	GEM_BUG_ON(!list_empty(&i915->gt.active_rings));
 
 	if (!i915->gt.awake)
 		return I915_EPOCH_INVALID;
@@ -5169,7 +5168,6 @@ int i915_gem_init_early(struct drm_i915_private *dev_priv)
 	if (!dev_priv->luts)
 		goto err_vmas;
 
-	INIT_LIST_HEAD(&dev_priv->gt.active_rings);
 	INIT_LIST_HEAD(&dev_priv->gt.closed_vma);
 
 	i915_gem_init__mm(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5aa4ea3e90f1..a8ed221bc878 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -804,27 +804,6 @@ int i915_gem_vm_destroy_ioctl(struct drm_device *dev, void *data,
 	return 0;
 }
 
-static struct i915_request *
-last_request_on_engine(struct i915_timeline *timeline,
-		       struct intel_engine_cs *engine)
-{
-	struct i915_request *rq;
-
-	GEM_BUG_ON(timeline == &engine->timeline);
-
-	rq = i915_active_request_raw(&timeline->last_request,
-				     &engine->i915->drm.struct_mutex);
-	if (rq && rq->engine->mask & engine->mask) {
-		GEM_TRACE("last request for %s on engine %s: %llx:%llu\n",
-			  timeline->name, engine->name,
-			  rq->fence.context, rq->fence.seqno);
-		GEM_BUG_ON(rq->timeline != timeline);
-		return rq;
-	}
-
-	return NULL;
-}
-
 struct context_barrier_task {
 	struct i915_active base;
 	void (*task)(void *data);
@@ -902,10 +881,9 @@ static int context_barrier_task(struct i915_gem_context *ctx,
 int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915,
 				      unsigned long mask)
 {
+	struct i915_gt_timelines *gt = &i915->gt.timelines;
 	struct intel_engine_cs *engine;
 
-	GEM_TRACE("awake?=%s\n", yesno(i915->gt.awake));
-
 	lockdep_assert_held(&i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915->kernel_context);
 
@@ -914,7 +892,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915,
 		return 0;
 
 	for_each_engine_masked(engine, i915, mask, mask) {
-		struct intel_ring *ring;
+		struct i915_timeline *tl;
 		struct i915_request *rq;
 
 		GEM_BUG_ON(!to_intel_context(i915->kernel_context, engine));
@@ -924,23 +902,31 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915,
 			return PTR_ERR(rq);
 
 		/* Queue this switch after all other activity */
-		list_for_each_entry(ring, &i915->gt.active_rings, active_link) {
+		mutex_lock(&gt->mutex);
+		list_for_each_entry(tl, &gt->active_list, link) {
 			struct i915_request *prev;
+			int err;
 
-			prev = last_request_on_engine(ring->timeline, engine);
-			if (!prev)
+			if (tl == rq->timeline)
 				continue;
 
-			if (prev->gem_context == i915->kernel_context)
+			prev = i915_active_request_raw(&tl->last_request,
+						       &i915->drm.struct_mutex);
+			if (!prev || (prev->engine->mask & engine->mask) == 0)
 				continue;
 
-			GEM_TRACE("add barrier on %s for %llx:%lld\n",
-				  engine->name,
-				  prev->fence.context,
-				  prev->fence.seqno);
-			i915_sw_fence_await_sw_fence_gfp(&rq->submit,
-							 &prev->submit,
-							 I915_FENCE_GFP);
+			if (prev == rq)
+				continue;
+
+			mutex_unlock(&gt->mutex);
+			err = i915_active_request_set(&tl->last_request, rq);
+			if (err) {
+				i915_request_add(rq);
+				return err;
+			}
+
+			mutex_lock(&gt->mutex);
+			tl = list_entry(&gt->active_list, typeof(*tl), link);
 		}
 
 		i915_request_add_barriers(rq);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 4edfa36c6d36..6ac14194d4c8 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -169,7 +169,6 @@ static void advance_ring(struct i915_request *request)
 		 */
 		GEM_TRACE("marking %s as inactive\n", ring->timeline->name);
 		tail = READ_ONCE(request->tail);
-		list_del(&ring->active_link);
 	} else {
 		tail = request->postfix;
 	}
@@ -1073,10 +1072,6 @@ void i915_request_add(struct i915_request *request)
 	__i915_active_request_set(&timeline->last_request, request);
 
 	list_add_tail(&request->ring_link, &ring->request_list);
-	if (list_is_first(&request->ring_link, &ring->request_list)) {
-		GEM_TRACE("marking %s as active\n", ring->timeline->name);
-		list_add(&ring->active_link, &request->i915->gt.active_rings);
-	}
 	request->i915->gt.active_engines |= request->engine->mask;
 	request->emitted_jiffies = jiffies;
 
@@ -1348,15 +1343,37 @@ long i915_request_wait(struct i915_request *rq,
 
 void i915_retire_requests(struct drm_i915_private *i915)
 {
-	struct intel_ring *ring, *tmp;
+	struct i915_gt_timelines *gt = &i915->gt.timelines;
+	struct i915_timeline *tl;
 
 	lockdep_assert_held(&i915->drm.struct_mutex);
 
 	if (!i915->gt.active_requests)
 		return;
 
-	list_for_each_entry_safe(ring, tmp, &i915->gt.active_rings, active_link)
-		ring_retire_requests(ring);
+	mutex_lock(&gt->mutex);
+	list_for_each_entry(tl, &gt->active_list, link) {
+		struct i915_request *rq, *rn;
+		struct list_head retire, *it;
+
+		list_for_each(it, &tl->requests) {
+			rq = list_entry(it, typeof(*rq), link);
+			if (!i915_request_completed(rq))
+				break;
+		}
+		if (it == tl->requests.next)
+			continue;
+
+		list_cut_before(&retire, &tl->requests, it);
+		mutex_unlock(&gt->mutex);
+
+		list_for_each_entry_safe(rq, rn, &retire, link)
+			i915_request_retire(rq);
+
+		mutex_lock(&gt->mutex);
+		tl = list_entry(&gt->active_list, typeof(*tl), link);
+	}
+	mutex_unlock(&gt->mutex);
 }
 
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 6a030a538e5d..c901328f7994 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -132,7 +132,6 @@ struct intel_ring {
 
 	struct i915_timeline *timeline;
 	struct list_head request_list;
-	struct list_head active_link;
 
 	u32 head;
 	u32 tail;
diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
index be5e871be26b..38487f37708e 100644
--- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c
+++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c
@@ -213,7 +213,6 @@ struct drm_i915_private *mock_gem_device(void)
 
 	i915_timelines_init(i915);
 
-	INIT_LIST_HEAD(&i915->gt.active_rings);
 	INIT_LIST_HEAD(&i915->gt.closed_vma);
 
 	mutex_lock(&i915->drm.struct_mutex);
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list