linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] PM / Runtime: Fix error path for prepare
@ 2013-11-15 11:40 Ulf Hansson
  2013-11-15 11:40 ` [RFC PATCH 2/2] PM / Runtime: Allow devices to become inactive during system suspend Ulf Hansson
  2013-11-15 15:14 ` [PATCH 1/2] PM / Runtime: Fix error path for prepare Rafael J. Wysocki
  0 siblings, 2 replies; 3+ messages in thread
From: Ulf Hansson @ 2013-11-15 11:40 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, linux-pm
  Cc: Greg Kroah-Hartman, linux-pci, linux-usb, Ulf Hansson,
	Kevin Hilman, Alan Stern

If a device prepare callback for some reason would fail, the PM core
prevented the device from going inactive forever.

In this case, to reverse the pm_runtime_get_noresume() we invokes the
asyncronous pm_runtime_put(), thus restoring the usage count.

Cc: Kevin Hilman <khilman@linaro.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/main.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index ee039af..2a1b06a 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1350,6 +1350,9 @@ static int device_prepare(struct device *dev, pm_message_t state)
 
 	device_unlock(dev);
 
+	if (error)
+		pm_runtime_put(dev);
+
 	return error;
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC PATCH 2/2] PM / Runtime: Allow devices to become inactive during system suspend
  2013-11-15 11:40 [PATCH 1/2] PM / Runtime: Fix error path for prepare Ulf Hansson
@ 2013-11-15 11:40 ` Ulf Hansson
  2013-11-15 15:14 ` [PATCH 1/2] PM / Runtime: Fix error path for prepare Rafael J. Wysocki
  1 sibling, 0 replies; 3+ messages in thread
From: Ulf Hansson @ 2013-11-15 11:40 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown, Pavel Machek, linux-pm
  Cc: Greg Kroah-Hartman, linux-pci, linux-usb, Ulf Hansson,
	Kevin Hilman, Alan Stern

The PM core was unconditionally preventing devices from being runtime
suspended during system suspend. The reason is that we don't want
asynchronous runtime suspends to happen during system suspend and thus
race with the system suspend process, which some drivers and buses are
not able to handle.

However, for drivers that don't have issues with the races above, are
somewhat suffering from the constraints this cause and then need to
inactivate their devices outside the runtime PM control during system
suspend. In other words, those implements .suspend|suspend_late
callbacks to handle this.

To simplify for these drivers, we add new runtime PM API,
pm_runtime_no_prevent_suspend(), which drivers typically should call
from their probe routines to tell PM core that it must not prevent
runtime suspend during system suspend. Additonally the PM core will
in this case instead invode the pm_runtime_idle just before it shall
disable runtime PM in suspend_late.

Drivers making use if this feature are then able to trigger runtime
suspend with for example a pm_runtime_put_sync from their .suspend
callbacks. Additionally, for drivers that are able to cope with only
runtime PM callbacks, these can rely on the PM core to trigger a
runtime suspend (if the runtime PM usage count doesn't prevent it)
to inactivate their devices during system suspend.

Cc: Kevin Hilman <khilman@linaro.org>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Some discussion started recently while I posted below patch:
[RFC PATCH] PM / Runtime: Allow to inactivate devices during system suspend

After some thinking I decided to cook another RFC, that might be better
material for discussion. If we decide to go in this direction, the doc
obviously needs some update as well, which is not a part of this RFC yet.

---
 drivers/base/power/main.c    |   13 ++++++++++---
 drivers/base/power/runtime.c |    1 +
 include/linux/pm.h           |    1 +
 include/linux/pm_runtime.h   |   13 +++++++++++++
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 2a1b06a..838ebb6 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -832,7 +832,10 @@ static void device_complete(struct device *dev, pm_message_t state)
 
 	device_unlock(dev);
 
-	pm_runtime_put(dev);
+	if (pm_runtime_suspend_prevented(dev))
+		pm_runtime_put(dev);
+	else
+		pm_request_idle(dev);
 }
 
 /**
@@ -1004,6 +1007,9 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
 	pm_callback_t callback = NULL;
 	char *info = NULL;
 
+	if (!pm_runtime_suspend_prevented(dev))
+		pm_runtime_idle(dev);
+
 	__pm_runtime_disable(dev, false);
 
 	if (dev->power.syscore)
@@ -1318,7 +1324,8 @@ static int device_prepare(struct device *dev, pm_message_t state)
 	 * block runtime suspend here, during the prepare phase, and allow
 	 * it again during the complete phase.
 	 */
-	pm_runtime_get_noresume(dev);
+	if (pm_runtime_suspend_prevented(dev))
+		pm_runtime_get_noresume(dev);
 
 	device_lock(dev);
 
@@ -1350,7 +1357,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
 
 	device_unlock(dev);
 
-	if (error)
+	if (error && pm_runtime_suspend_prevented(dev))
 		pm_runtime_put(dev);
 
 	return error;
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 72e00e6..bdac1e2 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1373,6 +1373,7 @@ void pm_runtime_init(struct device *dev)
 	atomic_set(&dev->power.child_count, 0);
 	pm_suspend_ignore_children(dev, false);
 	dev->power.runtime_auto = true;
+	dev->power.prevent_suspend = true;
 
 	dev->power.request_pending = false;
 	dev->power.request = RPM_REQ_NONE;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index a224c7f..98ef412 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -551,6 +551,7 @@ struct dev_pm_info {
 	unsigned int		use_autosuspend:1;
 	unsigned int		timer_autosuspends:1;
 	unsigned int		memalloc_noio:1;
+	unsigned int		prevent_suspend:1;
 	enum rpm_request	request;
 	enum rpm_status		runtime_status;
 	int			runtime_error;
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 6fa7cea..2b72e30 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -106,6 +106,16 @@ static inline void pm_runtime_mark_last_busy(struct device *dev)
 	ACCESS_ONCE(dev->power.last_busy) = jiffies;
 }
 
+static inline void pm_runtime_no_prevent_suspend(struct device *dev)
+{
+	dev->power.prevent_suspend = false;
+}
+
+static inline bool pm_runtime_suspend_prevented(struct device *dev)
+{
+	return dev->power.prevent_suspend;
+}
+
 #else /* !CONFIG_PM_RUNTIME */
 
 static inline int __pm_runtime_idle(struct device *dev, int rpmflags)
@@ -157,6 +167,9 @@ static inline unsigned long pm_runtime_autosuspend_expiration(
 				struct device *dev) { return 0; }
 static inline void pm_runtime_set_memalloc_noio(struct device *dev,
 						bool enable){}
+static inline void pm_runtime_no_prevent_suspend(struct device *dev) {}
+static inline bool pm_runtime_suspend_prevented(struct device *dev)
+						{ return false; }
 
 #endif /* !CONFIG_PM_RUNTIME */
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/2] PM / Runtime: Fix error path for prepare
  2013-11-15 11:40 [PATCH 1/2] PM / Runtime: Fix error path for prepare Ulf Hansson
  2013-11-15 11:40 ` [RFC PATCH 2/2] PM / Runtime: Allow devices to become inactive during system suspend Ulf Hansson
@ 2013-11-15 15:14 ` Rafael J. Wysocki
  1 sibling, 0 replies; 3+ messages in thread
From: Rafael J. Wysocki @ 2013-11-15 15:14 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Len Brown, Pavel Machek, linux-pm, Greg Kroah-Hartman, linux-pci,
	linux-usb, Kevin Hilman, Alan Stern

On Friday, November 15, 2013 12:40:44 PM Ulf Hansson wrote:
> If a device prepare callback for some reason would fail, the PM core
> prevented the device from going inactive forever.
> 
> In this case, to reverse the pm_runtime_get_noresume() we invokes the
> asyncronous pm_runtime_put(), thus restoring the usage count.
> 
> Cc: Kevin Hilman <khilman@linaro.org>
> Cc: Alan Stern <stern@rowland.harvard.edu>
> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

This should be in linux-next already.

Thanks!

> ---
>  drivers/base/power/main.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index ee039af..2a1b06a 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -1350,6 +1350,9 @@ static int device_prepare(struct device *dev, pm_message_t state)
>  
>  	device_unlock(dev);
>  
> +	if (error)
> +		pm_runtime_put(dev);
> +
>  	return error;
>  }
>  
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-11-15 15:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-15 11:40 [PATCH 1/2] PM / Runtime: Fix error path for prepare Ulf Hansson
2013-11-15 11:40 ` [RFC PATCH 2/2] PM / Runtime: Allow devices to become inactive during system suspend Ulf Hansson
2013-11-15 15:14 ` [PATCH 1/2] PM / Runtime: Fix error path for prepare Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).