[PATCH 41/42] drm/i915/gt: Reduce GT runtime stats from seqlock to a latch
Chris Wilson
chris at chris-wilson.co.uk
Thu Jan 28 14:55:27 UTC 2021
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 <chris at chris-wilson.co.uk>
Reviewed-by: Andi Shyti <andi.shyti at 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
More information about the Intel-gfx-trybot
mailing list