aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2018-04-10 07:27:04 -0400
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2018-04-18 07:17:09 -0400
commite6be6bd85654dba55b97758f937c46835d961a44 (patch)
treec83b4a79cc1499c725d9d4ad1bfae8894f353dd1
parentfcf1fadf4c65eea6c519c773d2d9901e8ad94f5f (diff)
drm/i915/pmu: Inspect runtime PM state more carefully while estimating RC6
While thinking about sporadic failures of perf_pmu/rc6-runtime-pm* tests on some CI machines I have concluded that: a) the PMU readout of RC6 can race against runtime PM transitions, and b) there are other reasons than being runtime suspended which can cause intel_runtime_pm_get_if_in_use to fail. Therefore when estimating RC6 the code needs to assert we are indeed in suspended state, and if not, the best we can do is return the last known RC6 value. Without this check we can calculate the estimated value based on un- initialized or inappropriate internal state, which can result in over- estimation, or in any case incorrect value being returned. v2: * Re-arrange the code a bit to avoid second unlock and return branch. (Chris Wilson) v3: * Insert some strategic blank lines and improve commit msg. (Chris Wilson) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Fixes: 1fe699e30113 ("drm/i915/pmu: Fix sleep under atomic in RC6 readout") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105010 Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Imre Deak <imre.deak@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: https://patchwork.freedesktop.org/patch/msgid/20180410112704.24462-1-tvrtko.ursulin@linux.intel.com (cherry picked from commit 2924bdee21edd6785a4df1b4d17fd3cb265fddd9) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_pmu.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index d8feb9053e0c..f0519e31543a 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -473,20 +473,37 @@ static u64 get_rc6(struct drm_i915_private *i915)
473 spin_lock_irqsave(&i915->pmu.lock, flags); 473 spin_lock_irqsave(&i915->pmu.lock, flags);
474 spin_lock(&kdev->power.lock); 474 spin_lock(&kdev->power.lock);
475 475
476 if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) 476 /*
477 i915->pmu.suspended_jiffies_last = 477 * After the above branch intel_runtime_pm_get_if_in_use failed
478 kdev->power.suspended_jiffies; 478 * to get the runtime PM reference we cannot assume we are in
479 * runtime suspend since we can either: a) race with coming out
480 * of it before we took the power.lock, or b) there are other
481 * states than suspended which can bring us here.
482 *
483 * We need to double-check that we are indeed currently runtime
484 * suspended and if not we cannot do better than report the last
485 * known RC6 value.
486 */
487 if (kdev->power.runtime_status == RPM_SUSPENDED) {
488 if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
489 i915->pmu.suspended_jiffies_last =
490 kdev->power.suspended_jiffies;
479 491
480 val = kdev->power.suspended_jiffies - 492 val = kdev->power.suspended_jiffies -
481 i915->pmu.suspended_jiffies_last; 493 i915->pmu.suspended_jiffies_last;
482 val += jiffies - kdev->power.accounting_timestamp; 494 val += jiffies - kdev->power.accounting_timestamp;
483 495
484 spin_unlock(&kdev->power.lock); 496 val = jiffies_to_nsecs(val);
497 val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
485 498
486 val = jiffies_to_nsecs(val); 499 i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
487 val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; 500 } else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
488 i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; 501 val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
502 } else {
503 val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
504 }
489 505
506 spin_unlock(&kdev->power.lock);
490 spin_unlock_irqrestore(&i915->pmu.lock, flags); 507 spin_unlock_irqrestore(&i915->pmu.lock, flags);
491 } 508 }
492 509