[PATCH 5/6] client busy

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Mon Feb 3 14:52:07 UTC 2020


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

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/gt/intel_context.h | 26 +++++++++++++++++++++----
 drivers/gpu/drm/i915/gt/intel_lrc.c     | 20 +++++++++++++++++--
 drivers/gpu/drm/i915/i915_drm_client.c  |  1 +
 drivers/gpu/drm/i915/i915_drm_client.h  | 10 ++++++++++
 4 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
index 77f3d34c44ee..b621e58dc338 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include <linux/types.h>
 
 #include "i915_active.h"
+#include "i915_drm_client.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -228,11 +229,28 @@ static inline void
 __intel_context_stats_start(struct intel_context *ce, ktime_t now)
 {
 	struct intel_context_stats *stats = &ce->stats;
-
-	if (!stats->active) {
-		stats->start = now;
-		stats->active = true;
+	struct i915_gem_context *ctx;
+
+	if (stats->active)
+		return;
+
+	stats->start = now;
+	stats->active = true;
+
+	rcu_read_lock();
+	ctx = rcu_dereference(ce->gem_context);
+	if (ctx && ctx->client) {
+		struct i915_drm_client *client = ctx->client;
+		unsigned int class = ce->engine->uabi_class;
+		unsigned long flags;
+
+		write_seqlock_irqsave(&client->stats.lock, flags);
+		if (client->stats.active[class]++ == 0)
+			client->stats.start[class] = now;
+		GEM_WARN_ON(client->stats.active[class] == 0);
+		write_sequnlock_irqrestore(&client->stats.lock, flags);
 	}
+	rcu_read_unlock();
 }
 
 ktime_t intel_context_get_busy_time(struct intel_context *ce);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 43066a80b482..308eb00d54b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1210,17 +1210,33 @@ static void intel_context_stats_start(struct intel_context *ce)
 static void intel_context_stats_stop(struct intel_context *ce)
 {
 	struct intel_context_stats *stats = &ce->stats;
+	struct i915_gem_context *ctx;
 	unsigned long flags;
+	ktime_t runtime;
 
 	if (!READ_ONCE(stats->active))
 		return;
 
 	write_seqlock_irqsave(&stats->lock, flags);
 	GEM_BUG_ON(!READ_ONCE(stats->active));
-	stats->total = ktime_add(stats->total,
-				 ktime_sub(ktime_get(), stats->start));
+	runtime = ktime_sub(ktime_get(), stats->start);
+	stats->total = ktime_add(stats->total, runtime);
 	stats->active = false;
 	write_sequnlock_irqrestore(&stats->lock, flags);
+
+	rcu_read_lock();
+	ctx = rcu_dereference(ce->gem_context);
+	if (ctx && ctx->client) {
+		struct i915_drm_client *client = ctx->client;
+		unsigned int class = ce->engine->uabi_class;
+
+		write_seqlock_irqsave(&client->stats.lock, flags);
+		GEM_WARN_ON(client->stats.active[class] == 0);
+		client->stats.active[class]--;
+		client->stats.busy[class] += ktime_to_ns(runtime);
+		write_sequnlock_irqrestore(&client->stats.lock, flags);
+	}
+	rcu_read_unlock();
 }
 
 static inline struct intel_engine_cs *
diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c
index a517de2281c0..efa612897e6d 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.c
+++ b/drivers/gpu/drm/i915/i915_drm_client.c
@@ -129,6 +129,7 @@ i915_drm_client_add(struct i915_drm_clients *clients, struct task_struct *task)
 
 	kref_init(&client->kref);
 	mutex_init(&client->update_lock);
+	seqlock_init(&client->stats.lock);
 	client->clients = clients;
 
 	ret = xa_alloc_cyclic(&clients->xarray, &client->id, client,
diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h
index a9d4d7396e43..26d211ea319b 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.h
+++ b/drivers/gpu/drm/i915/i915_drm_client.h
@@ -14,8 +14,11 @@
 #include <linux/pid.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
+#include <linux/seqlock.h>
 #include <linux/xarray.h>
 
+#include "gt/intel_engine_types.h"
+
 struct i915_drm_clients {
 	struct xarray xarray;
 	struct kobject *root;
@@ -33,6 +36,13 @@ struct i915_drm_client {
 	char __rcu *name;
 	bool closed;
 
+	struct {
+		seqlock_t lock;
+		unsigned int active[MAX_ENGINE_CLASS + 1];
+		ktime_t start[MAX_ENGINE_CLASS + 1];
+		u64 busy[MAX_ENGINE_CLASS + 1];
+	} stats;
+
 	struct i915_drm_clients *clients;
 
 	struct kobject *root;
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list