From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>,
Ulf Hansson <ulf.hansson@linaro.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Alan Stern <stern@rowland.harvard.edu>,
Johan Hovold <johan@kernel.org>,
Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>,
Jon Hunter <jonathanh@nvidia.com>,
Tony Lindgren <tony.lindgren@linux.intel.com>
Subject: [PATCH v1 08/10] PM: sleep: Make pm_runtime_force_resume() look at power.set_active
Date: Tue, 11 Feb 2025 22:19:13 +0100 [thread overview]
Message-ID: <3817761.MHq7AAxBmi@rjwysocki.net> (raw)
In-Reply-To: <2314745.iZASKD2KPV@rjwysocki.net>
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
In theory (and also in practice after a change to come),
pm_runtime_force_resume() can be called on a device with power.set_active
set, in which case the core has already called pm_runtime_set_active()
on it, and power.needs_force_resume may be clear. This happens when the
core decides to resume a device because new information on it has become
available during the "noirq" phase of system-wide suspend.
In order to handle that case properly, make pm_runtime_force_resume()
look at power.set_active in addition to power.needs_force_resume, so it
does not skip the device when the former is set. Namely, make it invoke
the callback for the device then, but without disabling the wake IRQ if
pm_runtime_force_resume() has not enabled it. Also clear power.set_active
in pm_runtime_force_resume() to prevent it from being taken into account
twice in a row.
Additionally, adjust the pm_runtime_force_resume() kerneldoc comment
and the code comments inside it. Moreover, remove a remark regarding
DPM_FLAG_SMART_SUSPEND from the pm_runtime_force_suspend() kerneldoc
comment because it is not valid any more after this change.
This change is not expected to alter the behavior in the case when
power.needs_force_resume is set.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
Unfortunately, I have not found a way to do this without adding
a new device PM flag and now there are 2 flags specifically for
pm_runtime_force_suspend/resume() which is a bit sad.
Questions for Ulf:
(1) How is the enabling of wakeirqs handled for devices that are runtime-
suspended before system suspend, so pm_runtime_force_suspend() skips
them?
(2) What is supposed to happen to wakeirqs during system resume after
pm_runtime_force_suspend() has enabled them, but hasn't set
power.needs_force_resume at the same time?
---
drivers/base/power/runtime.c | 41 ++++++++++++++++++++++++++---------------
include/linux/pm.h | 1 +
2 files changed, 27 insertions(+), 15 deletions(-)
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1897,10 +1897,6 @@
* sure the device is put into low power state and it should only be used during
* system-wide PM transitions to sleep states. It assumes that the analogous
* pm_runtime_force_resume() will be used to resume the device.
- *
- * Do not use with DPM_FLAG_SMART_SUSPEND as this can lead to an inconsistent
- * state where this function has called the ->runtime_suspend callback but the
- * PM core marks the driver as runtime active.
*/
int pm_runtime_force_suspend(struct device *dev)
{
@@ -1923,6 +1919,7 @@
goto err;
dev_pm_enable_wake_irq_complete(dev);
+ dev->power.wake_irq_enabled = true;
/*
* If the device can stay in suspend after the system-wide transition
@@ -1950,31 +1947,39 @@
* pm_runtime_force_resume - Force a device into resume state if needed.
* @dev: Device to resume.
*
- * Prior invoking this function we expect the user to have brought the device
- * into low power state by a call to pm_runtime_force_suspend(). Here we reverse
- * those actions and bring the device into full power, if it is expected to be
- * used on system resume. In the other case, we defer the resume to be managed
- * via runtime PM.
+ * The primary role of this function is to reverse the actions carried out by
+ * pm_runtime_force_suspend() for @dev, so it must always be balanced with a
+ * matching invocation of the latter. Accordingly, it is only valid to call
+ * this function during system-wide resume transitions.
+ *
+ * Typically, it is used as a system resume callback of a device driver.
*
- * Typically this function may be invoked from a system resume callback.
+ * However, if @dev had been runtime-suspended before pm_runtime_force_suspend()
+ * was called for it and that function did nothing, but power.set_active has
+ * been set for it by the core, it still needs to be resumed. That special case
+ * is also handled by this function.
*/
int pm_runtime_force_resume(struct device *dev)
{
int (*callback)(struct device *);
int ret = 0;
- if (!dev->power.needs_force_resume)
+ if (!dev->power.needs_force_resume && !dev->power.set_active)
goto out;
/*
- * The value of the parent's children counter is correct already, so
- * just update the status of the device.
+ * The parent's active children counter an the suppliers' usage counters
+ * are correct already, so just update the status (even though it is
+ * already RPM_ACTIVE if power.set_active is set).
*/
__update_runtime_status(dev, RPM_ACTIVE);
- callback = RPM_GET_CALLBACK(dev, runtime_resume);
+ if (dev->power.wake_irq_enabled) {
+ dev_pm_disable_wake_irq_check(dev, false);
+ dev->power.wake_irq_enabled = false;
+ }
- dev_pm_disable_wake_irq_check(dev, false);
+ callback = RPM_GET_CALLBACK(dev, runtime_resume);
ret = callback ? callback(dev) : 0;
if (ret) {
pm_runtime_set_suspended(dev);
@@ -1982,6 +1987,12 @@
}
pm_runtime_mark_last_busy(dev);
+ /*
+ * Clear power.set_active in case this function runs for the same
+ * device again.
+ */
+ dev->power.set_active = false;
+
out:
dev->power.needs_force_resume = 0;
pm_runtime_enable(dev);
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -698,6 +698,7 @@
bool request_pending:1;
bool deferred_resume:1;
bool needs_force_resume:1;
+ bool wake_irq_enabled:1;
bool runtime_auto:1;
bool ignore_children:1;
bool no_callbacks:1;
next prev parent reply other threads:[~2025-02-11 21:25 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-11 21:01 [PATCH v1 00/10] PM: Make the core and pm_runtime_force_suspend/resume() agree more Rafael J. Wysocki
2025-02-11 21:02 ` [PATCH v1 01/10] PM: runtime: Introduce pm_runtime_no_support() Rafael J. Wysocki
2025-02-11 21:03 ` [PATCH v1 02/10] PM: sleep: core: Use pm_runtime_no_support() during set_active updates Rafael J. Wysocki
2025-02-11 21:05 ` [PATCH v1 03/10] PM: runtime: Use pm_runtime_no_support() in pm_runtime_force_suspend() Rafael J. Wysocki
2025-02-11 21:07 ` [PATCH v1 04/10] PM: runtime: Drop status check from pm_runtime_force_resume() Rafael J. Wysocki
2025-02-11 21:09 ` [PATCH v1 05/10] PM: runtime: Do not enable wakeup IRQs during system resume Rafael J. Wysocki
2025-02-11 21:10 ` [PATCH v1 06/10] PM: sleep: Adjust check before setting power.must_resume Rafael J. Wysocki
2025-02-11 21:11 ` [PATCH v1 07/10] PM: sleep: Clear the power.set_active upfront Rafael J. Wysocki
2025-02-11 21:19 ` Rafael J. Wysocki [this message]
2025-02-11 21:21 ` [PATCH v1 09/10] PM: sleep: Propagate power.set_active in dependency chains Rafael J. Wysocki
2025-02-11 21:25 ` [PATCH v1 10/10] PM: runtime: Discover the lack of runtime PM support Rafael J. Wysocki
2025-02-12 11:14 ` Rafael J. Wysocki
2025-02-12 9:12 ` [PATCH v1 00/10] PM: Make the core and pm_runtime_force_suspend/resume() agree more Ulf Hansson
2025-02-12 10:59 ` Rafael J. Wysocki
2025-02-12 11:33 ` Rafael J. Wysocki
2025-02-12 11:36 ` Rafael J. Wysocki
2025-02-12 15:14 ` Ulf Hansson
2025-02-12 17:05 ` Rafael J. Wysocki
2025-02-12 19:04 ` Rafael J. Wysocki
2025-02-13 13:37 ` Ulf Hansson
2025-02-13 20:42 ` Rafael J. Wysocki
2025-02-13 13:10 ` Ulf Hansson
2025-02-13 20:17 ` Rafael J. Wysocki
2025-02-14 9:55 ` Ulf Hansson
2025-02-15 12:32 ` 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=3817761.MHq7AAxBmi@rjwysocki.net \
--to=rjw@rjwysocki.net \
--cc=johan@kernel.org \
--cc=jonathanh@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=manivannan.sadhasivam@linaro.org \
--cc=stern@rowland.harvard.edu \
--cc=tony.lindgren@linux.intel.com \
--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