Re: [Intel-gfx] [RFC 09/12] drm/i915: Track per-context engine busyness

2020-03-10 Thread Chris Wilson
Quoting Tvrtko Ursulin (2020-03-09 18:31:26)
> From: Tvrtko Ursulin 
> 
> Some customers want to know how much of the GPU time are their clients
> using in order to make dynamic load balancing decisions.
> 
> With the hooks already in place which track the overall engine busyness,
> we can extend that slightly to split that time between contexts.
> 
> v2: Fix accounting for tail updates.
> v3: Rebase.
> v4: Mark currently running contexts as active on stats enable.
> v5: Include some headers to fix the build.
> v6: Added fine grained lock.
> v7: Convert to seqlock. (Chris Wilson)
> v8: Rebase and tidy with helpers.
> v9: Refactor.
> v10: Move recording start to promotion. (Chris)
> v11: Consolidate duplicated code. (Chris)
> v12: execlists->active cannot be NULL. (Chris)
> v13: Move start to set_timeslice. (Chris)
> 
> Signed-off-by: Tvrtko Ursulin 
> ---
>  drivers/gpu/drm/i915/gt/intel_context.c   | 20 +++
>  drivers/gpu/drm/i915/gt/intel_context.h   | 13 +++
>  drivers/gpu/drm/i915/gt/intel_context_types.h |  9 +
>  drivers/gpu/drm/i915/gt/intel_engine_cs.c | 15 ++--
>  drivers/gpu/drm/i915/gt/intel_lrc.c   | 34 ++-
>  5 files changed, 88 insertions(+), 3 deletions(-)

We also should put together a basic selftest to accompany its
introduction. Just something that runs a context (using a spinner) for
50ms and check the stats report ~50ms.
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [RFC 09/12] drm/i915: Track per-context engine busyness

2020-03-09 Thread Tvrtko Ursulin
From: Tvrtko Ursulin 

Some customers want to know how much of the GPU time are their clients
using in order to make dynamic load balancing decisions.

With the hooks already in place which track the overall engine busyness,
we can extend that slightly to split that time between contexts.

v2: Fix accounting for tail updates.
v3: Rebase.
v4: Mark currently running contexts as active on stats enable.
v5: Include some headers to fix the build.
v6: Added fine grained lock.
v7: Convert to seqlock. (Chris Wilson)
v8: Rebase and tidy with helpers.
v9: Refactor.
v10: Move recording start to promotion. (Chris)
v11: Consolidate duplicated code. (Chris)
v12: execlists->active cannot be NULL. (Chris)
v13: Move start to set_timeslice. (Chris)

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   | 20 +++
 drivers/gpu/drm/i915/gt/intel_context.h   | 13 +++
 drivers/gpu/drm/i915/gt/intel_context_types.h |  9 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 15 ++--
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 34 ++-
 5 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 01474d3a558b..c09b5fe7f61d 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -296,6 +296,7 @@ intel_context_init(struct intel_context *ce,
INIT_LIST_HEAD(&ce->signals);
 
mutex_init(&ce->pin_mutex);
+   seqlock_init(&ce->stats.lock);
 
i915_active_init(&ce->active,
 __intel_context_active, __intel_context_retire);
@@ -390,6 +391,25 @@ struct i915_request *intel_context_create_request(struct 
intel_context *ce)
return rq;
 }
 
+ktime_t intel_context_get_busy_time(struct intel_context *ce)
+{
+   unsigned int seq;
+   ktime_t total;
+
+   do {
+   seq = read_seqbegin(&ce->stats.lock);
+
+   total = ce->stats.total;
+
+   if (ce->stats.active)
+   total = ktime_add(total,
+ ktime_sub(ktime_get(),
+   ce->stats.start));
+   } while (read_seqretry(&ce->stats.lock, seq));
+
+   return total;
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 #include "selftest_context.c"
 #endif
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 18efad255124..b18b0012cb40 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -244,4 +244,17 @@ static inline u64 intel_context_get_avg_runtime_ns(struct 
intel_context *ce)
return mul_u32_u32(ewma_runtime_read(&ce->runtime.avg), period);
 }
 
+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;
+   }
+}
+
+ktime_t intel_context_get_busy_time(struct intel_context *ce);
+
 #endif /* __INTEL_CONTEXT_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index c60490e756f9..120532ddd6fa 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "i915_active_types.h"
 #include "i915_utils.h"
@@ -96,6 +97,14 @@ struct intel_context {
 
/** sseu: Control eu/slice partitioning */
struct intel_sseu sseu;
+
+   /** stats: Context GPU engine busyness tracking. */
+   struct intel_context_stats {
+   seqlock_t lock;
+   bool active;
+   ktime_t start;
+   ktime_t total;
+   } stats;
 };
 
 #endif /* __INTEL_CONTEXT_TYPES__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 53ac3f00909a..3845093b41ee 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -1594,8 +1594,19 @@ int intel_enable_engine_stats(struct intel_engine_cs 
*engine)
 
engine->stats.enabled_at = ktime_get();
 
-   /* XXX submission method oblivious? */
-   for (port = execlists->active; (rq = *port); port++)
+   /*
+* Mark currently running context as active.
+* XXX submission method oblivious?
+*/
+
+   rq = NULL;
+   port = execlists->active;
+   rq = *port;
+   if (rq)
+   __intel_context_stats_start(rq->context,
+   engine->stats.enabled_at);
+
+   for (; (rq = *port); port++)
engine->stats.active++;