[Intel-gfx] [PATCH 09/10] drm/i915: add support for checking RPM atomic sections
Imre Deak
imre.deak at intel.com
Wed Dec 16 14:53:15 PST 2015
On Wed, 2015-12-16 at 12:18 +0100, Daniel Vetter wrote:
> On Tue, Dec 15, 2015 at 08:10:37PM +0200, Imre Deak wrote:
> > In some cases we want to check whether we hold an RPM wakelock
> > reference
> > for the whole duration of a sequence. To achieve this add a new RPM
> > atomic sequence
> > counter that we increment any time the wakelock refcount drops to
> > zero.
> > Check whether the sequence number stays the same during the atomic
> > section and that we hold the wakelock at the beginning of the
> > section.
> >
> > Motivated by Chris.
> >
> > v2-v3:
> > - unchanged
> > v4:
> > - swap the order of atomic_read() and assert_rpm_wakelock_held() in
> > assert_rpm_atomic_begin() to avoid race
> >
> > Signed-off-by: Imre Deak <imre.deak at intel.com>
> > Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk> (v3)
>
> Can we employ lockdep for some of this? In general lockdep doesn't
> mesh
> with rpm references, since rpm references can be transferred between
> processes. And lockdep doesn't like that.
>
> But in many cases, and this one here sounds like one, we don't do
> that.
> And those cases could be annotated/validated with the help of
> lockdep.
> The bonus of lockdep is that we could then also tell lockdep that the
> rpm
> suspend/resume functionsa acquire this lock context, which would
> catch
> bugs like mutex_lock(dev->struct_mutex); before rpm_get().
>
> Just a thought really.
Yes, as I mentioned I also played with the idea and it could be done by
separating the RPM wakelock users into "prolonged" and short time
users. Yea, couldn't think of a better name. I explained what I mean in
the top three patch of:
https://github.com/ideak/linux/commits/rpm-lockdep-annotations
But I would still need to do more testing with this, making sure the
annotations work as expected, in particular that I call lock_acquire()
with the proper parameters. So until that we could use this simpler
check that could reveal some issues already now.
--Imre
> > ---
> > drivers/gpu/drm/i915/i915_drv.h | 1 +
> > drivers/gpu/drm/i915/intel_drv.h | 17 +++++++++++++++++
> > drivers/gpu/drm/i915/intel_pm.c | 1 +
> > drivers/gpu/drm/i915/intel_runtime_pm.c | 3 ++-
> > 4 files changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 2894716..00ce627 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1603,6 +1603,7 @@ struct skl_wm_level {
> > */
> > struct i915_runtime_pm {
> > atomic_t wakeref_count;
> > + atomic_t atomic_seq;
> > bool suspended;
> > bool irqs_enabled;
> > };
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h
> > b/drivers/gpu/drm/i915/intel_drv.h
> > index d8e4aca..88d37eb 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -1446,6 +1446,23 @@ assert_rpm_wakelock_held(struct
> > drm_i915_private *dev_priv)
> > "RPM wakelock ref not held during HW access");
> > }
> >
> > +static inline int
> > +assert_rpm_atomic_begin(struct drm_i915_private *dev_priv)
> > +{
> > + int seq = atomic_read(&dev_priv->pm.atomic_seq);
> > +
> > + assert_rpm_wakelock_held(dev_priv);
> > +
> > + return seq;
> > +}
> > +
> > +static inline void
> > +assert_rpm_atomic_end(struct drm_i915_private *dev_priv, int
> > begin_seq)
> > +{
> > + WARN_ONCE(atomic_read(&dev_priv->pm.atomic_seq) !=
> > begin_seq,
> > + "HW access outside of RPM atomic section\n");
> > +}
> > +
> > /**
> > * disable_rpm_wakeref_asserts - disable the RPM assert checks
> > * @dev_priv: i915 device instance
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index 6c08537..6eb9606 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -7248,4 +7248,5 @@ void intel_pm_setup(struct drm_device *dev)
> >
> > dev_priv->pm.suspended = false;
> > atomic_set(&dev_priv->pm.wakeref_count, 0);
> > + atomic_set(&dev_priv->pm.atomic_seq, 0);
> > }
> > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > index 82c55a9..cee54ea 100644
> > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > @@ -2283,7 +2283,8 @@ void intel_runtime_pm_put(struct
> > drm_i915_private *dev_priv)
> > struct device *device = &dev->pdev->dev;
> >
> > assert_rpm_wakelock_held(dev_priv);
> > - atomic_dec(&dev_priv->pm.wakeref_count);
> > + if (atomic_dec_and_test(&dev_priv->pm.wakeref_count))
> > + atomic_inc(&dev_priv->pm.atomic_seq);
> >
> > pm_runtime_mark_last_busy(device);
> > pm_runtime_put_autosuspend(device);
> > --
> > 2.5.0
> >
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
More information about the Intel-gfx
mailing list