From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Alan Stern <stern@rowland.harvard.edu>,
Ulf Hansson <ulf.hansson@linaro.org>,
Johan Hovold <johan@kernel.org>,
Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>,
Saravana Kannan <saravanak@google.com>
Subject: [PATCH v1 5/5] PM: sleep: Make late and noirq suspend of devices more asynchronous
Date: Tue, 25 Feb 2025 17:45:37 +0100 [thread overview]
Message-ID: <2016539.usQuhbGJ8B@rjwysocki.net> (raw)
In-Reply-To: <13709135.uLZWGnKmhe@rjwysocki.net>
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
In analogy with previous changes, make device_suspend_late() and
device_suspend_noirq() start the async suspend of the device's parent
and suppliers after the device itself has been processed and make
dpm_suspend_late() and dpm_noirq_suspend_devices() start processing
"async" leaf devices (that is, devices without children or consumers)
upfront because they don't need to wait for any other devices.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/base/power/main.c | 60 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 52 insertions(+), 8 deletions(-)
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -1317,6 +1317,8 @@
device_links_read_unlock(idx);
}
+static void async_suspend_noirq(void *data, async_cookie_t cookie);
+
/**
* device_suspend_noirq - Execute a "noirq suspend" callback for given device.
* @dev: Device to handle.
@@ -1396,7 +1398,13 @@
Complete:
complete_all(&dev->power.completion);
TRACE_SUSPEND(error);
- return error;
+
+ if (error || async_error)
+ return error;
+
+ dpm_async_suspend_superior(dev, async_suspend_noirq);
+
+ return 0;
}
static void async_suspend_noirq(void *data, async_cookie_t cookie)
@@ -1410,6 +1418,7 @@
static int dpm_noirq_suspend_devices(pm_message_t state)
{
ktime_t starttime = ktime_get();
+ struct device *dev;
int error = 0;
trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true);
@@ -1419,15 +1428,28 @@
mutex_lock(&dpm_list_mtx);
+ /*
+ * Start processing "async" leaf devices upfront because they don't need
+ * to wait.
+ */
+ list_for_each_entry_reverse(dev, &dpm_late_early_list, power.entry) {
+ dpm_clear_async_state(dev);
+ if (dpm_leaf_device(dev))
+ dpm_async_fn(dev, async_suspend_noirq);
+ }
+
while (!list_empty(&dpm_late_early_list)) {
- struct device *dev = to_device(dpm_late_early_list.prev);
+ dev = to_device(dpm_late_early_list.prev);
list_move(&dev->power.entry, &dpm_noirq_list);
- dpm_clear_async_state(dev);
- if (dpm_async_fn(dev, async_suspend_noirq))
+ dpm_async_unless_in_progress(dev, async_suspend_noirq);
+
+ if (dev->power.work_in_progress)
continue;
+ dev->power.work_in_progress = true;
+
get_device(dev);
mutex_unlock(&dpm_list_mtx);
@@ -1492,6 +1514,8 @@
spin_unlock_irq(&parent->power.lock);
}
+static void async_suspend_late(void *data, async_cookie_t cookie);
+
/**
* device_suspend_late - Execute a "late suspend" callback for given device.
* @dev: Device to handle.
@@ -1568,7 +1592,13 @@
Complete:
TRACE_SUSPEND(error);
complete_all(&dev->power.completion);
- return error;
+
+ if (error || async_error)
+ return error;
+
+ dpm_async_suspend_superior(dev, async_suspend_late);
+
+ return 0;
}
static void async_suspend_late(void *data, async_cookie_t cookie)
@@ -1586,6 +1616,7 @@
int dpm_suspend_late(pm_message_t state)
{
ktime_t starttime = ktime_get();
+ struct device *dev;
int error = 0;
trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true);
@@ -1597,15 +1628,28 @@
mutex_lock(&dpm_list_mtx);
+ /*
+ * Start processing "async" leaf devices upfront because they don't need
+ * to wait.
+ */
+ list_for_each_entry_reverse(dev, &dpm_suspended_list, power.entry) {
+ dpm_clear_async_state(dev);
+ if (dpm_leaf_device(dev))
+ dpm_async_fn(dev, async_suspend_late);
+ }
+
while (!list_empty(&dpm_suspended_list)) {
- struct device *dev = to_device(dpm_suspended_list.prev);
+ dev = to_device(dpm_suspended_list.prev);
list_move(&dev->power.entry, &dpm_late_early_list);
- dpm_clear_async_state(dev);
- if (dpm_async_fn(dev, async_suspend_late))
+ dpm_async_unless_in_progress(dev, async_suspend_late);
+
+ if (dev->power.work_in_progress)
continue;
+ dev->power.work_in_progress = true;
+
get_device(dev);
mutex_unlock(&dpm_list_mtx);
next prev parent reply other threads:[~2025-02-25 16:46 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-25 16:38 [PATCH v1 0/5] PM: sleep: Improvements of async suspend and resume of devices Rafael J. Wysocki
2025-02-25 16:38 ` [PATCH v1 1/5] PM: sleep: Rename power.async_in_progress to power.work_in_progress Rafael J. Wysocki
2025-02-25 16:39 ` [PATCH v1 2/5] PM: sleep: Rearrange dpm_async_fn() and async state clearing Rafael J. Wysocki
2025-02-25 16:45 ` [PATCH v1 3/5] PM: sleep: Resume children right after resuming the parent Rafael J. Wysocki
2025-03-13 1:46 ` Saravana Kannan
2025-03-13 15:16 ` Rafael J. Wysocki
2025-02-25 16:45 ` [PATCH v1 4/5] PM: sleep: Start suspending parents and suppliers after subordinate suspend Rafael J. Wysocki
2025-03-13 1:46 ` Saravana Kannan
2025-03-13 13:53 ` Rafael J. Wysocki
2025-02-25 16:45 ` Rafael J. Wysocki [this message]
2025-03-13 1:47 ` [PATCH v1 5/5] PM: sleep: Make late and noirq suspend of devices more asynchronous Saravana Kannan
2025-03-13 13:32 ` Rafael J. Wysocki
2025-02-27 15:44 ` [PATCH v1 0/5] PM: sleep: Improvements of async suspend and resume of devices Saravana Kannan
2025-02-27 16:23 ` Rafael J. Wysocki
2025-03-09 22:37 ` Saravana Kannan
2025-03-10 16:01 ` Rafael J. Wysocki
2025-03-10 20:31 ` Saravana Kannan
2025-03-10 21:29 ` Rafael J. Wysocki
2025-03-03 12:06 ` Ulf Hansson
2025-03-03 12:08 ` Rafael J. Wysocki
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=2016539.usQuhbGJ8B@rjwysocki.net \
--to=rjw@rjwysocki.net \
--cc=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=manivannan.sadhasivam@linaro.org \
--cc=saravanak@google.com \
--cc=stern@rowland.harvard.edu \
--cc=ulf.hansson@linaro.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox