From: Tvrtko Ursulin <tvrtko.ursu...@intel.com> Track total time requests have been executing on the hardware.
To make this cheap it is hidden behind a static branch with the intention that it is only enabled when there is a consumer listening. This means that in the default off case the total cost of the tracking is just a few no-op instructions on the fast paths. Signed-off-by: Tvrtko Ursulin <tvrtko.ursu...@intel.com> --- drivers/gpu/drm/i915/intel_engine_cs.c | 6 +++++ drivers/gpu/drm/i915/intel_lrc.c | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 39 +++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 24db316e0fd1..3e5e08c6b5ef 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -22,10 +22,14 @@ * */ +#include <linux/static_key.h> + #include "i915_drv.h" #include "intel_ringbuffer.h" #include "intel_lrc.h" +DEFINE_STATIC_KEY_FALSE(i915_engine_stats_key); + /* Haswell does have the CXT_SIZE register however it does not appear to be * valid. Now, docs explain in dwords what is in the context object. The full * size is 70720 bytes, however, the power context and execlist context will @@ -223,6 +227,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv, /* Nothing to do here, execute in order of dependencies */ engine->schedule = NULL; + spin_lock_init(&engine->stats.lock); + ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); dev_priv->engine[id] = engine; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 89aa29f23a92..b72a2d7cd44c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -310,12 +310,14 @@ execlists_context_status_change(struct drm_i915_gem_request *rq, static inline void execlists_context_schedule_in(struct drm_i915_gem_request *rq) { + intel_engine_context_in(rq->engine); execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN); } static inline void execlists_context_schedule_out(struct drm_i915_gem_request *rq) { + intel_engine_context_out(rq->engine); execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 0877b151239d..2eb1e970ad06 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -443,6 +443,13 @@ struct intel_engine_cs { * certain bits to encode the command length in the header). */ u32 (*get_cmd_length_mask)(u32 cmd_header); + + struct { + spinlock_t lock; + unsigned int ref; + u64 start; /* Timestamp of the last idle to active transition. */ + u64 total; /* Total time engined was busy. */ + } stats; }; static inline unsigned int @@ -737,4 +744,36 @@ bool intel_engines_are_idle(struct drm_i915_private *dev_priv); void intel_engines_mark_idle(struct drm_i915_private *i915); void intel_engines_reset_default_submission(struct drm_i915_private *i915); +DECLARE_STATIC_KEY_FALSE(i915_engine_stats_key); + +static inline void intel_engine_context_in(struct intel_engine_cs *engine) +{ + if (static_branch_unlikely(&i915_engine_stats_key)) { + unsigned long flags; + + spin_lock_irqsave(&engine->stats.lock, flags); + if (engine->stats.ref++ == 0) + engine->stats.start = ktime_get_real_ns(); + GEM_BUG_ON(engine->stats.ref == 0); + spin_unlock_irqrestore(&engine->stats.lock, flags); + } +} + +static inline void intel_engine_context_out(struct intel_engine_cs *engine) +{ + if (static_branch_unlikely(&i915_engine_stats_key)) { + unsigned long flags; + + spin_lock_irqsave(&engine->stats.lock, flags); + /* + * After turning on the static key context out might be the + * first event which then needs to be ignored (ref == 0). + */ + if (engine->stats.ref && --engine->stats.ref == 0) + engine->stats.total += ktime_get_real_ns() - + engine->stats.start; + spin_unlock_irqrestore(&engine->stats.lock, flags); + } +} + #endif /* _INTEL_RINGBUFFER_H_ */ -- 2.9.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx