Thread (2 messages) flat view 2 messages, 2 authors, 2015-05-11

[PATCH/RFC] PM / Domains: Minimize latencies by not delaying save/restore

From: Russell King - ARM Linux <hidden>
Date: 2015-05-11 14:41:03
Also in: linux-pm

On Mon, May 11, 2015 at 03:24:33PM +0200, Ulf Hansson wrote:
This patch actually address two issues which exists due to the current
policy of how genpd deals with devices' ->runtime_suspend|resume()
callbacks.

The two issues are described below.

Issue 1) A thundering herd problem with latencies issues:

Currently genpd delays to walk the hierarchy of ->runtime_suspend()
callbacks for a device, until all devices in a PM domain becomes
inactive.

Support for fine grained PM is instead handled via the gpd_dev_ops'
->stop|start() callbacks. The ->stop() callback is invoked immediately
when genpd's ->runtime_suspend() callback is called at the PM domain
level.
These two paragraphs seem to be contradictory.  I think the first is
telling me that genpd waits until all devices have become inactive
before walking the hierarchy of ->runtime_suspend callbacks[*] for a
device.  As this waits for all devices to become inactivate, this is
not fine grained.  The second paragraph tells me that genpd's ->stop
method is called from the genpd's ->runtime_suspend(), but this is
fine grained... that's confusing.  As I'm not sure what you're trying
to say here, maybe it'd help if you replaced "->runtime_suspend()
callback" with the actual function name so the two ->runtime_suspend()
references don't get confused.  IOW, pm_genpd_runtime_suspend.

Second point here is that "->runtime_suspend callbacks for a device".
Why plural?  Can a single device have more than one runtime_suspend
callback?  My understanding is that a struct device can have up to one
struct device_driver, and there will be one dev_pm_ops available for
use, which may come from one of several sources (device driver, bus
type, device class, etc.)
When genpd realizes that all devices have become inactive within the PM
domain, it starts the power off sequence.

Those devices that were re-activated since the last powered off
sequence, needs to be given the opportunity to have their register
context saved. That means walking the hierarchy of the devices'
->runtime_suspend() callbacks.
There's, no, need, for, a, comma, there.  It's just confusing and makes
it harder to read.
Though, genpd first need to invoke the ->start() callbacks, else
drivers/subsystems won't be able to save their devices' register
context.
Can we please have the above worded a little clearer?  How does this
relate to the previous paragraphs?  This description makes it unclear
at what point this action is required.  Is this talking about the point
where a device is being re-activated, or are we still talking about
the powering down sequence mentioned three paragraphs above?
After invoking the ->start() and then ->runtime_suspend() callback,
genpd again needs to invoke the ->stop() callback. A sequence which
is repeated for each of the re-activated devices within the PM domain,
during the power off sequence.
Hang on, if the ->stop() callback was already called because of a
genpd's ->runtime_suspend() method being called, but which
->runtime_suspend are we talking about here.  Confused.
This leads to a suboptimal power off sequence, both from the
perspective that the ->start|stop() callback needs to be invoked but
also because all operations are serialized. It simply causes a
thundering herd problem and gives latency issues.

To elaborate on the latency issues, let's follow the below scenario.

	* Device [A] and [B] lives in the same generic PM domain.

	* Device [A] has been re-activated and has recently also become
	inactive, which means genpd has invoked the ->stop() callback
	for it and started the power off sequence.
I'm not sure what "also" has to do with anything here.  What action is
"also" referring to?  Maybe this is sufficient:

	* Device [A] has recently become inactive, causing genpd to
	invoke the PM domain's stop() method, which starts the power
	off sequence via pm_genpd_poweroff().

(That's another thing... providing actual function names in the
description allow people to refer to the code and follow your
problem description.)
	* Then someone calls pm_runtime_get_sync() for the inactive
	device [B]. The ongoing power off sequence should thus be
	aborted as soon as possible.

	* In this scenario the actual PM domain hasn't yet been powered
	off, but instead the power off sequence calls
	__pm_genpd_save_device() for device [A].

	* In parallel genpd's ->runtime_resume() callback at the PM
	domain level is invoked for device [B]. It notifies the power
	off sequence to abort, which needs confirmation to be able to
	continue.

	* Unfortunate, aborting the power off sequence won't be
	confirmed until device [A] has been powered off through
	__pm_genpd_save_device().

In this scenario, device [B] will be waiting for device [A] to complete
->start(), ->runtime_suspend() and ->stop(), which are invoked from
__pm_genpd_save_device(). In other words, device [B]'s
->runtime_resume() latency will be extended with device [A]'s time to
complete power off.

To move this reasoning a step further, it means all devices within the
same generic PM domain suffers from an increased ->runtime_resume()
latency. Moreover, that extended latency comes from the device with the
slowest power off sequence.

This behavior in genpd, is a consequence from that the power off
sequence needs to protect itself by using locks and states. Therefore
can an abort only be confirmed in between calls to
__pm_genpd_save_device().
Really, this English needs to be improved... I'm not sure I follow what
you're trying to say in this mail thus far, and the above paragraph makes
very little sense, and like previous ones, is gramatically wrong - there
should be no comma between "genpd" and "is", but it is generally accepted
that a comma always follows "Therefore".  "can an abort" makes zero sense,
maybe you meant "Therefore, an abort can only be..."

I'm giving up at this point... a description which can't be understood is
useless, sorry.

Please try again.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help