[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-16 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.
v3:
 * Include total/avg in traces and error state for debugging

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
 drivers/gpu/drm/i915/gt/intel_context.h   | 17 
 drivers/gpu/drm/i915/gt/intel_context_types.h | 12 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 46 -
 drivers/gpu/drm/i915/gt/intel_lrc_reg.h   |  1 +
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 96 +++
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 10 files changed, 195 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
 {
struct intel_context *ce = container_of(active, typeof(*ce), active);
 
-   CE_TRACE(ce, "retire\n");
+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
 
set_bit(CONTEXT_VALID_BIT, >flags);
if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
 
+   ewma_runtime_init(>runtime.avg);
+
ce->vm = i915_vm_get(engine->gt->vm);
 
INIT_LIST_HEAD(>signal_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..18efad255124 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,20 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return READ_ONCE(ce->runtime.total) * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
 #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 ca1420fb8b53..11278343b9b5 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,8 @@
 
 #define CONTEXT_REDZONE POISON_INUSE
 
+DECLARE_EWMA(runtime, 3, 8);
+
 struct i915_gem_context;
 struct i915_vma;
 struct intel_context;
@@ -68,6 +71,15 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 num_underflow);
+   I915_SELFTEST_DECLARE(u32 max_underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..78e854440949 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,42 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* We can use either ppHWSP[16] which is recorded before the context
+* switch (and so excludes the cost of context switches) or use the
+* value from the context image itself, which is saved/restored earlier
+* and so includes the cost of 

[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-16 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.
v3:
 * Include total/avg in traces and error state for debugging

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
 drivers/gpu/drm/i915/gt/intel_context.h   | 17 
 drivers/gpu/drm/i915/gt/intel_context_types.h | 12 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 45 -
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 91 +++
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 9 files changed, 188 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
 {
struct intel_context *ce = container_of(active, typeof(*ce), active);
 
-   CE_TRACE(ce, "retire\n");
+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
 
set_bit(CONTEXT_VALID_BIT, >flags);
if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
 
+   ewma_runtime_init(>runtime.avg);
+
ce->vm = i915_vm_get(engine->gt->vm);
 
INIT_LIST_HEAD(>signal_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..18efad255124 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,20 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return READ_ONCE(ce->runtime.total) * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
 #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 ca1420fb8b53..90f8f4dd7091 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,8 @@
 
 #define CONTEXT_REDZONE POISON_INUSE
 
+DECLARE_EWMA(runtime, 3, 4);
+
 struct i915_gem_context;
 struct i915_vma;
 struct intel_context;
@@ -68,6 +71,15 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 num_underflow);
+   I915_SELFTEST_DECLARE(u32 max_underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..afce5f1330eb 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,41 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/
+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 1);
+   return READ_ONCE(ce->lrc_reg_state[-1024 + 16]);
+}
+
+static void intel_context_update_runtime(struct 

[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-16 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.
v3:
 * Include total/avg in traces and error state for debugging

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
 drivers/gpu/drm/i915/gt/intel_context.h   | 17 
 drivers/gpu/drm/i915/gt/intel_context_types.h | 12 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 44 -
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 91 +++
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 9 files changed, 187 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
 {
struct intel_context *ce = container_of(active, typeof(*ce), active);
 
-   CE_TRACE(ce, "retire\n");
+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
 
set_bit(CONTEXT_VALID_BIT, >flags);
if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
 
+   ewma_runtime_init(>runtime.avg);
+
ce->vm = i915_vm_get(engine->gt->vm);
 
INIT_LIST_HEAD(>signal_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..18efad255124 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,20 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return READ_ONCE(ce->runtime.total) * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
 #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 ca1420fb8b53..90f8f4dd7091 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,8 @@
 
 #define CONTEXT_REDZONE POISON_INUSE
 
+DECLARE_EWMA(runtime, 3, 4);
+
 struct i915_gem_context;
 struct i915_vma;
 struct intel_context;
@@ -68,6 +71,15 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 num_underflow);
+   I915_SELFTEST_DECLARE(u32 max_underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..ec9df88eb867 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,40 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/
+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 1);
+   return READ_ONCE(ce->lrc_reg_state[-1024 + 16]);
+}
+
+static void intel_context_update_runtime(struct 

[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-16 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.
v3:
 * Include total/avg in traces and error state for debugging

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
 drivers/gpu/drm/i915/gt/intel_context.h   | 17 
 drivers/gpu/drm/i915/gt/intel_context_types.h | 12 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 44 -
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 90 +++
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 9 files changed, 186 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
 {
struct intel_context *ce = container_of(active, typeof(*ce), active);
 
-   CE_TRACE(ce, "retire\n");
+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
 
set_bit(CONTEXT_VALID_BIT, >flags);
if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
 
+   ewma_runtime_init(>runtime.avg);
+
ce->vm = i915_vm_get(engine->gt->vm);
 
INIT_LIST_HEAD(>signal_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..18efad255124 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,20 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return READ_ONCE(ce->runtime.total) * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
 #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 ca1420fb8b53..90f8f4dd7091 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,8 @@
 
 #define CONTEXT_REDZONE POISON_INUSE
 
+DECLARE_EWMA(runtime, 3, 4);
+
 struct i915_gem_context;
 struct i915_vma;
 struct intel_context;
@@ -68,6 +71,15 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 num_underflow);
+   I915_SELFTEST_DECLARE(u32 max_underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..ec9df88eb867 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,40 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/
+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 1);
+   return READ_ONCE(ce->lrc_reg_state[-1024 + 16]);
+}
+
+static void intel_context_update_runtime(struct 

[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-16 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

QQQ: Do we want to make this accounting conditional / able to turn on/off?

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
 drivers/gpu/drm/i915/gt/intel_context.h   | 17 
 drivers/gpu/drm/i915/gt/intel_context_types.h | 12 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 44 -
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 90 +++
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 9 files changed, 186 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
 {
struct intel_context *ce = container_of(active, typeof(*ce), active);
 
-   CE_TRACE(ce, "retire\n");
+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
 
set_bit(CONTEXT_VALID_BIT, >flags);
if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
 
+   ewma_runtime_init(>runtime.avg);
+
ce->vm = i915_vm_get(engine->gt->vm);
 
INIT_LIST_HEAD(>signal_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..18efad255124 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,20 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return READ_ONCE(ce->runtime.total) * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
 #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 ca1420fb8b53..90f8f4dd7091 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,8 @@
 
 #define CONTEXT_REDZONE POISON_INUSE
 
+DECLARE_EWMA(runtime, 3, 4);
+
 struct i915_gem_context;
 struct i915_vma;
 struct intel_context;
@@ -68,6 +71,15 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 num_underflow);
+   I915_SELFTEST_DECLARE(u32 max_underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..ec9df88eb867 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,40 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/
+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 1);
+   return READ_ONCE(ce->lrc_reg_state[-1024 + 16]);
+}
+
+static void 

Re: [Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-16 Thread Lionel Landwerlin

On 16/02/2020 00:06, Chris Wilson wrote:

From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

QQQ: Do we want to make this accounting conditional / able to turn on/off?

v2:
  (Chris)
  * Do not store pphwsp address in intel_context.
  * Log CS wrap-around.
  * Simplify calculation by relying on integer wraparound.

Signed-off-by: Tvrtko Ursulin 
---
  drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
  drivers/gpu/drm/i915/gt/intel_context.h   | 18 
  drivers/gpu/drm/i915/gt/intel_context_types.h | 11 +++
  drivers/gpu/drm/i915/gt/intel_lrc.c   | 42 -
  drivers/gpu/drm/i915/gt/selftest_lrc.c| 87 +++
  drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
  drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
  drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
  drivers/gpu/drm/i915/intel_device_info.h  |  1 +
  9 files changed, 181 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
  {
struct intel_context *ce = container_of(active, typeof(*ce), active);
  
-	CE_TRACE(ce, "retire\n");

+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
  
  	set_bit(CONTEXT_VALID_BIT, >flags);

if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
  
+	ewma_runtime_init(>runtime.avg);

+
ce->vm = i915_vm_get(engine->gt->vm);
  
  	INIT_LIST_HEAD(>signal_link);

diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..e58da0938dcb 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
  #include 
  
  #include "i915_active.h"

+#include "i915_drv.h"
  #include "intel_context_types.h"
  #include "intel_engine_types.h"
  #include "intel_ring_types.h"
@@ -227,4 +228,21 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
  }
  
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)

+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return ce->runtime.total * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
+
  #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 ca1420fb8b53..6112ec97fbdf 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
  #ifndef __INTEL_CONTEXT_TYPES__
  #define __INTEL_CONTEXT_TYPES__
  
+#include 

  #include 
  #include 
  #include 
@@ -19,6 +20,8 @@
  
  #define CONTEXT_REDZONE POISON_INUSE
  
+DECLARE_EWMA(runtime, 3, 4);

+
  struct i915_gem_context;
  struct i915_vma;
  struct intel_context;
@@ -68,6 +71,14 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
  
+	/* Time on GPU as tracked by the hw. */

+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
  
  	atomic_t pin_count;

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..c09079c93345 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,38 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
  }
  
+static u32 intel_context_get_runtime(const struct intel_context *ce)

+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/



I read somewhere this accumulated runtime was incremented only every 8th 
CS timestamp tick.



-Lionel


+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 

[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-15 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

QQQ: Do we want to make this accounting conditional / able to turn on/off?

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |  6 +-
 drivers/gpu/drm/i915/gt/intel_context.h   | 18 
 drivers/gpu/drm/i915/gt/intel_context_types.h | 11 +++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 42 -
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 87 +++
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 ++-
 drivers/gpu/drm/i915/i915_gpu_error.h |  4 +
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 9 files changed, 181 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index e4f89341d17c..8bb444cda14f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -220,7 +220,9 @@ static void __intel_context_retire(struct i915_active 
*active)
 {
struct intel_context *ce = container_of(active, typeof(*ce), active);
 
-   CE_TRACE(ce, "retire\n");
+   CE_TRACE(ce, "retire runtime: { total:%lluns, avg:%lluns }\n",
+intel_context_get_total_runtime_ns(ce),
+intel_context_get_avg_runtime_ns(ce));
 
set_bit(CONTEXT_VALID_BIT, >flags);
if (ce->state)
@@ -281,6 +283,8 @@ intel_context_init(struct intel_context *ce,
ce->sseu = engine->sseu;
ce->ring = __intel_context_ring_size(SZ_4K);
 
+   ewma_runtime_init(>runtime.avg);
+
ce->vm = i915_vm_get(engine->gt->vm);
 
INIT_LIST_HEAD(>signal_link);
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..e58da0938dcb 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,21 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_total_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return ce->runtime.total * period;
+}
+
+static inline u64 intel_context_get_avg_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ewma_runtime_read(>runtime.avg), period);
+}
+
+
 #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 ca1420fb8b53..6112ec97fbdf 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -7,6 +7,7 @@
 #ifndef __INTEL_CONTEXT_TYPES__
 #define __INTEL_CONTEXT_TYPES__
 
+#include 
 #include 
 #include 
 #include 
@@ -19,6 +20,8 @@
 
 #define CONTEXT_REDZONE POISON_INUSE
 
+DECLARE_EWMA(runtime, 3, 4);
+
 struct i915_gem_context;
 struct i915_vma;
 struct intel_context;
@@ -68,6 +71,14 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   struct ewma_runtime avg;
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(u32 underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..c09079c93345 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,38 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/
+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 1);
+   return ce->lrc_reg_state[-1024 + 16];
+}
+
+static void intel_context_update_runtime(struct intel_context *ce)
+{
+   u32 new, old;
+
+   if 

[Intel-gfx] [CI] drm/i915: Track hw reported context runtime

2020-02-15 Thread Chris Wilson
From: Tvrtko Ursulin 

GPU saves accumulated context runtime (in CS timestamp units) in PPHWSP
which will be useful for us in cases when we are not able to track context
busyness ourselves (like with GuC). Keep a copy of this in struct
intel_context from where it can be easily read even if the context is not
pinned.

QQQ: Do we want to make this accounting conditional / able to turn on/off?

v2:
 (Chris)
 * Do not store pphwsp address in intel_context.
 * Log CS wrap-around.
 * Simplify calculation by relying on integer wraparound.

Signed-off-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/intel_context.h   |  9 ++
 drivers/gpu/drm/i915/gt/intel_context_types.h |  7 ++
 drivers/gpu/drm/i915/gt/intel_lrc.c   | 41 -
 drivers/gpu/drm/i915/gt/selftest_lrc.c| 85 +++
 drivers/gpu/drm/i915/intel_device_info.c  |  6 ++
 drivers/gpu/drm/i915/intel_device_info.h  |  1 +
 6 files changed, 147 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h
index 604d5cfc46ba..502cf7361a29 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -12,6 +12,7 @@
 #include 
 
 #include "i915_active.h"
+#include "i915_drv.h"
 #include "intel_context_types.h"
 #include "intel_engine_types.h"
 #include "intel_ring_types.h"
@@ -227,4 +228,12 @@ intel_context_clear_nopreempt(struct intel_context *ce)
clear_bit(CONTEXT_NOPREEMPT, >flags);
 }
 
+static inline u64 intel_context_get_hw_runtime_ns(struct intel_context *ce)
+{
+   const u32 period =
+   RUNTIME_INFO(ce->engine->i915)->cs_timestamp_period_ns;
+
+   return mul_u32_u32(ce->runtime.total, period);
+}
+
 #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 ca1420fb8b53..3100823b16c3 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -68,6 +68,13 @@ struct intel_context {
u64 lrc_desc;
u32 tag; /* cookie passed to HW to track this context on submission */
 
+   /* Time on GPU as tracked by the hw. */
+   struct {
+   u64 total;
+   u32 last;
+   I915_SELFTEST_DECLARE(unsigned long underflow);
+   } runtime;
+
unsigned int active_count; /* protected by timeline->mutex */
 
atomic_t pin_count;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index c3d7727021db..a505e98c8854 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1195,6 +1195,37 @@ static void reset_active(struct i915_request *rq,
ce->lrc_desc |= CTX_DESC_FORCE_RESTORE;
 }
 
+static u32 intel_context_get_runtime(const struct intel_context *ce)
+{
+   /*
+* PPHWSP is one page before the lrc state page and in it at
+* dword 16 we have cumulative context runtime in CS timestamp ticks.
+*/
+   BUILD_BUG_ON((LRC_STATE_PN - LRC_PPHWSP_PN) != 1);
+   return ce->lrc_reg_state[-1024 + 16];
+}
+
+static void intel_context_update_runtime(struct intel_context *ce)
+{
+   u32 new, old;
+
+   if (intel_context_is_barrier(ce))
+   return;
+
+   old = ce->runtime.last;
+   new = intel_context_get_runtime(ce);
+   if ((s32)(new - old) <= 0) {
+   CE_TRACE(ce, "runtime underflow: last=%u, new=%u, delta=%d\n",
+old, new, new - old);
+   I915_SELFTEST_ONLY(ce->runtime.underflow++);
+   GEM_TRACE_DUMP();
+   return;
+   }
+
+   ce->runtime.total += new - old;
+   ce->runtime.last = new;
+}
+
 static inline struct intel_engine_cs *
 __execlists_schedule_in(struct i915_request *rq)
 {
@@ -1278,6 +1309,7 @@ __execlists_schedule_out(struct i915_request *rq,
i915_request_completed(rq))
intel_engine_add_retire(engine, ce->timeline);
 
+   intel_context_update_runtime(ce);
intel_engine_context_out(engine);
execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT);
intel_gt_pm_put_async(engine->gt);
@@ -4607,8 +4639,13 @@ populate_lr_context(struct intel_context *ce,
inhibit = false;
}
 
-   /* The second page of the context object contains some fields which must
-* be set up prior to the first execution. */
+   /* Clear the ppHWSP (inc. per-context counters) */
+   memset(vaddr, 0, PAGE_SIZE);
+
+   /*
+* The second page of the context object contains some registers which
+* must be set up prior to the first execution.
+*/
execlists_init_reg_state(vaddr + LRC_STATE_PN * PAGE_SIZE,
 ce, engine, ring, inhibit);
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c 
b/drivers/gpu/drm/i915/gt/selftest_lrc.c
index