[PATCH 1/2] rq queued/runnable hack

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Thu Apr 16 12:14:50 UTC 2020


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

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  7 ++++
 drivers/gpu/drm/i915/gem/i915_gem_context.h   | 40 +++++++++++++++++++
 .../gpu/drm/i915/gem/i915_gem_context_types.h |  3 ++
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  2 +
 drivers/gpu/drm/i915/gt/intel_lrc.c           | 14 ++++++-
 drivers/gpu/drm/i915/gt/intel_reset.c         |  5 +++
 drivers/gpu/drm/i915/i915_request.c           | 12 ++++++
 7 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 11d9135cf21a..d0e0dbc82b21 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -730,6 +730,13 @@ __create_context(struct drm_i915_private *i915)
 
 	INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
 
+	BUILD_BUG_ON(ARRAY_SIZE(ctx->rq_queued) !=
+		     ARRAY_SIZE(ctx->rq_runnable));
+	for (i = 0; i < ARRAY_SIZE(ctx->rq_queued); i++) {
+		atomic_set(&ctx->rq_queued[i], 0);
+		atomic_set(&ctx->rq_runnable[i], 0);
+	}
+
 	/* NB: Mark all slices as needing a remap so that when the context first
 	 * loads it will restore whatever remap state already exists. If there
 	 * is no remap info, it will be a NOP. */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 3702b2fb27ab..6c3a57dd3c67 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -229,4 +229,44 @@ int i915_gem_user_to_context_sseu(struct drm_i915_private *i915,
 				  const struct drm_i915_gem_context_param_sseu *user,
 				  struct intel_sseu *context);
 
+static inline void
+i915_ctx_inc_runnable(struct i915_gem_context *ctx, unsigned int class)
+{
+	if (!ctx)
+		return;
+
+	GEM_BUG_ON(class >= ARRAY_SIZE(ctx->rq_runnable));
+	atomic_inc(&ctx->rq_runnable[class]);
+}
+
+static inline void
+i915_ctx_dec_runnable(struct i915_gem_context *ctx, unsigned int class)
+{
+	if (!ctx)
+		return;
+
+	GEM_BUG_ON(class >= ARRAY_SIZE(ctx->rq_runnable));
+	atomic_dec(&ctx->rq_runnable[class]);
+}
+
+static inline void
+i915_ctx_inc_queued(struct i915_gem_context *ctx, unsigned int class)
+{
+	if (!ctx)
+		return;
+
+	GEM_BUG_ON(class >= ARRAY_SIZE(ctx->rq_queued));
+	atomic_inc(&ctx->rq_queued[class]);
+}
+
+static inline void
+i915_ctx_dec_queued(struct i915_gem_context *ctx, unsigned int class)
+{
+	if (!ctx)
+		return;
+
+	GEM_BUG_ON(class >= ARRAY_SIZE(ctx->rq_queued));
+	atomic_dec(&ctx->rq_queued[class]);
+}
+
 #endif /* !__I915_GEM_CONTEXT_H__ */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
index 28760bd03265..6baeaae68dd6 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
@@ -126,6 +126,9 @@ struct i915_gem_context {
 	 */
 	struct rcu_head rcu;
 
+	atomic_t rq_queued[MAX_ENGINE_CLASS + 1];
+	atomic_t rq_runnable[MAX_ENGINE_CLASS + 1];
+
 	/**
 	 * @user_flags: small set of booleans controlled by the user
 	 */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 517898aa634c..ef0c56e1801b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2434,6 +2434,8 @@ static void eb_request_add(struct i915_execbuffer *eb)
 
 	__i915_request_queue(rq, &attr);
 
+	i915_ctx_inc_queued(eb->gem_context, rq->engine->class);
+
 	/* Try to clean up the client's timeline after submitting the request */
 	if (prev)
 		retire_requests(tl, prev);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 6fbad5e2343f..0cd56effc1e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -134,6 +134,7 @@
 #include <linux/interrupt.h>
 
 #include "i915_drv.h"
+#include "gem/i915_gem_context.h"
 #include "i915_perf.h"
 #include "i915_trace.h"
 #include "i915_vgpu.h"
@@ -3047,9 +3048,14 @@ static void __submit_queue_imm(struct intel_engine_cs *engine)
 }
 
 static void submit_queue(struct intel_engine_cs *engine,
-			 const struct i915_request *rq)
+			 struct i915_request *rq)
 {
 	struct intel_engine_execlists *execlists = &engine->execlists;
+	struct i915_gem_context *ctx = i915_request_gem_context(rq);
+	const unsigned int class = rq->engine->class;
+
+	i915_ctx_dec_queued(ctx, class);
+	i915_ctx_inc_runnable(ctx, class);
 
 	if (rq_prio(rq) <= execlists->queue_priority_hint)
 		return;
@@ -5177,6 +5183,12 @@ static void virtual_submit_request(struct i915_request *rq)
 		ve->base.execlists.queue_priority_hint = INT_MIN;
 		ve->request = NULL;
 	} else {
+		struct i915_gem_context *ctx = i915_request_gem_context(rq);
+		const unsigned int class = rq->engine->class;
+
+		i915_ctx_dec_queued(ctx, class);
+		i915_ctx_inc_runnable(ctx, class);
+
 		ve->base.execlists.queue_priority_hint = rq_prio(rq);
 		ve->request = i915_request_get(rq);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c
index 39070b514e65..b2af32e21f0a 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -783,12 +783,17 @@ static void reset_finish(struct intel_gt *gt, intel_engine_mask_t awake)
 
 static void nop_submit_request(struct i915_request *request)
 {
+	struct i915_gem_context *ctx = i915_request_gem_context(request);
 	struct intel_engine_cs *engine = request->engine;
+	const unsigned int class = engine->class;
 	unsigned long flags;
 
 	RQ_TRACE(request, "-EIO\n");
 	i915_request_set_error_once(request, -EIO);
 
+	i915_ctx_dec_queued(ctx, class);
+	i915_ctx_inc_runnable(ctx, class);
+
 	spin_lock_irqsave(&engine->active.lock, flags);
 	__i915_request_submit(request);
 	i915_request_mark_complete(request);
diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index 22635bbabf06..66d84d693d16 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -418,6 +418,7 @@ void i915_request_set_error_once(struct i915_request *rq, int error)
 
 bool __i915_request_submit(struct i915_request *request)
 {
+	struct i915_gem_context *ctx = i915_request_gem_context(request);
 	struct intel_engine_cs *engine = request->engine;
 	bool result = false;
 
@@ -426,6 +427,8 @@ bool __i915_request_submit(struct i915_request *request)
 	GEM_BUG_ON(!irqs_disabled());
 	lockdep_assert_held(&engine->active.lock);
 
+	i915_ctx_dec_runnable(ctx, engine->class);
+
 	/*
 	 * With the advent of preempt-to-busy, we frequently encounter
 	 * requests that we have unsubmitted from HW, but left running
@@ -499,9 +502,14 @@ bool __i915_request_submit(struct i915_request *request)
 
 void i915_request_submit(struct i915_request *request)
 {
+	struct i915_gem_context *ctx = i915_request_gem_context(request);
 	struct intel_engine_cs *engine = request->engine;
+	const unsigned int class = engine->class;
 	unsigned long flags;
 
+	i915_ctx_dec_queued(ctx, class);
+	i915_ctx_inc_runnable(ctx, class);
+
 	/* Will be called from irq-context when using foreign fences. */
 	spin_lock_irqsave(&engine->active.lock, flags);
 
@@ -512,6 +520,7 @@ void i915_request_submit(struct i915_request *request)
 
 void __i915_request_unsubmit(struct i915_request *request)
 {
+	struct i915_gem_context *ctx = i915_request_gem_context(request);
 	struct intel_engine_cs *engine = request->engine;
 
 	RQ_TRACE(request, "\n");
@@ -519,6 +528,8 @@ void __i915_request_unsubmit(struct i915_request *request)
 	GEM_BUG_ON(!irqs_disabled());
 	lockdep_assert_held(&engine->active.lock);
 
+	i915_ctx_inc_runnable(ctx, engine->class);
+
 	/*
 	 * Only unwind in reverse order, required so that the per-context list
 	 * is kept in seqno/ring order.
@@ -1454,6 +1465,7 @@ void i915_request_add(struct i915_request *rq)
 	ctx = rcu_dereference(rq->context->gem_context);
 	if (ctx)
 		attr = ctx->sched;
+	i915_ctx_inc_queued(ctx, rq->engine->class);
 	rcu_read_unlock();
 
 	if (!(rq->sched.flags & I915_SCHED_HAS_SEMAPHORE_CHAIN))
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list