Since we can compute the elapsed time to add to the total, during the PMU sample we only need to have a consistent view of the (start, total, active) tuple to be able to locally determine the runtime. That can be arrange by a pair of memory bariiers and carefully sequencing of the writes and reads.
Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk> Reviewed-by: Andi Shyti <andi.sh...@intel.com> --- drivers/gpu/drm/i915/gt/intel_gt_pm.c | 51 +++++++++--------------- drivers/gpu/drm/i915/gt/intel_gt_types.h | 7 ---- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c index aef3084e8b16..0bd303d2823e 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c @@ -40,24 +40,20 @@ static void user_forcewake(struct intel_gt *gt, bool suspend) static void runtime_begin(struct intel_gt *gt) { - local_irq_disable(); - write_seqcount_begin(>->stats.lock); - gt->stats.start = ktime_get(); - gt->stats.active = true; - write_seqcount_end(>->stats.lock); - local_irq_enable(); + smp_wmb(); /* pairs with intel_gt_get_busy_time() */ + WRITE_ONCE(gt->stats.start, ktime_get()); } static void runtime_end(struct intel_gt *gt) { - local_irq_disable(); - write_seqcount_begin(>->stats.lock); - gt->stats.active = false; - gt->stats.total = - ktime_add(gt->stats.total, - ktime_sub(ktime_get(), gt->stats.start)); - write_seqcount_end(>->stats.lock); - local_irq_enable(); + ktime_t total; + + total = ktime_sub(ktime_get(), gt->stats.start); + total = ktime_add(gt->stats.total, total); + + WRITE_ONCE(gt->stats.start, 0); + smp_wmb(); /* pairs with intel_gt_get_busy_time() */ + gt->stats.total = total; } static int __gt_unpark(struct intel_wakeref *wf) @@ -129,7 +125,6 @@ static const struct intel_wakeref_ops wf_ops = { void intel_gt_pm_init_early(struct intel_gt *gt) { intel_wakeref_init(>->wakeref, gt->uncore->rpm, &wf_ops); - seqcount_mutex_init(>->stats.lock, >->wakeref.mutex); } void intel_gt_pm_init(struct intel_gt *gt) @@ -363,28 +358,18 @@ int intel_gt_runtime_resume(struct intel_gt *gt) return intel_uc_runtime_resume(>->uc); } -static ktime_t __intel_gt_get_awake_time(const struct intel_gt *gt) -{ - ktime_t total = gt->stats.total; - - if (gt->stats.active) - total = ktime_add(total, - ktime_sub(ktime_get(), gt->stats.start)); - - return total; -} - ktime_t intel_gt_get_awake_time(const struct intel_gt *gt) { - unsigned int seq; - ktime_t total; + ktime_t total = gt->stats.total; + ktime_t start; - do { - seq = read_seqcount_begin(>->stats.lock); - total = __intel_gt_get_awake_time(gt); - } while (read_seqcount_retry(>->stats.lock, seq)); + start = READ_ONCE(gt->stats.start); + if (start) { + smp_rmb(); /* pairs with runtime_begin/end */ + start = ktime_sub(ktime_get(), start); + } - return total; + return ktime_add(total, start); } #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h index a83d3e18254d..91d20daca536 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -89,13 +89,6 @@ struct intel_gt { u32 pm_guc_events; struct { - bool active; - - /** - * @lock: Lock protecting the below fields. - */ - seqcount_mutex_t lock; - /** * @total: Total time this engine was busy. * -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx