PM regression with commit 5de85b9d57ab PM runtime re-init in v4.5-rc1

Alan Stern stern at rowland.harvard.edu
Tue Feb 2 13:45:22 PST 2016


On Tue, 2 Feb 2016, Tony Lindgren wrote:

> > Also, what is autosuspend_delay set to for your device?  And is 
> > runtime_auto set?
> 
> It's 100 at that point, see the commented snippet below from
> omap_hsmmc_probe():
> 
> 	pm_runtime_enable(host->dev);
> 	pm_runtime_get_sync(host->dev);
> 	pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY);
> 	/* NOTE: pm_runtime_dont_use_autosuspend(host->dev) needed here? */
> 	pm_runtime_use_autosuspend(host->dev);
> 	...
> 	/* gets -EPROBE_DEFER */
> err_irq:
> 	...
> 	pm_runtime_put_sync(host->dev);

You could try changing this to pm_runtime_put_sync_suspend().  But
putting pm_runtime_dont_use_autosuspend() before the put_sync seems
like a perfectly reasonable thing to do, especially if you feel you
should reverse all the changes you made at the start.

>         pm_runtime_disable(host->dev);
> 	/* NOTE: suspend callback never gets called unless
> 	 * pm_runtime_dont_use_autosuspend() is called
> 	 * before pm_runtime_put_sync() above.
> 	 */
> 	 ...
> 
> > > > Does pm_runtime_use_autosuspend() get called by the probe routine?  If 
> > > > it does, then perhaps you can get what you want by having the probe 
> > > > routine call pm_runtime_dont_use_autosuspend() whenever it's about to 
> > > > return an error -- particularly -EDEFER.
> > > 
> > > Yes so far that's the only fix that seems to work like I posted
> > > earlier. But is that the right fix though?
> > 
> > No, not really.  Ideally you would leave autosuspend turned on.  The 
> > delay would be long enough to that after -EDEFER, another probe would 
> > start before the delay expired.  But shortly after the last probe 
> > attempt, the delay would expire and the device would then be put in low 
> > power.
> 
> But then what about the new reinit function? To me it seems that
> we should not attempt to maintain a state from the earlier failed
> probe. Or are you thinking we just skip the reinit if autosuspend
> is set?

The reinit function gets called too late to do what you want -- namely, 
put the hardware in a low-power state.

That _is_ what you want, isn't it?  The alternative is to leave
dev->power.rpm_status set to RPM_ACTIVE, to match the hardware's actual 
state.

Given that the reinit function is supposed to restore the initial 
settings, it probably ought to call pm_runtime_dont_use_autosuspend().  
But that won't be enough to fix your problem.

> > > If we wanted to have some generic fix, it seems we would have to pass
> > > a new flag in pm_runtime_put_sync() to ignore any autosuspend
> > > configuration. But I don't know if that's what we want to or should
> > > do though?
> > 
> > I don't think so.
> 
> So should we just establish a policy that pm_runtime_use_autosuspend()
> needs to be paired with pm_runtime_dont_use_autosuspend() for
> pm_runtime_put_sync() to work?

Your understanding is slightly wrong.  pm_runtime_put_sync() _does_
work -- that is, it does what it's supposed to do.  The difficulty is
that what it's supposed to do doesn't match what you think.

pm_runtime_put_sync() is supposed to follow the driver's wishes.  It
invokes the driver's runtime_idle callback if there is one, and the
callback routine can start a suspend or an autosuspend.  If there is no
callback, it will use whatever autosuspend setting the driver has set
up.  If you want to override the autosuspend setting, use
pm_runtime_put_sync_suspend() instead.

Alan Stern




More information about the linux-arm-kernel mailing list