[PATCH 14/15] drm/i915: Keep contexts pinned during lifetime of the context.

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Thu Aug 5 09:16:51 UTC 2021


Remove pinning contexts from execbuf, and keep them pinnned for the
lifetime of the context. It's hard to evict contexts anyway.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 49 ++++++++++++++++++-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   | 19 +------
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 19 -------
 drivers/gpu/drm/i915/gt/intel_context_types.h |  1 +
 4 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index cff72679ad7c..07b0954068b0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -136,6 +136,50 @@ static void lut_close(struct i915_gem_context *ctx)
 	mutex_unlock(&ctx->lut_mutex);
 }
 
+static inline struct intel_context *
+__i915_gem_context_get_engine(struct i915_gem_context *ctx, unsigned int idx)
+{
+	struct intel_context *ce;
+
+	rcu_read_lock(); {
+		struct i915_gem_engines *e = rcu_dereference(ctx->engines);
+		if (unlikely(!e)) /* context was closed! */
+			ce = ERR_PTR(-ENOENT);
+		else if (likely(idx < e->num_engines && e->engines[idx]))
+			ce = intel_context_get(e->engines[idx]);
+		else
+			ce = ERR_PTR(-EINVAL);
+	} rcu_read_unlock();
+
+	return ce;
+}
+
+struct intel_context *
+i915_gem_context_get_engine(struct i915_gem_context *ctx, unsigned int idx)
+{
+	struct intel_context *ce = __i915_gem_context_get_engine(ctx, idx);
+	int err;
+
+	if (IS_ERR(ce))
+		return ce;
+
+	if (test_bit(CONTEXT_GEM_PIN_BIT, &ce->flags))
+		return ce;
+
+	err = intel_context_alloc_state(ce);
+	if (err)
+		return ERR_PTR(err);
+
+	err = intel_context_pin(ce);
+	if (err)
+		return ERR_PTR(err);
+
+	if (test_and_set_bit(CONTEXT_GEM_PIN_BIT, &ce->flags))
+		intel_context_unpin(ce);
+
+	return ce;
+}
+
 static struct intel_context *
 lookup_user_engine(struct i915_gem_context *ctx,
 		   unsigned long flags,
@@ -161,7 +205,7 @@ lookup_user_engine(struct i915_gem_context *ctx,
 		idx = ci->engine_instance;
 	}
 
-	return i915_gem_context_get_engine(ctx, idx);
+	return __i915_gem_context_get_engine(ctx, idx);
 }
 
 static int validate_priority(struct drm_i915_private *i915,
@@ -820,6 +864,9 @@ static void __free_engines(struct i915_gem_engines *e, unsigned int count)
 		if (!e->engines[count])
 			continue;
 
+		if (test_bit(CONTEXT_GEM_PIN_BIT, &e->engines[count]->flags))
+			intel_context_unpin(e->engines[count]);
+
 		intel_context_put(e->engines[count]);
 	}
 	kfree(e);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 18060536b0c2..9529b9df1ff3 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -191,23 +191,8 @@ i915_gem_context_unlock_engines(struct i915_gem_context *ctx)
 	mutex_unlock(&ctx->engines_mutex);
 }
 
-static inline struct intel_context *
-i915_gem_context_get_engine(struct i915_gem_context *ctx, unsigned int idx)
-{
-	struct intel_context *ce;
-
-	rcu_read_lock(); {
-		struct i915_gem_engines *e = rcu_dereference(ctx->engines);
-		if (unlikely(!e)) /* context was closed! */
-			ce = ERR_PTR(-ENOENT);
-		else if (likely(idx < e->num_engines && e->engines[idx]))
-			ce = intel_context_get(e->engines[idx]);
-		else
-			ce = ERR_PTR(-EINVAL);
-	} rcu_read_unlock();
-
-	return ce;
-}
+struct intel_context *
+i915_gem_context_get_engine(struct i915_gem_context *ctx, unsigned int idx);
 
 static inline void
 i915_gem_engines_iter_init(struct i915_gem_engines_iter *it,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 6832b255294e..02038b413b51 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2280,22 +2280,12 @@ static struct i915_request *eb_pin_engine(struct i915_execbuffer *eb, bool throt
 	struct intel_context *ce = eb->context;
 	struct intel_timeline *tl;
 	struct i915_request *rq = NULL;
-	int err;
 
 	GEM_BUG_ON(eb->args->flags & __EXEC_ENGINE_PINNED);
 
 	if (unlikely(intel_context_is_banned(ce)))
 		return ERR_PTR(-EIO);
 
-	/*
-	 * Pinning the contexts may generate requests in order to acquire
-	 * GGTT space, so do this first before we reserve a seqno for
-	 * ourselves.
-	 */
-	err = intel_context_pin_ww(ce, &eb->ww);
-	if (err)
-		return ERR_PTR(err);
-
 	/*
 	 * Take a local wakeref for preparing to dispatch the execbuf as
 	 * we expect to access the hardware fairly frequently in the
@@ -2306,7 +2296,6 @@ static struct i915_request *eb_pin_engine(struct i915_execbuffer *eb, bool throt
 	 */
 	tl = intel_context_timeline_lock(ce);
 	if (IS_ERR(tl)) {
-		intel_context_unpin(ce);
 		return ERR_CAST(tl);
 	}
 
@@ -2332,8 +2321,6 @@ static void eb_unpin_engine(struct i915_execbuffer *eb)
 	mutex_lock(&tl->mutex);
 	intel_context_exit(ce);
 	mutex_unlock(&tl->mutex);
-
-	intel_context_unpin(ce);
 }
 
 static unsigned int
@@ -2397,12 +2384,6 @@ eb_select_engine(struct i915_execbuffer *eb)
 
 	intel_gt_pm_get(ce->engine->gt);
 
-	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
-		err = intel_context_alloc_state(ce);
-		if (err)
-			goto err;
-	}
-
 	/*
 	 * ABI: Before userspace accesses the GPU (e.g. execbuffer), report
 	 * EIO if the GPU is already wedged.
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h
index e54351a170e2..b4486308128a 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -112,6 +112,7 @@ struct intel_context {
 #define CONTEXT_FORCE_SINGLE_SUBMISSION	7
 #define CONTEXT_NOPREEMPT		8
 #define CONTEXT_LRCA_DIRTY		9
+#define CONTEXT_GEM_PIN_BIT		10
 
 	struct {
 		u64 timeout_us;
-- 
2.32.0



More information about the Intel-gfx-trybot mailing list