[Intel-gfx] [RFC 07/10] drm/i915: Track latest request per engine class

Tvrtko Ursulin tursulin at ursulin.net
Thu Jan 25 13:33:30 UTC 2018


From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>

We add a per-context, per-engine-class timeline so we are later able to
implement a virtual engine by creating implicit dependencies between
requests submitted to the same engine class.

v2: Rebase.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h          |  6 ++++++
 drivers/gpu/drm/i915/i915_gem_request.c  | 13 +++++++++++++
 drivers/gpu/drm/i915/i915_gem_request.h  |  2 ++
 drivers/gpu/drm/i915/i915_gem_timeline.c | 12 ++++++++++++
 drivers/gpu/drm/i915/i915_gem_timeline.h |  2 ++
 5 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0c348f6ab386..d20c6c542c2d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3449,6 +3449,12 @@ i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
 	return ctx;
 }
 
+static inline struct intel_timeline *
+i915_gem_context_lookup_timeline_class(struct i915_gem_context *ctx, u8 class)
+{
+	return &ctx->timeline->class[class];
+}
+
 int i915_perf_open_ioctl(struct drm_device *dev, void *data,
 			 struct drm_file *file);
 int i915_perf_add_config_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index 160d81bf6d85..85da7f7eee03 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -380,6 +380,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
 {
 	struct intel_engine_cs *engine = request->engine;
 	struct i915_gem_active *active, *next;
+	struct intel_timeline *timeline;
 
 	lockdep_assert_held(&request->i915->drm.struct_mutex);
 	GEM_BUG_ON(!i915_sw_fence_signaled(&request->submit));
@@ -392,6 +393,12 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
 	list_del_init(&request->link);
 	spin_unlock_irq(&engine->timeline->lock);
 
+	timeline = i915_gem_context_lookup_timeline_class(request->ctx,
+							  engine->class);
+	spin_lock_irq(&timeline->lock);
+	list_del(&request->ctx_link);
+	spin_unlock_irq(&timeline->lock);
+
 	unreserve_engine(request->engine);
 	advance_ring(request);
 
@@ -1054,6 +1061,12 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
 	GEM_BUG_ON(timeline->seqno != request->fence.seqno);
 	i915_gem_active_set(&timeline->last_request, request);
 
+	timeline = i915_gem_context_lookup_timeline_class(request->ctx,
+							  engine->class);
+	spin_lock_irq(&timeline->lock);
+	list_add(&request->ctx_link, &timeline->requests);
+	spin_unlock_irq(&timeline->lock);
+
 	list_add_tail(&request->ring_link, &ring->request_list);
 	request->emitted_jiffies = jiffies;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 2236e9188c5c..f8915ff3d62a 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -196,6 +196,8 @@ struct drm_i915_gem_request {
 	/** engine->request_list entry for this request */
 	struct list_head link;
 
+	struct list_head ctx_link;
+
 	/** ring->request_list entry for this request */
 	struct list_head ring_link;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.c b/drivers/gpu/drm/i915/i915_gem_timeline.c
index 1bf48bdb78c4..902eb92b8883 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.c
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.c
@@ -75,6 +75,10 @@ static int __i915_gem_timeline_init(struct drm_i915_private *i915,
 
 	/* Called during early_init before we know how many engines there are */
 	fences = dma_fence_context_alloc(ARRAY_SIZE(timeline->engine));
+	for (i = 0; i < ARRAY_SIZE(timeline->class); i++)
+		__intel_timeline_init(&timeline->class[i],
+				      timeline, fences++,
+				      lockclass, lockname);
 	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
 		__intel_timeline_init(&timeline->engine[i],
 				      timeline, fences++,
@@ -137,6 +141,11 @@ void i915_gem_timelines_park(struct drm_i915_private *i915)
 	lockdep_assert_held(&i915->drm.struct_mutex);
 
 	list_for_each_entry(timeline, &i915->gt.timelines, link) {
+		for (i = 0; i < ARRAY_SIZE(timeline->class); i++) {
+			struct intel_timeline *tl = &timeline->class[i];
+
+			i915_syncmap_free(&tl->sync);
+		}
 		for (i = 0; i < ARRAY_SIZE(timeline->engine); i++) {
 			struct intel_timeline *tl = &timeline->engine[i];
 
@@ -157,6 +166,9 @@ void i915_gem_timeline_fini(struct i915_gem_timeline *timeline)
 
 	lockdep_assert_held(&timeline->i915->drm.struct_mutex);
 
+	for (i = 0; i < ARRAY_SIZE(timeline->class); i++)
+		__intel_timeline_fini(&timeline->class[i]);
+
 	for (i = 0; i < ARRAY_SIZE(timeline->engine); i++)
 		__intel_timeline_fini(&timeline->engine[i]);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_timeline.h b/drivers/gpu/drm/i915/i915_gem_timeline.h
index 7ecf0a253d78..f625ef2ad14e 100644
--- a/drivers/gpu/drm/i915/i915_gem_timeline.h
+++ b/drivers/gpu/drm/i915/i915_gem_timeline.h
@@ -30,6 +30,7 @@
 #include "i915_utils.h"
 #include "i915_gem_request.h"
 #include "i915_syncmap.h"
+#include "i915_reg.h"
 
 struct i915_gem_timeline;
 
@@ -86,6 +87,7 @@ struct i915_gem_timeline {
 	struct drm_i915_private *i915;
 	const char *name;
 
+	struct intel_timeline class[MAX_ENGINE_CLASS];
 	struct intel_timeline engine[I915_NUM_ENGINES];
 };
 
-- 
2.14.1



More information about the Intel-gfx mailing list