Thread (32 messages) 32 messages, 3 authors, 2017-09-06
STALE3199d

[PATCH v3 0/8] PM / ACPI / i2c: Deploy runtime PM centric path for system sleep

From: Rafael J. Wysocki <hidden>
Date: 2017-09-04 00:17:21
Also in: linux-acpi, linux-i2c, linux-pm

On Friday, September 1, 2017 12:42:35 PM CEST Ulf Hansson wrote:
On 31 August 2017 at 02:17, Rafael J. Wysocki [off-list ref] wrote:
quoted
Disclaimer: I'm falling asleep, so I probably shouldn't reply to email right
now, but tomorrow I may not be able to get to email at all, so I'll try anyway.

On Wednesday, August 30, 2017 11:57:28 AM CEST Ulf Hansson wrote:
quoted
On 29 August 2017 at 22:19, Rafael J. Wysocki [off-list ref] wrote:
quoted
On Tuesday, August 29, 2017 4:56:42 PM CEST Ulf Hansson wrote:
quoted
The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
isn't well optimized for system sleep.

What makes this driver particularly interesting is because it's a cross-SoC
driver, which sometimes means there is an ACPI PM domain attached to the i2c
device and sometimes not. The driver is being used on both x86 and ARM.

In principle, to optimize the system sleep support in i2c driver, this series
enables the proven runtime PM centric path for the i2c driver. However, to do
that the ACPI PM domain also have to collaborate and understand this behaviour.
From earlier versions, Rafael has also pointed out that also the PM core needs
to be involved.
Earlier today I realized that drivers pointing their ->suspend_late and
->resume_early callbacks, respectively, to pm_runtime_force_suspend() and
pm_runtime_force_resume(), are fundamentally incompatible with any bus type
doing nontrivial PM and with almost any nontrivial PM domains, for two reasons.

First, it basically requires the bus type or PM domain to expect that its
->runtime_suspend callback may or may not be indirectly invoked from its
own ->suspend_late callback, depending on the driver (and analogously
for ->runtime_resume and ->resume early), which is insane.

Second, it is a layering violation, because it makes the driver effectively
override the upper layer's decisions about what code to run.
You are right that for more complex bus types and PM domains, those
needs to play along. So that is what I am trying to implement for the
ACPI PM domain in this series.
Well, "play along" is a bit of an understatement here.

They would need to turn into horrible mess and that's not going to happen.
I absolutely agree, there must be no mess what so ever!

But, I don't want to give up yet, I still believe I can make this
series into a nice couple of changes for the ACPI PM domain.
Well, as far as I'm concerned, this is not going to get any further.
Especially if you continue giving me your guidance.
quoted
quoted
The generic PM domain, is simple in this regards. There is only a
minor adaptation for the ->runtime_suspend|resume() callbacks, which
avoids validating dev_pm_qos constraints during system sleep. Nothing
special is needed in ->suspend_late|noirq callbacks, etc.

For most other simple bus types, like the platform bus, spi, i2c,
amba, no particular adoptions is needed at all. Instead those just
trust the drivers to do the right thing.
They are the trivial ones.
Yes.

However, the platform bus is also very commonly used in kernel. I
think that's an important thing to consider.
Well, so is ACPI, and PCI.

And the platform bus doesn't do any kind of PM handling by itself,
whereas the above do.  Therefore trying to look at the platform bus as
an example to follow by them is rather not useful IMO.
quoted
quoted
Before we had the direct_complete path, using the
pm_runtime_force_suspend|resume() helpers, was the only good way for
these kind of drivers, to in an optimized manner, deal with system
sleep when runtime PM also was enabled for their devices. Now this
method has become widely deployed, unfortunate whether you like it or
not.
So can you please remind me why the _force_ wrappers are needed?
See below.
quoted
In particular, why can't drivers arrange their callbacks the way I did that
in https://patchwork.kernel.org/patch/9928583/ ?
I was preparing a reply to that patch, but let me summarize that here instead.

Let me be clear, the patch is an improvement of the behavior of the
driver and it addresses the issues you point out in the change log.
Re-using the runtime PM callbacks for system sleep, is nice as it
avoids open coding, which is of curse also one of the reason of using
pm_runtime_force_suspend|resume().

Still there are a couple of things I am worried about in this patch.
*)
To be able to re-use the same callbacks for system sleep and runtime
PM, some boilerplate code is added to the driver, as to cope with the
different conditions inside the callbacks. That pattern would become
repeated to many drivers dealing with similar issues.
I'm not worried about that as long as there are good examples and
documented best practices.

There aren't any right now, which is a problem, but that certainly is
fixable.
**)
The ->resume_early() callback powers on the device, in case it was
runtime resumed when the ->suspend_late() callback was invoked. That
is in many cases completely unnecessary, causing us to waste power and
increase system resume time, for absolutely no reason. However, I
understand the patch didn't try to address this, but to really fix
this, there has to be an even closer collaboration between runtime PM
and the system sleep callbacks.
I don't quite agree and here's why.

If a device was not runtime-suspended right before system suspend, then quite
likely it was in use then.  Therefore it is quite likely to be resumed
immediately after system resume anyway.

Now, if that's just one device, it probably doesn't matter, but if there are
more devices like that, they will be resumed after system suspend when they
are accessed and quite likely they will be accessed one-by-one rather than in
parallel with each other, so the latencies related to that will add up.  In
that case it is better to resume them upfront during system resume as they will
be resumed in parallel with each other then.  And that also is *way* simpler.

This means that the benefit from avoiding to resume devices during system
resume is not quite so obvious and the whole point above is highly
questionable.
So, to remind you why the pm_runtime_force_suspend|resume() helpers is
preferred, that's because both of the above two things becomes taken
care of.
And that is why there is this stuff about parents and usage counters, right?

I'm not liking it at all.
quoted
quoted
Besides the slightly better optimizations you get when using
pm_runtime_force_suspend|resume(), comparing to the direct_complete
path - I think it's also worth to consider, how easy it becomes for
drivers to deploy system sleep support. In many cases, only two lines
of code is needed to add system sleep support in a driver.
You are doing a wrong comparison here IMO.  You essentially are comparing two
bandaids with each other and arguing that one of them somehow is better.
I just wanted to compare against something...
quoted
What about doing something which is not a bandaid instead?
I don't have a problem working on something new, but I am not sure
what that should be.

Unless you re-consider moving forward in some form, with the current
suggested approach for the ACPI PM domain, can you give me some
pointers on what you have in mind?
Yes.

Do what was indended from the start and make drivers re-use runtime
PM callbacks for ->suspend_late and ->resume_early.

First, that can be done.

Second, it is *conceptually* much more straightforward than things like
_force_suspend/resume().

Next, the drivers have full control on what they do in that case and
can be made work with any middle-layer core easily enough.

No layering violations, no insane callback chains.
To remind you of my current view, the direct_complete path is useful
for PM domains, like the ACPI PM domain as it impacts all its devices.
Using pm_runtime_force_suspend|resume() offers the next steps to
I completely disagree at this point.

So to be clear, the invocation of moddle-layer callbacks instead of
*driver* callbacks in pm_runtime_force_suspend|resume() is a grave mistake.
They would have been almost possible to work with had they just invoke
driver callbacks.

OTOH I'm starting to think that direct_complete is only theoretically useful
and may not be actually set very often in practice, whereas it adds significant
complexity to the code, so I'm not sure about it any more.
achieve a fully optimized behavior of a device during system sleep, as
already been proven by now. It would be great to both options
supported by the ACPI PM domain.
No.
Another related thing that is causing lots of problems during system
sleep of devices, but not related to optimizations, is to have the
correct order of how to suspend/resume the devices. We have talked
about this, but it's a separate problem and it's rather a deployment
issue, than having to implements something entirely new (we have
supplies/consumers links you invented for this).
Yes, that is a separate issue.
quoted
quoted
Now, some complex code always needs to be implemented somewhere. When
using the runtime PM centric path, that code consist of the
pm_runtime_force_suspend|resume() helpers itself - and some
adaptations in buses/PM domains in cases when those needs special
care.

My point is, the runtime PM centric path, allows us to keep the
complex part of the code at a few centralized places, instead of
having it spread/duplicated into drivers.

So yes, you could consider it insane, but to me and many others, it
seems to work out quite well.
Because it only has been used with trivial middle layer code so far
and I'm quite disappointed that you don't seem to see a problem here. :-/

I mean something like

PM core => bus type / PM domain ->suspend_late => driver ->suspend_late

is far more straightforward than

PM core => bus type / PM domain ->suspend_late => driver ->suspend_late =>
        bus type / PM domain ->runtime_suspend => driver ->runtime_suspend

with the bus type / PM domain having to figure out somehow at the
->suspend_late time whether or not its ->runtume_suspend is going to be invoked
in the middle of it.

Apart from this just being aesthetically disgusting to me, which admittedly is
a matter of personal opinion, it makes debugging new driver code harder (if it
happens to not work) and reviewing it almost impossible, because now you need
to take all of the tangling between callbacks into accont and sometimes not
just for one bus type / PM domain.
I am wondering that perhaps you may be overlooking some of the
internals of runtime PM. Or maybe not? :-)

I mean, the hole thing is build upon that anyone can call runtime PM
functions to runtime resume/suspend a device.
Well, right in general, except that _force_suspend/resume() invoke
*callbacks* and *not* runtime PM functions.
Doing that, makes the
hierarchy of the runtime PM callbacks being walked and invoked, of
course properly managed by the runtime PM core.

My point is that, the runtime PM core still controls this behavior,
even when the pm_runtime_force_suspend|resume() helpers are being
invoked. The only difference is that it allows runtime PM for the
device to be disabled, and still correctly invoked the callbacks. That
is what it is all about.
So why is it even useful to call ->runtime_suspend from a middle layer
in pm_runtime_force_suspend(), for example?
quoted
quoted
Yeah, and the laying violation is undoubtedly the most controversial
part of the runtime PM centric path - I agree to that! The
direct_complete path don't have this, as you implemented it. :-)

On the other hand, one could consider that these upper layers, in many
cases anyway needs to play along with the behavior of the driver. So,
I guess it depends on how one see it.
quoted
That's why I'm afraid that we've reached a dead end here. :-(
That's said news. Is was really hoping I could find a way to move this
forward. You don't have any other ideas on how I can adjust the series
to make you happy?
So to be precise, patches [2-3/8] are basically fine by me.  Patch [4/8]
sort of works too, but I'd do the splitting slightly differently and I don't
see much value in it alone.

The rest of the ACPI changes is mostly not acceptable to me, mostly because
of what is done to the PM domain's ->runtime_suspend/resume and
->suspend_late/->resume_early callbacks.

I guess the only way that could be made work for me would be by not using
_force_suspend/resume() at all, but that would defeat the point, right?
Yes, it would.
quoted
I don't like the flag too, but that might be worked out.
Yeah, I am open to any suggestion.
quoted
Also, when I looked at _force_suspend/resume() again, I got concerned.
There is stuff in there that shouldn't be necessary in a driver's
->late_suspend/->early_resume and some things in there just made me
scratch my head.
Yes, there are some complexity in there, I will be happy to answer any
specific question about it.
OK

Of course they require runtime PM to be enabled by drivers using them as
their callbacks, but I suppose that you realize that.

Why to disabe/renable runtime PM in there in the first place?  That should
have been done by the core when these functions are intended to be called.

Second, why to use RPM_GET_CALLBACK in there?

Next, how is the parent actually runtime-resumed by pm_runtime_force_resume()
which the comment in pm_runtime_force_suspend() talks about?
The main thing is, that it tries to conform to the regular rules set
by the runtime PM core when runtime PM is enabled for the device - and
then apply those to the device when runtime PM has been disabled for
it.
Sorry, I'm not sure what this means really ...
Again, thanks for being patient and reviewing!
Well, no problem.

Thanks,
Rafael
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help