All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM list <linux-pm@vger.kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Grant Likely <grant.likely@linaro.org>,
	Mark Brown <broonie@kernel.og>, Rob Herring <robh@kernel.org>,
	Tomeu Vizoso <tomeu.vizoso@collabora.com>,
	Thierry Reding <treding@nvidia.com>,
	Dmitry Torokhov <dtor@google.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Michael Turquette <mturquette@baylibre.com>
Subject: [RFC][PATCH 5/5] PM core: Optimize the use of device links for runtime PM
Date: Thu, 14 Jan 2016 02:56:53 +0100	[thread overview]
Message-ID: <1953764.Cf42Ruii0H@vostro.rjw.lan> (raw)
In-Reply-To: <2576341.476ZsjkPgF@vostro.rjw.lan>

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

If the device has no links to suppliers that should be used for
runtime PM (links with DEVICE_LINK_PM_RUNTIME set), there is no
reason to walk the list of suppliers for that device during
runtime suspend and resume.

Add a simple mechanism to detect that case and possibly avoid the
extra unnecessary overhead.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/core.c          |    6 ++++++
 drivers/base/power/runtime.c |   23 ++++++++++++++++++++---
 include/linux/pm.h           |    1 +
 include/linux/pm_runtime.h   |    4 ++++
 4 files changed, 31 insertions(+), 3 deletions(-)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -596,6 +596,7 @@ struct dev_pm_info {
 	unsigned int		use_autosuspend:1;
 	unsigned int		timer_autosuspends:1;
 	unsigned int		memalloc_noio:1;
+	unsigned int		links_count;
 	enum rpm_request	request;
 	enum rpm_status		runtime_status;
 	int			runtime_error;
Index: linux-pm/drivers/base/power/runtime.c
===================================================================
--- linux-pm.orig/drivers/base/power/runtime.c
+++ linux-pm/drivers/base/power/runtime.c
@@ -270,6 +270,7 @@ static int __rpm_callback(int (*cb)(stru
 {
 	struct devlink *link;
 	int retval, idx;
+	bool use_links = dev->power.links_count > 0;
 
 	if (dev->power.irq_safe) {
 		spin_unlock(&dev->power.lock);
@@ -283,7 +284,7 @@ static int __rpm_callback(int (*cb)(stru
 		 * routine returns, so it is safe to read the status outside of
 		 * the lock.
 		 */
-		if (dev->power.runtime_status == RPM_RESUMING) {
+		if (use_links && dev->power.runtime_status == RPM_RESUMING) {
 			idx = device_links_read_lock();
 
 			list_for_each_entry_rcu(link, &dev->consumer_links, c_node)
@@ -314,8 +315,9 @@ static int __rpm_callback(int (*cb)(stru
 		 *
 		 * Do that if resume fails too.
 		 */
-		if ((dev->power.runtime_status == RPM_SUSPENDING && !retval)
-		    || (dev->power.runtime_status == RPM_RESUMING && retval)) {
+		if (use_links
+		    && ((dev->power.runtime_status == RPM_SUSPENDING && !retval)
+		    || (dev->power.runtime_status == RPM_RESUMING && retval))) {
 			idx = device_links_read_lock();
 
  fail:
@@ -1525,6 +1527,21 @@ void pm_runtime_clean_up_links(struct de
 	device_links_read_unlock(idx);
 }
 
+void pm_runtime_new_link(struct device *dev)
+{
+	spin_lock_irq(&dev->power.lock);
+	dev->power.links_count++;
+	spin_unlock_irq(&dev->power.lock);
+}
+
+void pm_runtime_drop_link(struct device *dev)
+{
+	spin_lock_irq(&dev->power.lock);
+	WARN_ON(dev->power.links_count == 0);
+	dev->power.links_count--;
+	spin_unlock_irq(&dev->power.lock);
+}
+
 /**
  * pm_runtime_force_suspend - Force a device into suspend state if needed.
  * @dev: Device to suspend.
Index: linux-pm/include/linux/pm_runtime.h
===================================================================
--- linux-pm.orig/include/linux/pm_runtime.h
+++ linux-pm/include/linux/pm_runtime.h
@@ -56,6 +56,8 @@ extern void pm_runtime_update_max_time_s
 						 s64 delta_ns);
 extern void pm_runtime_set_memalloc_noio(struct device *dev, bool enable);
 extern void pm_runtime_clean_up_links(struct device *dev);
+extern void pm_runtime_new_link(struct device *dev);
+extern void pm_runtime_drop_link(struct device *dev);
 
 static inline bool pm_children_suspended(struct device *dev)
 {
@@ -182,6 +184,8 @@ static inline unsigned long pm_runtime_a
 static inline void pm_runtime_set_memalloc_noio(struct device *dev,
 						bool enable){}
 static inline void pm_runtime_clean_up_links(struct device *dev) {}
+static inline void pm_runtime_new_link(struct device *dev) {}
+static inline void pm_runtime_drop_link(struct device *dev) {}
 
 #endif /* !CONFIG_PM */
 
Index: linux-pm/drivers/base/core.c
===================================================================
--- linux-pm.orig/drivers/base/core.c
+++ linux-pm/drivers/base/core.c
@@ -119,6 +119,9 @@ struct devlink *device_link_add(struct d
 	get_device(consumer);
 	link->consumer = consumer;
 	INIT_LIST_HEAD(&link->c_node);
+	if (flags & DEVICE_LINK_PM_RUNTIME)
+		pm_runtime_new_link(consumer);
+
 	link->flags = flags;
 	link->status = (flags & DEVICE_LINK_PROBE_TIME) ?
 			DEVICE_LINK_CONSUMER_PROBE : DEVICE_LINK_DORMANT;
@@ -161,6 +164,9 @@ static void devlink_del(struct devlink *
 	dev_info(link->consumer, "Dropping the link to %s\n",
 		 dev_name(link->supplier));
 
+	if (link->flags & DEVICE_LINK_PM_RUNTIME)
+		pm_runtime_drop_link(link->consumer);
+
 	list_del_rcu(&link->s_node);
 	list_del_rcu(&link->c_node);
 	call_srcu(&device_links_srcu, &link->rcu_head, __devlink_free_srcu);

  parent reply	other threads:[~2016-01-14  1:56 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-27 15:24 [RFD] Functional dependencies between devices Rafael J. Wysocki
2015-10-27 15:20 ` Tomeu Vizoso
2015-10-28  2:15   ` Rafael J. Wysocki
2015-10-28 14:26     ` Tomeu Vizoso
2015-10-28 15:54       ` Rafael J. Wysocki
2015-10-29  0:18         ` Mark Brown
2015-10-29 14:03         ` Tomeu Vizoso
2015-10-29 14:31           ` Alan Stern
2015-10-31  2:23             ` Rafael J. Wysocki
2015-10-31 15:22               ` Alan Stern
2015-10-29  0:15 ` Mark Brown
2015-10-31  2:13   ` Rafael J. Wysocki
2015-10-31  2:40     ` Mark Brown
2015-10-30  9:50 ` Linus Walleij
2015-10-30 22:52 ` Greg Kroah-Hartman
2016-01-07 14:55   ` Tomeu Vizoso
2016-01-07 21:29     ` Greg Kroah-Hartman
2016-01-08  7:28       ` Tomeu Vizoso
2016-01-08 15:15         ` Greg Kroah-Hartman
2015-11-09 12:32 ` Thierry Reding
2015-11-09 21:42   ` Rafael J. Wysocki
2015-11-17 12:44 ` Andrzej Hajda
2015-11-18  2:17   ` Rafael J. Wysocki
2015-11-19  9:08     ` Andrzej Hajda
2015-11-19 22:04       ` Rafael J. Wysocki
2015-11-20  1:11         ` Rafael J. Wysocki
2015-11-24 14:57         ` Andrzej Hajda
2015-11-24 16:28           ` Rafael J. Wysocki
2015-11-30  7:16             ` Andrzej Hajda
2015-11-17 12:49 ` Andrzej Hajda
2015-11-17 13:55   ` Mark Brown
2015-11-19  6:50     ` Andrzej Hajda
2015-11-21 14:04       ` Mark Brown
2015-11-24 13:56         ` Andrzej Hajda
2015-11-19 13:18     ` Thierry Reding
2015-11-21 13:26       ` Mark Brown
2015-11-17 20:31   ` Alan Stern
2015-11-17 22:47     ` Mark Brown
2016-01-14  1:52 ` [RFC][PATCH 0/5] " Rafael J. Wysocki
2016-01-14  1:53   ` [RFC][PATCH 1/5] driver core: Add a wrapper around __device_release_driver() Rafael J. Wysocki
2016-01-14  1:54   ` [RFC][PATCH 2/5] driver core: Functional dependencies tracking support Rafael J. Wysocki
2016-06-08 12:48     ` Mark Brown
2016-06-08 18:12       ` Rafael J. Wysocki
2016-06-08 18:35         ` Mark Brown
2016-06-08 20:48           ` Rafael J. Wysocki
2016-06-08 22:24             ` Mark Brown
2016-01-14  1:55   ` [RFC][PATCH 3/5] PM core: Make async suspend/resume of devices use device links Rafael J. Wysocki
2016-06-08 12:59     ` Mark Brown
2016-01-14  1:56   ` [RFC][PATCH 4/5] PM core: Make runtime PM " Rafael J. Wysocki
2016-01-14  1:56   ` Rafael J. Wysocki [this message]
2016-01-14 14:19   ` [RFC][PATCH 0/5] Functional dependencies between devices Tomeu Vizoso
2016-01-15  0:44     ` Rafael J. Wysocki
2016-06-08 12:15   ` Mark Brown
2016-06-08 17:24     ` Rafael J. Wysocki
2016-06-08 17:33       ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1953764.Cf42Ruii0H@vostro.rjw.lan \
    --to=rjw@rjwysocki.net \
    --cc=broonie@kernel.og \
    --cc=dtor@google.com \
    --cc=geert@linux-m68k.org \
    --cc=grant.likely@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=robh@kernel.org \
    --cc=stern@rowland.harvard.edu \
    --cc=tomeu.vizoso@collabora.com \
    --cc=treding@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.