diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_pmu.c | 37 | 
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)  		spin_lock_irqsave(&i915->pmu.lock, flags);  		spin_lock(&kdev->power.lock); -		if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) -			i915->pmu.suspended_jiffies_last = -						kdev->power.suspended_jiffies; +		/* +		 * After the above branch intel_runtime_pm_get_if_in_use failed +		 * to get the runtime PM reference we cannot assume we are in +		 * runtime suspend since we can either: a) race with coming out +		 * of it before we took the power.lock, or b) there are other +		 * states than suspended which can bring us here. +		 * +		 * We need to double-check that we are indeed currently runtime +		 * suspended and if not we cannot do better than report the last +		 * known RC6 value. +		 */ +		if (kdev->power.runtime_status == RPM_SUSPENDED) { +			if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) +				i915->pmu.suspended_jiffies_last = +						  kdev->power.suspended_jiffies; -		val = kdev->power.suspended_jiffies - -		      i915->pmu.suspended_jiffies_last; -		val += jiffies - kdev->power.accounting_timestamp; +			val = kdev->power.suspended_jiffies - +			      i915->pmu.suspended_jiffies_last; +			val += jiffies - kdev->power.accounting_timestamp; -		spin_unlock(&kdev->power.lock); +			val = jiffies_to_nsecs(val); +			val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; -		val = jiffies_to_nsecs(val); -		val += i915->pmu.sample[__I915_SAMPLE_RC6].cur; -		i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; +			i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val; +		} else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) { +			val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur; +		} else { +			val = i915->pmu.sample[__I915_SAMPLE_RC6].cur; +		} +		spin_unlock(&kdev->power.lock);  		spin_unlock_irqrestore(&i915->pmu.lock, flags);  	}  | 

