[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