[PATCH 33/35] cref

Chris Wilson chris at chris-wilson.co.uk
Mon Mar 11 00:52:57 UTC 2019


---
 drivers/gpu/drm/i915/gem/i915_gem_context.c  |  2 +-
 drivers/gpu/drm/i915/intel_context.c         |  8 +++--
 drivers/gpu/drm/i915/intel_context.h         | 11 +++++++
 drivers/gpu/drm/i915/intel_context_types.h   |  6 +++-
 drivers/gpu/drm/i915/intel_lrc.c             | 31 ++++++++++----------
 drivers/gpu/drm/i915/intel_ringbuffer.c      |  7 ++++-
 drivers/gpu/drm/i915/selftests/mock_engine.c |  7 ++++-
 7 files changed, 50 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 96284c745c41..e3bdf401cb03 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -243,7 +243,7 @@ static void i915_gem_context_free(struct i915_gem_context *ctx)
 	free_engines(ctx->engines, ctx->nengine);
 
 	rbtree_postorder_for_each_entry_safe(it, n, &ctx->hw_contexts, node)
-		it->ops->destroy(it);
+		intel_context_put(it);
 
 	if (ctx->timeline)
 		i915_timeline_put(ctx->timeline);
diff --git a/drivers/gpu/drm/i915/intel_context.c b/drivers/gpu/drm/i915/intel_context.c
index a8588986406b..ce1200b2e4b9 100644
--- a/drivers/gpu/drm/i915/intel_context.c
+++ b/drivers/gpu/drm/i915/intel_context.c
@@ -210,7 +210,7 @@ void intel_context_retire(struct i915_active *active)
 		i915_vma_unpin(ce->state);
 	}
 
-	i915_gem_context_put(ce->gem_context);
+	intel_context_put(ce);
 }
 
 void
@@ -218,6 +218,8 @@ intel_context_init(struct intel_context *ce,
 		   struct i915_gem_context *ctx,
 		   struct intel_engine_cs *engine)
 {
+	kref_init(&ce->ref);
+
 	ce->gem_context = ctx;
 	ce->engine = engine;
 	ce->ops = engine->cops;
@@ -270,7 +272,7 @@ int intel_context_active(struct intel_context *ce, unsigned long flags)
 		return 0;
 
 	if (!ce->state)
-		return 0;
+		goto out;
 
 	err = __context_pin_state(ce->state, flags);
 	if (err) {
@@ -287,6 +289,8 @@ int intel_context_active(struct intel_context *ce, unsigned long flags)
 		}
 	}
 
+out:
+	kref_get(&ce->ref);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_context.h b/drivers/gpu/drm/i915/intel_context.h
index d5ead6f319a6..b913cc266a48 100644
--- a/drivers/gpu/drm/i915/intel_context.h
+++ b/drivers/gpu/drm/i915/intel_context.h
@@ -77,4 +77,15 @@ int intel_context_active(struct intel_context *ce, unsigned long flags);
 void intel_context_inactive(struct intel_context *ce);
 void intel_context_retire(struct i915_active *active);
 
+static inline struct intel_context *intel_context_get(struct intel_context *ce)
+{
+	kref_get(&ce->ref);
+	return ce;
+}
+
+static inline void intel_context_put(struct intel_context *ce)
+{
+	kref_put(&ce->ref, ce->ops->destroy);
+}
+
 #endif /* __INTEL_CONTEXT_H__ */
diff --git a/drivers/gpu/drm/i915/intel_context_types.h b/drivers/gpu/drm/i915/intel_context_types.h
index b46dc0d31ca4..5c999338bcd5 100644
--- a/drivers/gpu/drm/i915/intel_context_types.h
+++ b/drivers/gpu/drm/i915/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/rbtree.h>
@@ -22,7 +23,8 @@ struct intel_ring;
 struct intel_context_ops {
 	int (*pin)(struct intel_context *ce);
 	void (*unpin)(struct intel_context *ce);
-	void (*destroy)(struct intel_context *ce);
+
+	void (*destroy)(struct kref *kref);
 };
 
 /*
@@ -36,6 +38,8 @@ struct intel_sseu {
 };
 
 struct intel_context {
+	struct kref ref;
+
 	struct i915_gem_context *gem_context;
 	struct intel_engine_cs *engine;
 	struct intel_engine_cs *inflight;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index db1a2a0c19bb..03667039ebfb 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -173,7 +173,6 @@ struct virtual_engine {
 	struct intel_engine_cs base;
 
 	struct intel_context context;
-	struct kref kref;
 	struct rcu_head rcu;
 
 	struct i915_request *request;
@@ -1439,8 +1438,10 @@ static void __execlists_context_fini(struct intel_context *ce)
 	i915_gem_object_put(ce->state->obj);
 }
 
-static void execlists_context_destroy(struct intel_context *ce)
+static void execlists_context_destroy(struct kref *kref)
 {
+	struct intel_context *ce = container_of(kref, typeof(*ce), ref);
+
 	GEM_BUG_ON(intel_context_is_pinned(ce));
 
 	if (ce->state)
@@ -1457,7 +1458,10 @@ static void execlists_context_unpin(struct intel_context *ce)
 
 	i915_gem_object_unpin_map(ce->state->obj);
 
+	mutex_lock(&ce->gem_context->mutex);
 	list_del(&ce->active_link);
+	mutex_unlock(&ce->gem_context->mutex);
+	i915_gem_context_put(ce->gem_context);
 
 	intel_context_inactive(ce);
 }
@@ -3070,9 +3074,10 @@ static void __virtual_engine_free(struct rcu_head *rcu)
 	kfree(ve);
 }
 
-static void virtual_engine_free(struct kref *kref)
+static void virtual_engine_destroy(struct kref *kref)
 {
-	struct virtual_engine *ve = container_of(kref, typeof(*ve), kref);
+	struct virtual_engine *ve =
+		container_of(kref, typeof(*ve), context.ref);
 	unsigned int n;
 
 	GEM_BUG_ON(ve->request);
@@ -3106,7 +3111,6 @@ static void virtual_context_retire(struct i915_active *ref)
 		container_of(ref, typeof(*ve), context.active);
 
 	intel_context_retire(ref);
-	kref_put(&ve->kref, virtual_engine_free);
 }
 
 static void virtual_context_unpin(struct intel_context *ce)
@@ -3147,15 +3151,10 @@ static int virtual_context_pin(struct intel_context *ce)
 	struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
 	int err;
 
-	if (i915_active_is_idle(&ce->active))
-		kref_get(&ve->kref);
-
 	/* Note: we must use a real engine class for setting up reg state */
 	err = __execlists_context_pin(ce, ve->siblings[0]);
-	if (err) {
-		kref_put(&ve->kref, virtual_engine_free);
+	if (err)
 		return err;
-	}
 
 	virtual_engine_initial_hint(ve);
 
@@ -3165,6 +3164,8 @@ static int virtual_context_pin(struct intel_context *ce)
 static const struct intel_context_ops virtual_context_ops = {
 	.pin = virtual_context_pin,
 	.unpin = virtual_context_unpin,
+
+	.destroy = virtual_engine_destroy,
 };
 
 static void virtual_submission_tasklet(unsigned long data)
@@ -3300,7 +3301,6 @@ intel_execlists_create_virtual(struct i915_gem_context *ctx,
 	if (!ve)
 		return ERR_PTR(-ENOMEM);
 
-	kref_init(&ve->kref);
 	rcu_head_init(&ve->rcu);
 	ve->base.i915 = ctx->i915;
 	ve->base.id = -1;
@@ -3370,7 +3370,7 @@ intel_execlists_create_virtual(struct i915_gem_context *ctx,
 	/* gracefully replace a degenerate virtual engine */
 	if (is_power_of_2(ve->base.mask)) {
 		struct intel_engine_cs *actual = ve->siblings[0];
-		virtual_engine_free(&ve->kref);
+		intel_context_put(&ve->context);
 		return actual;
 	}
 
@@ -3378,7 +3378,7 @@ intel_execlists_create_virtual(struct i915_gem_context *ctx,
 	return &ve->base;
 
 err_put:
-	virtual_engine_free(&ve->kref);
+	intel_context_put(&ve->context);
 	return ERR_PTR(err);
 }
 
@@ -3467,8 +3467,7 @@ void intel_virtual_engine_destroy(struct intel_engine_cs *engine)
 		return;
 
 	__intel_context_remove(&ve->context);
-
-	kref_put(&ve->kref, virtual_engine_free);
+	intel_context_put(&ve->context);
 }
 
 void intel_execlists_show_requests(struct intel_engine_cs *engine,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index b9a5f48a45c6..a7785c8caebe 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1351,8 +1351,10 @@ static void __ring_context_fini(struct intel_context *ce)
 	i915_gem_object_put(ce->state->obj);
 }
 
-static void ring_context_destroy(struct intel_context *ce)
+static void ring_context_destroy(struct kref *ref)
 {
+	struct intel_context *ce = container_of(ref, typeof(*ce), ref);
+
 	GEM_BUG_ON(intel_context_is_pinned(ce));
 
 	if (ce->state)
@@ -1386,7 +1388,10 @@ static void ring_context_unpin(struct intel_context *ce)
 {
 	__context_unpin_ppgtt(ce->gem_context);
 
+	mutex_lock(&ce->gem_context->mutex);
 	list_del(&ce->active_link);
+	mutex_unlock(&ce->gem_context->mutex);
+	i915_gem_context_put(ce->gem_context);
 
 	intel_context_inactive(ce);
 }
diff --git a/drivers/gpu/drm/i915/selftests/mock_engine.c b/drivers/gpu/drm/i915/selftests/mock_engine.c
index d5ec698674cd..d5cf1b1de288 100644
--- a/drivers/gpu/drm/i915/selftests/mock_engine.c
+++ b/drivers/gpu/drm/i915/selftests/mock_engine.c
@@ -131,12 +131,16 @@ static void mock_context_unpin(struct intel_context *ce)
 	i915_gem_context_put(ce->gem_context);
 }
 
-static void mock_context_destroy(struct intel_context *ce)
+static void mock_context_destroy(struct kref *ref)
 {
+	struct intel_context *ce = container_of(ref, typeof(*ce), ref);
+
 	GEM_BUG_ON(intel_context_is_pinned(ce));
 
 	if (ce->ring)
 		mock_ring_free(ce->ring);
+
+	intel_context_free(ce);
 }
 
 static int mock_context_pin(struct intel_context *ce)
@@ -154,6 +158,7 @@ static int mock_context_pin(struct intel_context *ce)
 static const struct intel_context_ops mock_context_ops = {
 	.pin = mock_context_pin,
 	.unpin = mock_context_unpin,
+
 	.destroy = mock_context_destroy,
 };
 
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list