[PATCH 46/54] context-barrier-task

Chris Wilson chris at chris-wilson.co.uk
Mon Jan 28 00:12:14 UTC 2019


---
 drivers/gpu/drm/i915/i915_gem_context.c | 76 +++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_lrc.c        |  4 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c |  5 +-
 3 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index ef726a3bfb49..375c8a8f222e 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -685,6 +685,82 @@ last_request_on_engine(struct i915_timeline *timeline,
 	return NULL;
 }
 
+struct context_barrier_task {
+	void (*func)(void *data);
+	void *data;
+
+	unsigned int count;
+	struct cb_active {
+		struct i915_active_request active;
+		struct context_barrier_task *cb;
+	} active[0];
+};
+
+static void
+cb_retire(struct i915_active_request *base, struct i915_request *rq)
+{
+	struct context_barrier_task *cb =
+		container_of(base, struct cb_active, active)->cb;
+
+	if (--cb->count)
+		return;
+
+	if (cb->func)
+		cb->func(cb->data);
+
+	kfree(cb);
+}
+
+static int context_barrier_task(struct i915_gem_context *ctx,
+				void (*func)(void *data),
+				void *data)
+{
+	struct drm_i915_private *i915 = ctx->i915;
+	struct context_barrier_task *cb;
+	struct intel_context *ce;
+	unsigned int count;
+
+	lockdep_assert_held(&i915->drm.struct_mutex);
+	GEM_BUG_ON(!func);
+
+	count = 0;
+	list_for_each_entry(ce, &ctx->active_engines, active_link)
+		count++;
+	if (!count) {
+		func(data);
+		return 0;
+	}
+
+	cb = kmalloc(sizeof(*cb) + count * sizeof(cb->active[0]), GFP_KERNEL);
+	if (!cb)
+		return -ENOMEM;
+
+	cb->func = func;
+	cb->data = data;
+	cb->count = 0;
+
+	list_for_each_entry(ce, &ctx->active_engines, active_link) {
+		struct intel_engine_cs *engine = ce->engine;
+		struct cb_active *active;
+		struct i915_request *rq;
+
+		rq = i915_request_alloc(engine, ctx);
+		if (IS_ERR(rq)) {
+			cb->func = NULL;
+			return PTR_ERR(rq);
+		}
+
+		active = &cb->active[cb->count++];
+		i915_active_request_init(&active->active, rq, cb_retire);
+		active->cb = cb;
+
+		i915_request_add(rq);
+	}
+	GEM_BUG_ON(cb->count != count);
+
+	return 0;
+}
+
 int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915)
 {
 	struct intel_engine_cs *engine;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 18a08b528be3..2debd5bf20b4 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1272,7 +1272,6 @@ static void execlists_context_unpin(struct intel_context *ce)
 		GEM_BUG_ON(READ_ONCE(ce->active));
 	}
 
-	list_del(&ce->active_link);
 	i915_gem_context_unpin_hw_id(ce->gem_context);
 
 	intel_ring_unpin(ce->ring);
@@ -1281,6 +1280,7 @@ static void execlists_context_unpin(struct intel_context *ce)
 	i915_gem_object_unpin_map(ce->state->obj);
 	i915_vma_unpin(ce->state);
 
+	list_del(&ce->active_link);
 	i915_gem_context_put(ce->gem_context);
 }
 
@@ -1364,9 +1364,9 @@ __execlists_context_pin(struct intel_engine_cs *engine,
 
 	__execlists_update_reg_state(engine, ce);
 
-	list_add(&ce->active_link, &ctx->active_engines);
 	ce->state->obj->pin_global++;
 	i915_gem_context_get(ctx);
+	list_add(&ce->active_link, &ctx->active_engines);
 	return ce;
 
 unpin_ring:
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 48dfca8aefa8..5ee7c51407c1 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1414,8 +1414,6 @@ static void __context_unpin(struct intel_context *ce)
 {
 	struct i915_vma *vma;
 
-	list_del(&ce->active_link);
-
 	vma = ce->state;
 	if (!vma)
 		return;
@@ -1429,6 +1427,7 @@ static void intel_ring_context_unpin(struct intel_context *ce)
 	__context_unpin_ppgtt(ce->gem_context);
 	__context_unpin(ce);
 
+	list_del(&ce->active_link);
 	i915_gem_context_put(ce->gem_context);
 }
 
@@ -1528,8 +1527,8 @@ __ring_context_pin(struct intel_engine_cs *engine,
 	if (err)
 		goto err_unpin;
 
-	list_add(&ce->active_link, &ctx->active_engines);
 	i915_gem_context_get(ctx);
+	list_add(&ce->active_link, &ctx->active_engines);
 
 	/* One ringbuffer to rule them all */
 	GEM_BUG_ON(!engine->buffer);
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list