drm/i915/pmu: Correct the rc6 offset upon enabling
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 14 Jan 2020 10:56:47 +0000 (10:56 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 14 Jan 2020 12:55:13 +0000 (12:55 +0000)
The rc6 residency starts ticking from 0 from BIOS POST, but the kernel
starts measuring the time from its boot. If we start measuruing
I915_PMU_RC6_RESIDENCY while the GT is idle, we start our sampling from
0 and then upon first activity (park/unpark) add in all the rc6
residency since boot. After the first park with the sampler engaged, the
sleep/active counters are aligned.

v2: With a wakeref to be sure

Closes: https://gitlab.freedesktop.org/drm/intel/issues/973
Fixes: df6a42053513 ("drm/i915/pmu: Ensure monotonic rc6")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200114105648.2172026-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_pmu.c

index 28a82c849bacbc2a43fc1fff4236b8981d349d1e..ec0299490dd4215b272ce986fd397ad4ddef01c6 100644 (file)
@@ -637,8 +637,10 @@ static void i915_pmu_enable(struct perf_event *event)
                container_of(event->pmu, typeof(*i915), pmu.base);
        unsigned int bit = event_enabled_bit(event);
        struct i915_pmu *pmu = &i915->pmu;
+       intel_wakeref_t wakeref;
        unsigned long flags;
 
+       wakeref = intel_runtime_pm_get(&i915->runtime_pm);
        spin_lock_irqsave(&pmu->lock, flags);
 
        /*
@@ -648,6 +650,14 @@ static void i915_pmu_enable(struct perf_event *event)
        BUILD_BUG_ON(ARRAY_SIZE(pmu->enable_count) != I915_PMU_MASK_BITS);
        GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count));
        GEM_BUG_ON(pmu->enable_count[bit] == ~0);
+
+       if (pmu->enable_count[bit] == 0 &&
+           config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) {
+               pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0;
+               pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
+               pmu->sleep_last = ktime_get();
+       }
+
        pmu->enable |= BIT_ULL(bit);
        pmu->enable_count[bit]++;
 
@@ -688,6 +698,8 @@ static void i915_pmu_enable(struct perf_event *event)
         * an existing non-zero value.
         */
        local64_set(&event->hw.prev_count, __i915_pmu_event_read(event));
+
+       intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 }
 
 static void i915_pmu_disable(struct perf_event *event)