diff mbox

[05/10] drm/i915: add assert_rpm_wakelock_held helper

Message ID 1450203038-5150-6-git-send-email-imre.deak@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Imre Deak Dec. 15, 2015, 6:10 p.m. UTC
As a preparation for follow-up patches add a new helper that checks
whether we hold an RPM reference, since this is what we want most of
the cases. Atm this helper will only check for the HW suspended state, a
follow-up patch will do the actual change to check the refcount instead.
One exception is the forcewake release timer function, where it's
guaranteed that the HW is on even though the RPM refcount drops to zero.
This guarantee is provided by flushing the timer in the runtime suspend
handler. So leave the assert_device_not_suspended check in place there.

Also rename assert_device_suspended for consistency and export these
helpers as a preparation for the follow-up patches.

No functional change.

v3:
- change the assert warning message to be more meaningful (Chris)

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_drv.h    | 14 ++++++++++++++
 drivers/gpu/drm/i915/intel_uncore.c | 20 +++++++-------------
 2 files changed, 21 insertions(+), 13 deletions(-)

Comments

Chris Wilson Dec. 16, 2015, 12:11 p.m. UTC | #1
On Tue, Dec 15, 2015 at 08:10:33PM +0200, Imre Deak wrote:
> As a preparation for follow-up patches add a new helper that checks
> whether we hold an RPM reference, since this is what we want most of
> the cases. Atm this helper will only check for the HW suspended state, a
> follow-up patch will do the actual change to check the refcount instead.
> One exception is the forcewake release timer function, where it's
> guaranteed that the HW is on even though the RPM refcount drops to zero.
> This guarantee is provided by flushing the timer in the runtime suspend
> handler. So leave the assert_device_not_suspended check in place there.
> 
> Also rename assert_device_suspended for consistency and export these
> helpers as a preparation for the follow-up patches.
> 
> No functional change.
> 
> v3:
> - change the assert warning message to be more meaningful (Chris)
> 
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/intel_drv.h    | 14 ++++++++++++++
>  drivers/gpu/drm/i915/intel_uncore.c | 20 +++++++-------------
>  2 files changed, 21 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 798463e..9837a25 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1430,6 +1430,20 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
>  			     enum intel_display_power_domain domain);
>  void intel_display_power_put(struct drm_i915_private *dev_priv,
>  			     enum intel_display_power_domain domain);
> +
> +static inline void
> +assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
> +{
> +	WARN_ONCE(dev_priv->pm.suspended,
> +		  "Device suspended during HW access\n");
> +}

On irc, Joonas expressed a wish to see all errors during an igt run,
i.e. something like

static inline void
assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
{
	WARN(dev_priv->pm.suspended &&
	     atomic_inc_return(&dev_priv->pm.errors) < 0,
		  "Device suspended during HW access\n");
}

with

static int
i915_pm_errors_get(void *data, u64 *val)
{
	struct drm_device *dev = data;

	*val = atomic_read(&to_i915(dev)->pm.erors);
	return 0;
}

static int
i915_pm_errors_set(void *data, u64 val)
{
	struct drm_device *dev = data;

	atomic_set(&to_i915(dev)->pm.errors, val);
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(i915_pm_errors_fops,
                        i915_pm_errors_get,
			i915_pm_errors_set,
			"0x%llx\n");


Then users only see the first WARN (and not swamped when it does go
wrong) and igt can echo INT_MIN > /sys/kernel/debug/dri/0/i915_pm_errors
to generate a WARN for each failure (and can even do a quick check for
any errors during a test by reading back i915_pm_errors).
-Chris
Imre Deak Dec. 16, 2015, 12:54 p.m. UTC | #2
On ke, 2015-12-16 at 12:11 +0000, Chris Wilson wrote:
> On Tue, Dec 15, 2015 at 08:10:33PM +0200, Imre Deak wrote:
> > As a preparation for follow-up patches add a new helper that checks
> > whether we hold an RPM reference, since this is what we want most
> > of
> > the cases. Atm this helper will only check for the HW suspended
> > state, a
> > follow-up patch will do the actual change to check the refcount
> > instead.
> > One exception is the forcewake release timer function, where it's
> > guaranteed that the HW is on even though the RPM refcount drops to
> > zero.
> > This guarantee is provided by flushing the timer in the runtime
> > suspend
> > handler. So leave the assert_device_not_suspended check in place
> > there.
> > 
> > Also rename assert_device_suspended for consistency and export
> > these
> > helpers as a preparation for the follow-up patches.
> > 
> > No functional change.
> > 
> > v3:
> > - change the assert warning message to be more meaningful (Chris)
> > 
> > Signed-off-by: Imre Deak <imre.deak@intel.com>
> > Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> >  drivers/gpu/drm/i915/intel_drv.h    | 14 ++++++++++++++
> >  drivers/gpu/drm/i915/intel_uncore.c | 20 +++++++-------------
> >  2 files changed, 21 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index 798463e..9837a25 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1430,6 +1430,20 @@ void intel_display_power_get(struct
> > drm_i915_private *dev_priv,
> >  			     enum intel_display_power_domain
> > domain);
> >  void intel_display_power_put(struct drm_i915_private *dev_priv,
> >  			     enum intel_display_power_domain
> > domain);
> > +
> > +static inline void
> > +assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
> > +{
> > +	WARN_ONCE(dev_priv->pm.suspended,
> > +		  "Device suspended during HW access\n");
> > +}
> 
> On irc, Joonas expressed a wish to see all errors during an igt run,
> i.e. something like
> 
> static inline void
> assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
> {
> 	WARN(dev_priv->pm.suspended &&
> 	     atomic_inc_return(&dev_priv->pm.errors) < 0,
> 		  "Device suspended during HW access\n");
> }
> 
> with
> 
> static int
> i915_pm_errors_get(void *data, u64 *val)
> {
> 	struct drm_device *dev = data;
> 
> 	*val = atomic_read(&to_i915(dev)->pm.erors);
> 	return 0;
> }
> 
> static int
> i915_pm_errors_set(void *data, u64 val)
> {
> 	struct drm_device *dev = data;
> 
> 	atomic_set(&to_i915(dev)->pm.errors, val);
> 	return 0;
> }
> 
> DEFINE_SIMPLE_ATTRIBUTE(i915_pm_errors_fops,
>                         i915_pm_errors_get,
> 			i915_pm_errors_set,
> 			"0x%llx\n");
> 
> 
> Then users only see the first WARN (and not swamped when it does go
> wrong) and igt can echo INT_MIN >
> /sys/kernel/debug/dri/0/i915_pm_errors
> to generate a WARN for each failure (and can even do a quick check
> for
> any errors during a test by reading back i915_pm_errors).

Sounds good, we could use this also for other PM related error
reporting.

Are you ok to do this as a follow-up?

--Imre
Chris Wilson Dec. 16, 2015, 1:02 p.m. UTC | #3
On Wed, Dec 16, 2015 at 02:54:43PM +0200, Imre Deak wrote:
> On ke, 2015-12-16 at 12:11 +0000, Chris Wilson wrote:
> > On Tue, Dec 15, 2015 at 08:10:33PM +0200, Imre Deak wrote:
> > > +static inline void
> > > +assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
> > > +{
> > > +	WARN_ONCE(dev_priv->pm.suspended,
> > > +		  "Device suspended during HW access\n");
> > > +}
> > 
> > On irc, Joonas expressed a wish to see all errors during an igt run,
> > i.e. something like
> > 
> > static inline void
> > assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
> > {
> > 	WARN(dev_priv->pm.suspended &&
> > 	     atomic_inc_return(&dev_priv->pm.errors) < 0,
> > 		  "Device suspended during HW access\n");
> > }
[snip]

> Sounds good, we could use this also for other PM related error
> reporting.
> 
> Are you ok to do this as a follow-up?

Definitely. We haven't changed any behaviour so far, so this is a new
feature.
-Chris
Joonas Lahtinen Dec. 16, 2015, 1:39 p.m. UTC | #4
On ke, 2015-12-16 at 13:02 +0000, Chris Wilson wrote:
> On Wed, Dec 16, 2015 at 02:54:43PM +0200, Imre Deak wrote:
> > On ke, 2015-12-16 at 12:11 +0000, Chris Wilson wrote:
> > > On Tue, Dec 15, 2015 at 08:10:33PM +0200, Imre Deak wrote:
> > > > +static inline void
> > > > +assert_rpm_device_not_suspended(struct drm_i915_private
> > > > *dev_priv)
> > > > +{
> > > > +	WARN_ONCE(dev_priv->pm.suspended,
> > > > +		  "Device suspended during HW access\n");
> > > > +}
> > > 
> > > On irc, Joonas expressed a wish to see all errors during an igt
> > > run,
> > > i.e. something like
> > > 
> > > static inline void
> > > assert_rpm_device_not_suspended(struct drm_i915_private
> > > *dev_priv)
> > > {
> > > 	WARN(dev_priv->pm.suspended &&
> > > 	     atomic_inc_return(&dev_priv->pm.errors) < 0,
> > > 		  "Device suspended during HW access\n");
> > > }
> [snip]
> 
> > Sounds good, we could use this also for other PM related error
> > reporting.
> > 
> > Are you ok to do this as a follow-up?
> 
> Definitely. We haven't changed any behaviour so far, so this is a new
> feature.

I'd prefer to currently add it as WARN instead of WARN_ONCE, and then
reduce the message amount with follow-up. This way we'll get more
useful CI results immediately.

Regards, Joonas

> -Chris
>
Imre Deak Dec. 16, 2015, 1:43 p.m. UTC | #5
On ke, 2015-12-16 at 15:39 +0200, Joonas Lahtinen wrote:
> On ke, 2015-12-16 at 13:02 +0000, Chris Wilson wrote:
> > On Wed, Dec 16, 2015 at 02:54:43PM +0200, Imre Deak wrote:
> > > On ke, 2015-12-16 at 12:11 +0000, Chris Wilson wrote:
> > > > On Tue, Dec 15, 2015 at 08:10:33PM +0200, Imre Deak wrote:
> > > > > +static inline void
> > > > > +assert_rpm_device_not_suspended(struct drm_i915_private
> > > > > *dev_priv)
> > > > > +{
> > > > > +	WARN_ONCE(dev_priv->pm.suspended,
> > > > > +		  "Device suspended during HW access\n");
> > > > > +}
> > > > 
> > > > On irc, Joonas expressed a wish to see all errors during an igt
> > > > run,
> > > > i.e. something like
> > > > 
> > > > static inline void
> > > > assert_rpm_device_not_suspended(struct drm_i915_private
> > > > *dev_priv)
> > > > {
> > > > 	WARN(dev_priv->pm.suspended &&
> > > > 	     atomic_inc_return(&dev_priv->pm.errors) < 0,
> > > > 		  "Device suspended during HW access\n");
> > > > }
> > [snip]
> > 
> > > Sounds good, we could use this also for other PM related error
> > > reporting.
> > > 
> > > Are you ok to do this as a follow-up?
> > 
> > Definitely. We haven't changed any behaviour so far, so this is a
> > new
> > feature.
> 
> I'd prefer to currently add it as WARN instead of WARN_ONCE, and then
> reduce the message amount with follow-up. This way we'll get more
> useful CI results immediately.

And more annoyed upstream users.. Really adding that knob is a good
idea and it doesn't take long to implement it, but we could make
progress if we did it as a follow-up.

> 
> Regards, Joonas
> 
> > -Chris
> >
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 798463e..9837a25 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1430,6 +1430,20 @@  void intel_display_power_get(struct drm_i915_private *dev_priv,
 			     enum intel_display_power_domain domain);
 void intel_display_power_put(struct drm_i915_private *dev_priv,
 			     enum intel_display_power_domain domain);
+
+static inline void
+assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
+{
+	WARN_ONCE(dev_priv->pm.suspended,
+		  "Device suspended during HW access\n");
+}
+
+static inline void
+assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
+{
+	assert_rpm_device_not_suspended(dev_priv);
+}
+
 void intel_runtime_pm_get(struct drm_i915_private *dev_priv);
 void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv);
 void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 0226776..3c63d94 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -50,12 +50,6 @@  intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id)
 	return "unknown";
 }
 
-static void
-assert_device_not_suspended(struct drm_i915_private *dev_priv)
-{
-	WARN_ONCE(dev_priv->pm.suspended, "Device suspended\n");
-}
-
 static inline void
 fw_domain_reset(const struct intel_uncore_forcewake_domain *d)
 {
@@ -235,7 +229,7 @@  static void intel_uncore_fw_release_timer(unsigned long arg)
 	struct intel_uncore_forcewake_domain *domain = (void *)arg;
 	unsigned long irqflags;
 
-	assert_device_not_suspended(domain->i915);
+	assert_rpm_device_not_suspended(domain->i915);
 
 	spin_lock_irqsave(&domain->i915->uncore.lock, irqflags);
 	if (WARN_ON(domain->wake_count == 0))
@@ -627,7 +621,7 @@  hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv)
 
 #define GEN2_READ_HEADER(x) \
 	u##x val = 0; \
-	assert_device_not_suspended(dev_priv);
+	assert_rpm_wakelock_held(dev_priv);
 
 #define GEN2_READ_FOOTER \
 	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
@@ -669,7 +663,7 @@  __gen2_read(64)
 	u32 offset = i915_mmio_reg_offset(reg); \
 	unsigned long irqflags; \
 	u##x val = 0; \
-	assert_device_not_suspended(dev_priv); \
+	assert_rpm_wakelock_held(dev_priv); \
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
 
 #define GEN6_READ_FOOTER \
@@ -802,7 +796,7 @@  __gen6_read(64)
 #define VGPU_READ_HEADER(x) \
 	unsigned long irqflags; \
 	u##x val = 0; \
-	assert_device_not_suspended(dev_priv); \
+	assert_rpm_device_not_suspended(dev_priv); \
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
 
 #define VGPU_READ_FOOTER \
@@ -829,7 +823,7 @@  __vgpu_read(64)
 
 #define GEN2_WRITE_HEADER \
 	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
-	assert_device_not_suspended(dev_priv); \
+	assert_rpm_wakelock_held(dev_priv); \
 
 #define GEN2_WRITE_FOOTER
 
@@ -869,7 +863,7 @@  __gen2_write(64)
 	u32 offset = i915_mmio_reg_offset(reg); \
 	unsigned long irqflags; \
 	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
-	assert_device_not_suspended(dev_priv); \
+	assert_rpm_wakelock_held(dev_priv); \
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
 
 #define GEN6_WRITE_FOOTER \
@@ -1045,7 +1039,7 @@  __gen6_write(64)
 #define VGPU_WRITE_HEADER \
 	unsigned long irqflags; \
 	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
-	assert_device_not_suspended(dev_priv); \
+	assert_rpm_device_not_suspended(dev_priv); \
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
 
 #define VGPU_WRITE_FOOTER \