RE: [PATCH 1/1] PM / Runtime: let rpm_resume fail if rpm disabled and device suspended.

From: Alan Stern
Date: Mon Jun 16 2014 - 10:43:33 EST


On Mon, 16 Jun 2014, Allen Yu wrote:

> On Sat, 14 Jun 2014, Alan Stern wrote:
>
> > > dev->power.is_suspended is set after core suspends device during system
> > suspend.
> > > This flag mostly means device is not operational (all I/O been
> > > quiesced, no more data read or write acceptible, etc.), hence it's
> > > dangerous to access hardware if device is suspended even though runtime
> > PM status is RPM_ACTIVE.
> > >
> > > In turn, we should allow device to be accessed in case device is *not*
> > > suspended and runtime PM status is RPM_ACTIVE, even if runtime PM
> > > disabled. This corner case can happen to a device in a generic PM
> > > domain if the domain is not powered off while preparing for a system-wide
> > power transition.
> >
> > I don't understand. Even if the PM domain isn't powered off, the device's
> > is_suspended flag will still be set by __device_suspend().
>
> Yes, is_suspended flag will be set by __device_suspend(). But runtime PM can be disabled in pm_genpd_prepare():
>
> 914 static int pm_genpd_prepare(struct device *dev){
> ...
> 956 /*
> 957 * The PM domain must be in the GPD_STATE_ACTIVE state at this point,
> 958 * so pm_genpd_poweron() will return immediately, but if the device
> 959 * is suspended (e.g. it's been stopped by genpd_stop_dev()), we need
> 960 * to make it operational.
> 961 */
> 962 pm_runtime_resume(dev);
> 963 __pm_runtime_disable(dev, false);
> ...
> 978 }
>
> And there is a gap between pm_genpd_prepare() and __device_suspend(), during which is_suspended flag is *not* yet set but runtime PM is disabled and device status is RPM_ACTIVE.

It sounds like the real problem lies in pm_genpd_prepare(). It
disables the device too early.

> > > In this case, runtime PM status will
> > > be set to RPM_ACTIVE and then runtime PM is disabled. After that,
> > > device driver may call pm_runtime_get_sync() and rpm_resume() should
> > > return 1, because the device is still active as long as not been suspended.
> >
> > Isn't that what the existing code does already? Your patch seems to change
> > it so that it _doesn't_ behave the way you want.
> >
>
> The existing code return 1 for case is_suspended flag is set. That means __device_suspend() has been called and device is not in operational state. Whereas the case I mentioned above is before device is suspended.
> It's dangerous to access device if it's in suspended state, so I propose only allowing access to a device if it's not suspended (i.e. value of "is_suspneded" flag is false).

Okay, now I understand what you want to do. I couldn't figure it out
just from the patch description.

A better solution might be to remove the __pm_runtime_disable() call
from pm_genpd_prepare(). There's no obvious reason for it to be there,
especially since the PM core does a disable in __device_suspend_late().

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/