+++ /dev/null
-From 1856343e6435d557ab04729f9707bc14b961039a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Jan 2025 20:24:41 +0100
-Subject: PM: sleep: core: Synchronize runtime PM status of parents and
- children
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
-
-Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
-resume phase") overlooked the case in which the parent of a device with
-DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
-suspended before a transition into a system-wide sleep state. In that
-case, if the child is resumed during the subsequent transition from
-that state into the working state, its runtime PM status will be set to
-RPM_ACTIVE, but the runtime PM status of the parent will not be updated
-accordingly, even though the parent will be resumed too, because of the
-dev_pm_skip_suspend() check in device_resume_noirq().
-
-Address this problem by tracking the need to set the runtime PM status
-to RPM_ACTIVE during system-wide resume transitions for devices with
-DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
-
-Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
-Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@hovoldconsulting.com/
-Reported-by: Johan Hovold <johan@kernel.org>
-Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
-Tested-by: Johan Hovold <johan+linaro@kernel.org>
-Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 29 ++++++++++++++++++++---------
- include/linux/pm.h | 1 +
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 07f561e17b637..39646b27f2fb0 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -618,13 +618,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
- * so change its status accordingly.
- *
- * Otherwise, the device is going to be resumed, so set its PM-runtime
-- * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-- * to avoid confusing drivers that don't use it.
-+ * status to "active" unless its power.set_active flag is clear, in
-+ * which case it is not necessary to update its PM-runtime status.
- */
-- if (skip_resume)
-+ if (skip_resume) {
- pm_runtime_set_suspended(dev);
-- else if (dev_pm_skip_suspend(dev))
-+ } else if (dev->power.set_active) {
- pm_runtime_set_active(dev);
-+ dev->power.set_active = false;
-+ }
-
- if (dev->pm_domain) {
- info = "noirq power domain ";
-@@ -1176,18 +1178,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
- return PMSG_ON;
- }
-
--static void dpm_superior_set_must_resume(struct device *dev)
-+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
- {
- struct device_link *link;
- int idx;
-
-- if (dev->parent)
-+ if (dev->parent) {
- dev->parent->power.must_resume = true;
-+ if (set_active)
-+ dev->parent->power.set_active = true;
-+ }
-
- idx = device_links_read_lock();
-
-- list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
-+ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
- link->supplier->power.must_resume = true;
-+ if (set_active)
-+ link->supplier->power.set_active = true;
-+ }
-
- device_links_read_unlock(idx);
- }
-@@ -1263,8 +1271,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
- dev->power.may_skip_resume))
- dev->power.must_resume = true;
-
-- if (dev->power.must_resume)
-- dpm_superior_set_must_resume(dev);
-+ if (dev->power.must_resume) {
-+ dev->power.set_active = dev->power.set_active ||
-+ dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-+ dpm_superior_set_must_resume(dev, dev->power.set_active);
-+ }
-
- Complete:
- complete_all(&dev->power.completion);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 04ba61ac1a8d6..9007379d333b3 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -585,6 +585,7 @@ struct dev_pm_info {
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
- bool must_resume:1; /* Owned by the PM core */
-+ bool set_active:1; /* Owned by the PM core */
- bool may_skip_resume:1; /* Set by subsystems */
- #else
- bool should_wakeup:1;
---
-2.39.5
-
+++ /dev/null
-From 46afbb4961503f331dbc45ed832299fd5a613a10 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 9 Jan 2024 17:59:22 +0100
-Subject: PM: sleep: Restore asynchronous device resume optimization
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3e999770ac1c7c31a70685dd5b88e89473509e9c ]
-
-Before commit 7839d0078e0d ("PM: sleep: Fix possible deadlocks in core
-system-wide PM code"), the resume of devices that were allowed to resume
-asynchronously was scheduled before starting the resume of the other
-devices, so the former did not have to wait for the latter unless
-functional dependencies were present.
-
-Commit 7839d0078e0d removed that optimization in order to address a
-correctness issue, but it can be restored with the help of a new device
-power management flag, so do that now.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 117 +++++++++++++++++++++-----------------
- include/linux/pm.h | 1 +
- 2 files changed, 65 insertions(+), 53 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index fbc57c4fcdd01..07f561e17b637 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -583,7 +583,7 @@ bool dev_pm_skip_resume(struct device *dev)
- }
-
- /**
-- * __device_resume_noirq - Execute a "noirq resume" callback for given device.
-+ * device_resume_noirq - Execute a "noirq resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
-@@ -591,7 +591,7 @@ bool dev_pm_skip_resume(struct device *dev)
- * The driver of @dev will not receive interrupts while this function is being
- * executed.
- */
--static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_noirq(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -678,16 +678,22 @@ static bool dpm_async_fn(struct device *dev, async_func_t func)
- {
- reinit_completion(&dev->power.completion);
-
-- if (!is_async(dev))
-- return false;
--
-- get_device(dev);
-+ if (is_async(dev)) {
-+ dev->power.async_in_progress = true;
-
-- if (async_schedule_dev_nocall(func, dev))
-- return true;
-+ get_device(dev);
-
-- put_device(dev);
-+ if (async_schedule_dev_nocall(func, dev))
-+ return true;
-
-+ put_device(dev);
-+ }
-+ /*
-+ * Because async_schedule_dev_nocall() above has returned false or it
-+ * has not been called at all, func() is not running and it is safe to
-+ * update the async_in_progress flag without extra synchronization.
-+ */
-+ dev->power.async_in_progress = false;
- return false;
- }
-
-@@ -695,18 +701,10 @@ static void async_resume_noirq(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_noirq(dev, pm_transition, true);
-+ device_resume_noirq(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_noirq(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_noirq))
-- return;
--
-- __device_resume_noirq(dev, pm_transition, false);
--}
--
- static void dpm_noirq_resume_devices(pm_message_t state)
- {
- struct device *dev;
-@@ -716,18 +714,28 @@ static void dpm_noirq_resume_devices(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_noirq_list, power.entry)
-+ dpm_async_fn(dev, async_resume_noirq);
-+
- while (!list_empty(&dpm_noirq_list)) {
- dev = to_device(dpm_noirq_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_late_early_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_noirq(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_noirq(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -753,14 +761,14 @@ void dpm_resume_noirq(pm_message_t state)
- }
-
- /**
-- * __device_resume_early - Execute an "early resume" callback for given device.
-+ * device_resume_early - Execute an "early resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- *
- * Runtime PM is disabled for @dev while this function is being executed.
- */
--static void __device_resume_early(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_early(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -826,18 +834,10 @@ static void async_resume_early(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_early(dev, pm_transition, true);
-+ device_resume_early(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_early(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_early))
-- return;
--
-- __device_resume_early(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume_early - Execute "early resume" callbacks for all devices.
- * @state: PM transition of the system being carried out.
-@@ -851,18 +851,28 @@ void dpm_resume_early(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_late_early_list, power.entry)
-+ dpm_async_fn(dev, async_resume_early);
-+
- while (!list_empty(&dpm_late_early_list)) {
- dev = to_device(dpm_late_early_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_suspended_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_early(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_early(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -882,12 +892,12 @@ void dpm_resume_start(pm_message_t state)
- EXPORT_SYMBOL_GPL(dpm_resume_start);
-
- /**
-- * __device_resume - Execute "resume" callbacks for given device.
-+ * device_resume - Execute "resume" callbacks for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- */
--static void __device_resume(struct device *dev, pm_message_t state, bool async)
-+static void device_resume(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -981,18 +991,10 @@ static void async_resume(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume(dev, pm_transition, true);
-+ device_resume(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume))
-- return;
--
-- __device_resume(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
- * @state: PM transition of the system being carried out.
-@@ -1012,16 +1014,25 @@ void dpm_resume(pm_message_t state)
- pm_transition = state;
- async_error = 0;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_suspended_list, power.entry)
-+ dpm_async_fn(dev, async_resume);
-+
- while (!list_empty(&dpm_suspended_list)) {
- dev = to_device(dpm_suspended_list.next);
-
- get_device(dev);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ mutex_unlock(&dpm_list_mtx);
-
-- device_resume(dev);
-+ device_resume(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ mutex_lock(&dpm_list_mtx);
-+ }
-
- if (!list_empty(&dev->power.entry))
- list_move_tail(&dev->power.entry, &dpm_prepared_list);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 52d9724db9dc6..c27d1e4ca8ca9 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -583,6 +583,7 @@ struct dev_pm_info {
- bool wakeup_path:1;
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
-+ bool async_in_progress:1; /* Owned by the PM core */
- unsigned int must_resume:1; /* Owned by the PM core */
- unsigned int may_skip_resume:1; /* Set by subsystems */
- #else
---
-2.39.5
-
+++ /dev/null
-From 6eaa9e0ddeb12a1936d188b0b17c0cd1c1abbb2b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 22 Jan 2024 17:11:26 +0100
-Subject: PM: sleep: Use bool for all 1-bit fields in struct dev_pm_info
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit b017500ab53c06441ff7d3a681484e37039b4f57 ]
-
-For some 1-bit fields in struct dev_pm_info the data type is bool, while
-for some other 1-bit fields in there it is unsigned int, and these
-differences are somewhat arbitrary.
-
-For consistency, change the data type of the latter to bool, so that all
-of the 1-bit fields in struct dev_pm_info fields are bool.
-
-No intentional functional impact.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/pm.h | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index c27d1e4ca8ca9..04ba61ac1a8d6 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -564,8 +564,8 @@ struct pm_subsys_data {
-
- struct dev_pm_info {
- pm_message_t power_state;
-- unsigned int can_wakeup:1;
-- unsigned int async_suspend:1;
-+ bool can_wakeup:1;
-+ bool async_suspend:1;
- bool in_dpm_list:1; /* Owned by the PM core */
- bool is_prepared:1; /* Owned by the PM core */
- bool is_suspended:1; /* Ditto */
-@@ -584,10 +584,10 @@ struct dev_pm_info {
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
-- unsigned int must_resume:1; /* Owned by the PM core */
-- unsigned int may_skip_resume:1; /* Set by subsystems */
-+ bool must_resume:1; /* Owned by the PM core */
-+ bool may_skip_resume:1; /* Set by subsystems */
- #else
-- unsigned int should_wakeup:1;
-+ bool should_wakeup:1;
- #endif
- #ifdef CONFIG_PM
- struct hrtimer suspend_timer;
-@@ -598,17 +598,17 @@ struct dev_pm_info {
- atomic_t usage_count;
- atomic_t child_count;
- unsigned int disable_depth:3;
-- unsigned int idle_notification:1;
-- unsigned int request_pending:1;
-- unsigned int deferred_resume:1;
-- unsigned int needs_force_resume:1;
-- unsigned int runtime_auto:1;
-+ bool idle_notification:1;
-+ bool request_pending:1;
-+ bool deferred_resume:1;
-+ bool needs_force_resume:1;
-+ bool runtime_auto:1;
- bool ignore_children:1;
-- unsigned int no_callbacks:1;
-- unsigned int irq_safe:1;
-- unsigned int use_autosuspend:1;
-- unsigned int timer_autosuspends:1;
-- unsigned int memalloc_noio:1;
-+ bool no_callbacks:1;
-+ bool irq_safe:1;
-+ bool use_autosuspend:1;
-+ bool timer_autosuspends:1;
-+ bool memalloc_noio:1;
- unsigned int links_count;
- enum rpm_request request;
- enum rpm_status runtime_status;
---
-2.39.5
-
net-netdevsim-try-to-close-udp-port-harness-races.patch
net-davicom-fix-uaf-in-dm9000_drv_remove.patch
perf-trace-fix-runtime-error-of-index-out-of-bounds.patch
-pm-sleep-restore-asynchronous-device-resume-optimiza.patch
-pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch
-pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
vsock-allow-retrying-on-connect-failure.patch
bgmac-reduce-max-frame-size-to-support-just-mtu-1500.patch
net-sh_eth-fix-missing-rtnl-lock-in-suspend-resume-p.patch
+++ /dev/null
-From 4059106177b70a7510345b9463b375e2da51f702 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Jan 2025 20:24:41 +0100
-Subject: PM: sleep: core: Synchronize runtime PM status of parents and
- children
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
-
-Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
-resume phase") overlooked the case in which the parent of a device with
-DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
-suspended before a transition into a system-wide sleep state. In that
-case, if the child is resumed during the subsequent transition from
-that state into the working state, its runtime PM status will be set to
-RPM_ACTIVE, but the runtime PM status of the parent will not be updated
-accordingly, even though the parent will be resumed too, because of the
-dev_pm_skip_suspend() check in device_resume_noirq().
-
-Address this problem by tracking the need to set the runtime PM status
-to RPM_ACTIVE during system-wide resume transitions for devices with
-DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
-
-Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
-Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@hovoldconsulting.com/
-Reported-by: Johan Hovold <johan@kernel.org>
-Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
-Tested-by: Johan Hovold <johan+linaro@kernel.org>
-Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 29 ++++++++++++++++++++---------
- include/linux/pm.h | 1 +
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 01591c1055117..c9092e0f9bc3b 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -615,13 +615,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
- * so change its status accordingly.
- *
- * Otherwise, the device is going to be resumed, so set its PM-runtime
-- * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-- * to avoid confusing drivers that don't use it.
-+ * status to "active" unless its power.set_active flag is clear, in
-+ * which case it is not necessary to update its PM-runtime status.
- */
-- if (skip_resume)
-+ if (skip_resume) {
- pm_runtime_set_suspended(dev);
-- else if (dev_pm_skip_suspend(dev))
-+ } else if (dev->power.set_active) {
- pm_runtime_set_active(dev);
-+ dev->power.set_active = false;
-+ }
-
- if (dev->pm_domain) {
- info = "noirq power domain ";
-@@ -1173,18 +1175,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
- return PMSG_ON;
- }
-
--static void dpm_superior_set_must_resume(struct device *dev)
-+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
- {
- struct device_link *link;
- int idx;
-
-- if (dev->parent)
-+ if (dev->parent) {
- dev->parent->power.must_resume = true;
-+ if (set_active)
-+ dev->parent->power.set_active = true;
-+ }
-
- idx = device_links_read_lock();
-
-- list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
-+ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
- link->supplier->power.must_resume = true;
-+ if (set_active)
-+ link->supplier->power.set_active = true;
-+ }
-
- device_links_read_unlock(idx);
- }
-@@ -1260,8 +1268,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
- dev->power.may_skip_resume))
- dev->power.must_resume = true;
-
-- if (dev->power.must_resume)
-- dpm_superior_set_must_resume(dev);
-+ if (dev->power.must_resume) {
-+ dev->power.set_active = dev->power.set_active ||
-+ dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-+ dpm_superior_set_must_resume(dev, dev->power.set_active);
-+ }
-
- Complete:
- complete_all(&dev->power.completion);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 1a478b7d6bef4..5549bdefabf8c 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -633,6 +633,7 @@ struct dev_pm_info {
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
- bool must_resume:1; /* Owned by the PM core */
-+ bool set_active:1; /* Owned by the PM core */
- bool may_skip_resume:1; /* Set by subsystems */
- #else
- bool should_wakeup:1;
---
-2.39.5
-
+++ /dev/null
-From 6585d5c43ceac9a984ca2eb2cf6e02aa64ea7685 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 9 Jan 2024 17:59:22 +0100
-Subject: PM: sleep: Restore asynchronous device resume optimization
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3e999770ac1c7c31a70685dd5b88e89473509e9c ]
-
-Before commit 7839d0078e0d ("PM: sleep: Fix possible deadlocks in core
-system-wide PM code"), the resume of devices that were allowed to resume
-asynchronously was scheduled before starting the resume of the other
-devices, so the former did not have to wait for the latter unless
-functional dependencies were present.
-
-Commit 7839d0078e0d removed that optimization in order to address a
-correctness issue, but it can be restored with the help of a new device
-power management flag, so do that now.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 117 +++++++++++++++++++++-----------------
- include/linux/pm.h | 1 +
- 2 files changed, 65 insertions(+), 53 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 185ea0d93a5e5..01591c1055117 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -580,7 +580,7 @@ bool dev_pm_skip_resume(struct device *dev)
- }
-
- /**
-- * __device_resume_noirq - Execute a "noirq resume" callback for given device.
-+ * device_resume_noirq - Execute a "noirq resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
-@@ -588,7 +588,7 @@ bool dev_pm_skip_resume(struct device *dev)
- * The driver of @dev will not receive interrupts while this function is being
- * executed.
- */
--static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_noirq(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -675,16 +675,22 @@ static bool dpm_async_fn(struct device *dev, async_func_t func)
- {
- reinit_completion(&dev->power.completion);
-
-- if (!is_async(dev))
-- return false;
--
-- get_device(dev);
-+ if (is_async(dev)) {
-+ dev->power.async_in_progress = true;
-
-- if (async_schedule_dev_nocall(func, dev))
-- return true;
-+ get_device(dev);
-
-- put_device(dev);
-+ if (async_schedule_dev_nocall(func, dev))
-+ return true;
-
-+ put_device(dev);
-+ }
-+ /*
-+ * Because async_schedule_dev_nocall() above has returned false or it
-+ * has not been called at all, func() is not running and it is safe to
-+ * update the async_in_progress flag without extra synchronization.
-+ */
-+ dev->power.async_in_progress = false;
- return false;
- }
-
-@@ -692,18 +698,10 @@ static void async_resume_noirq(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_noirq(dev, pm_transition, true);
-+ device_resume_noirq(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_noirq(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_noirq))
-- return;
--
-- __device_resume_noirq(dev, pm_transition, false);
--}
--
- static void dpm_noirq_resume_devices(pm_message_t state)
- {
- struct device *dev;
-@@ -713,18 +711,28 @@ static void dpm_noirq_resume_devices(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_noirq_list, power.entry)
-+ dpm_async_fn(dev, async_resume_noirq);
-+
- while (!list_empty(&dpm_noirq_list)) {
- dev = to_device(dpm_noirq_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_late_early_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_noirq(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_noirq(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -750,14 +758,14 @@ void dpm_resume_noirq(pm_message_t state)
- }
-
- /**
-- * __device_resume_early - Execute an "early resume" callback for given device.
-+ * device_resume_early - Execute an "early resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- *
- * Runtime PM is disabled for @dev while this function is being executed.
- */
--static void __device_resume_early(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_early(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -823,18 +831,10 @@ static void async_resume_early(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_early(dev, pm_transition, true);
-+ device_resume_early(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_early(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_early))
-- return;
--
-- __device_resume_early(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume_early - Execute "early resume" callbacks for all devices.
- * @state: PM transition of the system being carried out.
-@@ -848,18 +848,28 @@ void dpm_resume_early(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_late_early_list, power.entry)
-+ dpm_async_fn(dev, async_resume_early);
-+
- while (!list_empty(&dpm_late_early_list)) {
- dev = to_device(dpm_late_early_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_suspended_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_early(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_early(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -879,12 +889,12 @@ void dpm_resume_start(pm_message_t state)
- EXPORT_SYMBOL_GPL(dpm_resume_start);
-
- /**
-- * __device_resume - Execute "resume" callbacks for given device.
-+ * device_resume - Execute "resume" callbacks for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- */
--static void __device_resume(struct device *dev, pm_message_t state, bool async)
-+static void device_resume(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -978,18 +988,10 @@ static void async_resume(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume(dev, pm_transition, true);
-+ device_resume(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume))
-- return;
--
-- __device_resume(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
- * @state: PM transition of the system being carried out.
-@@ -1009,16 +1011,25 @@ void dpm_resume(pm_message_t state)
- pm_transition = state;
- async_error = 0;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_suspended_list, power.entry)
-+ dpm_async_fn(dev, async_resume);
-+
- while (!list_empty(&dpm_suspended_list)) {
- dev = to_device(dpm_suspended_list.next);
-
- get_device(dev);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ mutex_unlock(&dpm_list_mtx);
-
-- device_resume(dev);
-+ device_resume(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ mutex_lock(&dpm_list_mtx);
-+ }
-
- if (!list_empty(&dev->power.entry))
- list_move_tail(&dev->power.entry, &dpm_prepared_list);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index b8578e1f7c110..6eceb403afacf 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -631,6 +631,7 @@ struct dev_pm_info {
- bool wakeup_path:1;
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
-+ bool async_in_progress:1; /* Owned by the PM core */
- unsigned int must_resume:1; /* Owned by the PM core */
- unsigned int may_skip_resume:1; /* Set by subsystems */
- #else
---
-2.39.5
-
+++ /dev/null
-From 402a16325d0ef46e9c9d76c937274902475110a5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 22 Jan 2024 17:11:26 +0100
-Subject: PM: sleep: Use bool for all 1-bit fields in struct dev_pm_info
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit b017500ab53c06441ff7d3a681484e37039b4f57 ]
-
-For some 1-bit fields in struct dev_pm_info the data type is bool, while
-for some other 1-bit fields in there it is unsigned int, and these
-differences are somewhat arbitrary.
-
-For consistency, change the data type of the latter to bool, so that all
-of the 1-bit fields in struct dev_pm_info fields are bool.
-
-No intentional functional impact.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/pm.h | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 6eceb403afacf..1a478b7d6bef4 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -612,8 +612,8 @@ struct pm_subsys_data {
-
- struct dev_pm_info {
- pm_message_t power_state;
-- unsigned int can_wakeup:1;
-- unsigned int async_suspend:1;
-+ bool can_wakeup:1;
-+ bool async_suspend:1;
- bool in_dpm_list:1; /* Owned by the PM core */
- bool is_prepared:1; /* Owned by the PM core */
- bool is_suspended:1; /* Ditto */
-@@ -632,10 +632,10 @@ struct dev_pm_info {
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
-- unsigned int must_resume:1; /* Owned by the PM core */
-- unsigned int may_skip_resume:1; /* Set by subsystems */
-+ bool must_resume:1; /* Owned by the PM core */
-+ bool may_skip_resume:1; /* Set by subsystems */
- #else
-- unsigned int should_wakeup:1;
-+ bool should_wakeup:1;
- #endif
- #ifdef CONFIG_PM
- struct hrtimer suspend_timer;
-@@ -646,17 +646,17 @@ struct dev_pm_info {
- atomic_t usage_count;
- atomic_t child_count;
- unsigned int disable_depth:3;
-- unsigned int idle_notification:1;
-- unsigned int request_pending:1;
-- unsigned int deferred_resume:1;
-- unsigned int needs_force_resume:1;
-- unsigned int runtime_auto:1;
-+ bool idle_notification:1;
-+ bool request_pending:1;
-+ bool deferred_resume:1;
-+ bool needs_force_resume:1;
-+ bool runtime_auto:1;
- bool ignore_children:1;
-- unsigned int no_callbacks:1;
-- unsigned int irq_safe:1;
-- unsigned int use_autosuspend:1;
-- unsigned int timer_autosuspends:1;
-- unsigned int memalloc_noio:1;
-+ bool no_callbacks:1;
-+ bool irq_safe:1;
-+ bool use_autosuspend:1;
-+ bool timer_autosuspends:1;
-+ bool memalloc_noio:1;
- unsigned int links_count;
- enum rpm_request request;
- enum rpm_status runtime_status;
---
-2.39.5
-
net-davicom-fix-uaf-in-dm9000_drv_remove.patch
ptp-properly-handle-compat-ioctls.patch
perf-trace-fix-runtime-error-of-index-out-of-bounds.patch
-pm-sleep-restore-asynchronous-device-resume-optimiza.patch
-pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch
-pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
vsock-allow-retrying-on-connect-failure.patch
bgmac-reduce-max-frame-size-to-support-just-mtu-1500.patch
net-sh_eth-fix-missing-rtnl-lock-in-suspend-resume-p.patch
+++ /dev/null
-From e3acb3160dd133197b9ae1d36d7ad2c8b3a1f1c5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Jan 2025 20:24:41 +0100
-Subject: PM: sleep: core: Synchronize runtime PM status of parents and
- children
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
-
-Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
-resume phase") overlooked the case in which the parent of a device with
-DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
-suspended before a transition into a system-wide sleep state. In that
-case, if the child is resumed during the subsequent transition from
-that state into the working state, its runtime PM status will be set to
-RPM_ACTIVE, but the runtime PM status of the parent will not be updated
-accordingly, even though the parent will be resumed too, because of the
-dev_pm_skip_suspend() check in device_resume_noirq().
-
-Address this problem by tracking the need to set the runtime PM status
-to RPM_ACTIVE during system-wide resume transitions for devices with
-DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
-
-Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
-Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@hovoldconsulting.com/
-Reported-by: Johan Hovold <johan@kernel.org>
-Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
-Tested-by: Johan Hovold <johan+linaro@kernel.org>
-Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 29 ++++++++++++++++++++---------
- include/linux/pm.h | 1 +
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index fadcd0379dc2d..fd2d975de536f 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -614,13 +614,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
- * so change its status accordingly.
- *
- * Otherwise, the device is going to be resumed, so set its PM-runtime
-- * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-- * to avoid confusing drivers that don't use it.
-+ * status to "active" unless its power.set_active flag is clear, in
-+ * which case it is not necessary to update its PM-runtime status.
- */
-- if (skip_resume)
-+ if (skip_resume) {
- pm_runtime_set_suspended(dev);
-- else if (dev_pm_skip_suspend(dev))
-+ } else if (dev->power.set_active) {
- pm_runtime_set_active(dev);
-+ dev->power.set_active = false;
-+ }
-
- if (dev->pm_domain) {
- info = "noirq power domain ";
-@@ -1170,18 +1172,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
- return PMSG_ON;
- }
-
--static void dpm_superior_set_must_resume(struct device *dev)
-+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
- {
- struct device_link *link;
- int idx;
-
-- if (dev->parent)
-+ if (dev->parent) {
- dev->parent->power.must_resume = true;
-+ if (set_active)
-+ dev->parent->power.set_active = true;
-+ }
-
- idx = device_links_read_lock();
-
-- list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
-+ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
- link->supplier->power.must_resume = true;
-+ if (set_active)
-+ link->supplier->power.set_active = true;
-+ }
-
- device_links_read_unlock(idx);
- }
-@@ -1257,8 +1265,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
- dev->power.may_skip_resume))
- dev->power.must_resume = true;
-
-- if (dev->power.must_resume)
-- dpm_superior_set_must_resume(dev);
-+ if (dev->power.must_resume) {
-+ dev->power.set_active = dev->power.set_active ||
-+ dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-+ dpm_superior_set_must_resume(dev, dev->power.set_active);
-+ }
-
- Complete:
- complete_all(&dev->power.completion);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 39e7a7c6016f7..c46f4b6b6241d 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -655,6 +655,7 @@ struct dev_pm_info {
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
- bool must_resume:1; /* Owned by the PM core */
-+ bool set_active:1; /* Owned by the PM core */
- bool may_skip_resume:1; /* Set by subsystems */
- #else
- bool should_wakeup:1;
---
-2.39.5
-
+++ /dev/null
-From 4359a38f3f1b57a16412a59fa23d2ee64a524fdf Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 9 Jan 2024 17:59:22 +0100
-Subject: PM: sleep: Restore asynchronous device resume optimization
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3e999770ac1c7c31a70685dd5b88e89473509e9c ]
-
-Before commit 7839d0078e0d ("PM: sleep: Fix possible deadlocks in core
-system-wide PM code"), the resume of devices that were allowed to resume
-asynchronously was scheduled before starting the resume of the other
-devices, so the former did not have to wait for the latter unless
-functional dependencies were present.
-
-Commit 7839d0078e0d removed that optimization in order to address a
-correctness issue, but it can be restored with the help of a new device
-power management flag, so do that now.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 117 +++++++++++++++++++++-----------------
- include/linux/pm.h | 1 +
- 2 files changed, 65 insertions(+), 53 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 9c5a5f4dba5a6..fadcd0379dc2d 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -579,7 +579,7 @@ bool dev_pm_skip_resume(struct device *dev)
- }
-
- /**
-- * __device_resume_noirq - Execute a "noirq resume" callback for given device.
-+ * device_resume_noirq - Execute a "noirq resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
-@@ -587,7 +587,7 @@ bool dev_pm_skip_resume(struct device *dev)
- * The driver of @dev will not receive interrupts while this function is being
- * executed.
- */
--static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_noirq(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -674,16 +674,22 @@ static bool dpm_async_fn(struct device *dev, async_func_t func)
- {
- reinit_completion(&dev->power.completion);
-
-- if (!is_async(dev))
-- return false;
--
-- get_device(dev);
-+ if (is_async(dev)) {
-+ dev->power.async_in_progress = true;
-
-- if (async_schedule_dev_nocall(func, dev))
-- return true;
-+ get_device(dev);
-
-- put_device(dev);
-+ if (async_schedule_dev_nocall(func, dev))
-+ return true;
-
-+ put_device(dev);
-+ }
-+ /*
-+ * Because async_schedule_dev_nocall() above has returned false or it
-+ * has not been called at all, func() is not running and it is safe to
-+ * update the async_in_progress flag without extra synchronization.
-+ */
-+ dev->power.async_in_progress = false;
- return false;
- }
-
-@@ -691,18 +697,10 @@ static void async_resume_noirq(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_noirq(dev, pm_transition, true);
-+ device_resume_noirq(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_noirq(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_noirq))
-- return;
--
-- __device_resume_noirq(dev, pm_transition, false);
--}
--
- static void dpm_noirq_resume_devices(pm_message_t state)
- {
- struct device *dev;
-@@ -712,18 +710,28 @@ static void dpm_noirq_resume_devices(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_noirq_list, power.entry)
-+ dpm_async_fn(dev, async_resume_noirq);
-+
- while (!list_empty(&dpm_noirq_list)) {
- dev = to_device(dpm_noirq_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_late_early_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_noirq(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_noirq(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -747,14 +755,14 @@ void dpm_resume_noirq(pm_message_t state)
- }
-
- /**
-- * __device_resume_early - Execute an "early resume" callback for given device.
-+ * device_resume_early - Execute an "early resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- *
- * Runtime PM is disabled for @dev while this function is being executed.
- */
--static void __device_resume_early(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_early(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -820,18 +828,10 @@ static void async_resume_early(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_early(dev, pm_transition, true);
-+ device_resume_early(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_early(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_early))
-- return;
--
-- __device_resume_early(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume_early - Execute "early resume" callbacks for all devices.
- * @state: PM transition of the system being carried out.
-@@ -845,18 +845,28 @@ void dpm_resume_early(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_late_early_list, power.entry)
-+ dpm_async_fn(dev, async_resume_early);
-+
- while (!list_empty(&dpm_late_early_list)) {
- dev = to_device(dpm_late_early_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_suspended_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_early(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_early(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -876,12 +886,12 @@ void dpm_resume_start(pm_message_t state)
- EXPORT_SYMBOL_GPL(dpm_resume_start);
-
- /**
-- * __device_resume - Execute "resume" callbacks for given device.
-+ * device_resume - Execute "resume" callbacks for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- */
--static void __device_resume(struct device *dev, pm_message_t state, bool async)
-+static void device_resume(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -975,18 +985,10 @@ static void async_resume(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume(dev, pm_transition, true);
-+ device_resume(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume))
-- return;
--
-- __device_resume(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
- * @state: PM transition of the system being carried out.
-@@ -1006,16 +1008,25 @@ void dpm_resume(pm_message_t state)
- pm_transition = state;
- async_error = 0;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_suspended_list, power.entry)
-+ dpm_async_fn(dev, async_resume);
-+
- while (!list_empty(&dpm_suspended_list)) {
- dev = to_device(dpm_suspended_list.next);
-
- get_device(dev);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ mutex_unlock(&dpm_list_mtx);
-
-- device_resume(dev);
-+ device_resume(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ mutex_lock(&dpm_list_mtx);
-+ }
-
- if (!list_empty(&dev->power.entry))
- list_move_tail(&dev->power.entry, &dpm_prepared_list);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 93cd34f00822c..bfc441099d8ea 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -653,6 +653,7 @@ struct dev_pm_info {
- bool wakeup_path:1;
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
-+ bool async_in_progress:1; /* Owned by the PM core */
- unsigned int must_resume:1; /* Owned by the PM core */
- unsigned int may_skip_resume:1; /* Set by subsystems */
- #else
---
-2.39.5
-
+++ /dev/null
-From be53be67be3d256fa4d7c77c694df6c33eb96b0e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 22 Jan 2024 17:11:26 +0100
-Subject: PM: sleep: Use bool for all 1-bit fields in struct dev_pm_info
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit b017500ab53c06441ff7d3a681484e37039b4f57 ]
-
-For some 1-bit fields in struct dev_pm_info the data type is bool, while
-for some other 1-bit fields in there it is unsigned int, and these
-differences are somewhat arbitrary.
-
-For consistency, change the data type of the latter to bool, so that all
-of the 1-bit fields in struct dev_pm_info fields are bool.
-
-No intentional functional impact.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/pm.h | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index bfc441099d8ea..39e7a7c6016f7 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -634,8 +634,8 @@ struct pm_subsys_data {
-
- struct dev_pm_info {
- pm_message_t power_state;
-- unsigned int can_wakeup:1;
-- unsigned int async_suspend:1;
-+ bool can_wakeup:1;
-+ bool async_suspend:1;
- bool in_dpm_list:1; /* Owned by the PM core */
- bool is_prepared:1; /* Owned by the PM core */
- bool is_suspended:1; /* Ditto */
-@@ -654,10 +654,10 @@ struct dev_pm_info {
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
-- unsigned int must_resume:1; /* Owned by the PM core */
-- unsigned int may_skip_resume:1; /* Set by subsystems */
-+ bool must_resume:1; /* Owned by the PM core */
-+ bool may_skip_resume:1; /* Set by subsystems */
- #else
-- unsigned int should_wakeup:1;
-+ bool should_wakeup:1;
- #endif
- #ifdef CONFIG_PM
- struct hrtimer suspend_timer;
-@@ -668,17 +668,17 @@ struct dev_pm_info {
- atomic_t usage_count;
- atomic_t child_count;
- unsigned int disable_depth:3;
-- unsigned int idle_notification:1;
-- unsigned int request_pending:1;
-- unsigned int deferred_resume:1;
-- unsigned int needs_force_resume:1;
-- unsigned int runtime_auto:1;
-+ bool idle_notification:1;
-+ bool request_pending:1;
-+ bool deferred_resume:1;
-+ bool needs_force_resume:1;
-+ bool runtime_auto:1;
- bool ignore_children:1;
-- unsigned int no_callbacks:1;
-- unsigned int irq_safe:1;
-- unsigned int use_autosuspend:1;
-- unsigned int timer_autosuspends:1;
-- unsigned int memalloc_noio:1;
-+ bool no_callbacks:1;
-+ bool irq_safe:1;
-+ bool use_autosuspend:1;
-+ bool timer_autosuspends:1;
-+ bool memalloc_noio:1;
- unsigned int links_count;
- enum rpm_request request;
- enum rpm_status runtime_status;
---
-2.39.5
-
vxlan-fix-uninit-value-in-vxlan_vnifilter_dump.patch
net-davicom-fix-uaf-in-dm9000_drv_remove.patch
perf-trace-fix-runtime-error-of-index-out-of-bounds.patch
-pm-sleep-restore-asynchronous-device-resume-optimiza.patch
-pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch
-pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
bgmac-reduce-max-frame-size-to-support-just-mtu-1500.patch
net-sh_eth-fix-missing-rtnl-lock-in-suspend-resume-p.patch
net-hsr-fix-fill_frame_info-regression-vs-vlan-packe.patch
+++ /dev/null
-From 0887934a9d3a42c18e6b039b265bb8d93cc24b1c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Jan 2025 20:24:41 +0100
-Subject: PM: sleep: core: Synchronize runtime PM status of parents and
- children
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
-
-Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
-resume phase") overlooked the case in which the parent of a device with
-DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
-suspended before a transition into a system-wide sleep state. In that
-case, if the child is resumed during the subsequent transition from
-that state into the working state, its runtime PM status will be set to
-RPM_ACTIVE, but the runtime PM status of the parent will not be updated
-accordingly, even though the parent will be resumed too, because of the
-dev_pm_skip_suspend() check in device_resume_noirq().
-
-Address this problem by tracking the need to set the runtime PM status
-to RPM_ACTIVE during system-wide resume transitions for devices with
-DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
-
-Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
-Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@hovoldconsulting.com/
-Reported-by: Johan Hovold <johan@kernel.org>
-Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
-Tested-by: Johan Hovold <johan+linaro@kernel.org>
-Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 29 ++++++++++++++++++++---------
- include/linux/pm.h | 1 +
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 4a67e83300e16..e1b44266497d3 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -642,13 +642,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
- * so change its status accordingly.
- *
- * Otherwise, the device is going to be resumed, so set its PM-runtime
-- * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-- * to avoid confusing drivers that don't use it.
-+ * status to "active" unless its power.set_active flag is clear, in
-+ * which case it is not necessary to update its PM-runtime status.
- */
-- if (skip_resume)
-+ if (skip_resume) {
- pm_runtime_set_suspended(dev);
-- else if (dev_pm_skip_suspend(dev))
-+ } else if (dev->power.set_active) {
- pm_runtime_set_active(dev);
-+ dev->power.set_active = false;
-+ }
-
- if (dev->pm_domain) {
- info = "noirq power domain ";
-@@ -1175,18 +1177,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
- return PMSG_ON;
- }
-
--static void dpm_superior_set_must_resume(struct device *dev)
-+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
- {
- struct device_link *link;
- int idx;
-
-- if (dev->parent)
-+ if (dev->parent) {
- dev->parent->power.must_resume = true;
-+ if (set_active)
-+ dev->parent->power.set_active = true;
-+ }
-
- idx = device_links_read_lock();
-
-- list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
-+ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
- link->supplier->power.must_resume = true;
-+ if (set_active)
-+ link->supplier->power.set_active = true;
-+ }
-
- device_links_read_unlock(idx);
- }
-@@ -1264,8 +1272,11 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state, bool asy
- dev->power.may_skip_resume))
- dev->power.must_resume = true;
-
-- if (dev->power.must_resume)
-- dpm_superior_set_must_resume(dev);
-+ if (dev->power.must_resume) {
-+ dev->power.set_active = dev->power.set_active ||
-+ dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-+ dpm_superior_set_must_resume(dev, dev->power.set_active);
-+ }
-
- Complete:
- complete_all(&dev->power.completion);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 97b0e23363c82..a478737115cd9 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -683,6 +683,7 @@ struct dev_pm_info {
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
- bool must_resume:1; /* Owned by the PM core */
-+ bool set_active:1; /* Owned by the PM core */
- bool may_skip_resume:1; /* Set by subsystems */
- #else
- bool should_wakeup:1;
---
-2.39.5
-
s390-sclp-initialize-sclp-subsystem-via-arch_cpu_fin.patch
perf-trace-fix-runtime-error-of-index-out-of-bounds.patch
perf-test-skip-syscall-enum-test-if-no-landlock-sysc.patch
-pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
bluetooth-btusb-mediatek-add-locks-for-usb_driver_cl.patch
bluetooth-btnxpuart-fix-glitches-seen-in-dual-a2dp-s.patch
vsock-allow-retrying-on-connect-failure.patch
+++ /dev/null
-From 0210d62ffbe664322af62b70d101bc8c916e3f3d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Jan 2025 20:24:41 +0100
-Subject: PM: sleep: core: Synchronize runtime PM status of parents and
- children
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
-
-Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
-resume phase") overlooked the case in which the parent of a device with
-DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
-suspended before a transition into a system-wide sleep state. In that
-case, if the child is resumed during the subsequent transition from
-that state into the working state, its runtime PM status will be set to
-RPM_ACTIVE, but the runtime PM status of the parent will not be updated
-accordingly, even though the parent will be resumed too, because of the
-dev_pm_skip_suspend() check in device_resume_noirq().
-
-Address this problem by tracking the need to set the runtime PM status
-to RPM_ACTIVE during system-wide resume transitions for devices with
-DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
-
-Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
-Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@hovoldconsulting.com/
-Reported-by: Johan Hovold <johan@kernel.org>
-Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
-Tested-by: Johan Hovold <johan+linaro@kernel.org>
-Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 29 ++++++++++++++++++++---------
- include/linux/pm.h | 1 +
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 4a67e83300e16..e1b44266497d3 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -642,13 +642,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
- * so change its status accordingly.
- *
- * Otherwise, the device is going to be resumed, so set its PM-runtime
-- * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-- * to avoid confusing drivers that don't use it.
-+ * status to "active" unless its power.set_active flag is clear, in
-+ * which case it is not necessary to update its PM-runtime status.
- */
-- if (skip_resume)
-+ if (skip_resume) {
- pm_runtime_set_suspended(dev);
-- else if (dev_pm_skip_suspend(dev))
-+ } else if (dev->power.set_active) {
- pm_runtime_set_active(dev);
-+ dev->power.set_active = false;
-+ }
-
- if (dev->pm_domain) {
- info = "noirq power domain ";
-@@ -1175,18 +1177,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
- return PMSG_ON;
- }
-
--static void dpm_superior_set_must_resume(struct device *dev)
-+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
- {
- struct device_link *link;
- int idx;
-
-- if (dev->parent)
-+ if (dev->parent) {
- dev->parent->power.must_resume = true;
-+ if (set_active)
-+ dev->parent->power.set_active = true;
-+ }
-
- idx = device_links_read_lock();
-
-- list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
-+ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
- link->supplier->power.must_resume = true;
-+ if (set_active)
-+ link->supplier->power.set_active = true;
-+ }
-
- device_links_read_unlock(idx);
- }
-@@ -1264,8 +1272,11 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state, bool asy
- dev->power.may_skip_resume))
- dev->power.must_resume = true;
-
-- if (dev->power.must_resume)
-- dpm_superior_set_must_resume(dev);
-+ if (dev->power.must_resume) {
-+ dev->power.set_active = dev->power.set_active ||
-+ dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-+ dpm_superior_set_must_resume(dev, dev->power.set_active);
-+ }
-
- Complete:
- complete_all(&dev->power.completion);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index e7f0260f15ad5..514cafcd21951 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -683,6 +683,7 @@ struct dev_pm_info {
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
- bool must_resume:1; /* Owned by the PM core */
-+ bool set_active:1; /* Owned by the PM core */
- bool may_skip_resume:1; /* Set by subsystems */
- #else
- bool should_wakeup:1;
---
-2.39.5
-
s390-sclp-initialize-sclp-subsystem-via-arch_cpu_fin.patch
perf-trace-fix-runtime-error-of-index-out-of-bounds.patch
perf-test-skip-syscall-enum-test-if-no-landlock-sysc.patch
-pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
bluetooth-btusb-mediatek-add-locks-for-usb_driver_cl.patch
bluetooth-btnxpuart-fix-glitches-seen-in-dual-a2dp-s.patch
vsock-allow-retrying-on-connect-failure.patch
+++ /dev/null
-From 30a4530dee525c5f9befb6db9f8729504eab634c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 28 Jan 2025 20:24:41 +0100
-Subject: PM: sleep: core: Synchronize runtime PM status of parents and
- children
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3775fc538f535a7c5adaf11990c7932a0bd1f9eb ]
-
-Commit 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the
-resume phase") overlooked the case in which the parent of a device with
-DPM_FLAG_SMART_SUSPEND set did not use that flag and could be runtime-
-suspended before a transition into a system-wide sleep state. In that
-case, if the child is resumed during the subsequent transition from
-that state into the working state, its runtime PM status will be set to
-RPM_ACTIVE, but the runtime PM status of the parent will not be updated
-accordingly, even though the parent will be resumed too, because of the
-dev_pm_skip_suspend() check in device_resume_noirq().
-
-Address this problem by tracking the need to set the runtime PM status
-to RPM_ACTIVE during system-wide resume transitions for devices with
-DPM_FLAG_SMART_SUSPEND set and all of the devices depended on by them.
-
-Fixes: 6e176bf8d461 ("PM: sleep: core: Do not skip callbacks in the resume phase")
-Closes: https://lore.kernel.org/linux-pm/Z30p2Etwf3F2AUvD@hovoldconsulting.com/
-Reported-by: Johan Hovold <johan@kernel.org>
-Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
-Tested-by: Johan Hovold <johan+linaro@kernel.org>
-Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 29 ++++++++++++++++++++---------
- include/linux/pm.h | 1 +
- 2 files changed, 21 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index fadcd0379dc2d..fd2d975de536f 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -614,13 +614,15 @@ static void device_resume_noirq(struct device *dev, pm_message_t state, bool asy
- * so change its status accordingly.
- *
- * Otherwise, the device is going to be resumed, so set its PM-runtime
-- * status to "active", but do that only if DPM_FLAG_SMART_SUSPEND is set
-- * to avoid confusing drivers that don't use it.
-+ * status to "active" unless its power.set_active flag is clear, in
-+ * which case it is not necessary to update its PM-runtime status.
- */
-- if (skip_resume)
-+ if (skip_resume) {
- pm_runtime_set_suspended(dev);
-- else if (dev_pm_skip_suspend(dev))
-+ } else if (dev->power.set_active) {
- pm_runtime_set_active(dev);
-+ dev->power.set_active = false;
-+ }
-
- if (dev->pm_domain) {
- info = "noirq power domain ";
-@@ -1170,18 +1172,24 @@ static pm_message_t resume_event(pm_message_t sleep_state)
- return PMSG_ON;
- }
-
--static void dpm_superior_set_must_resume(struct device *dev)
-+static void dpm_superior_set_must_resume(struct device *dev, bool set_active)
- {
- struct device_link *link;
- int idx;
-
-- if (dev->parent)
-+ if (dev->parent) {
- dev->parent->power.must_resume = true;
-+ if (set_active)
-+ dev->parent->power.set_active = true;
-+ }
-
- idx = device_links_read_lock();
-
-- list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node)
-+ list_for_each_entry_rcu_locked(link, &dev->links.suppliers, c_node) {
- link->supplier->power.must_resume = true;
-+ if (set_active)
-+ link->supplier->power.set_active = true;
-+ }
-
- device_links_read_unlock(idx);
- }
-@@ -1257,8 +1265,11 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
- dev->power.may_skip_resume))
- dev->power.must_resume = true;
-
-- if (dev->power.must_resume)
-- dpm_superior_set_must_resume(dev);
-+ if (dev->power.must_resume) {
-+ dev->power.set_active = dev->power.set_active ||
-+ dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND);
-+ dpm_superior_set_must_resume(dev, dev->power.set_active);
-+ }
-
- Complete:
- complete_all(&dev->power.completion);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 9e1c60cd60e5a..1ad57c98264af 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -683,6 +683,7 @@ struct dev_pm_info {
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
- bool must_resume:1; /* Owned by the PM core */
-+ bool set_active:1; /* Owned by the PM core */
- bool may_skip_resume:1; /* Set by subsystems */
- #else
- bool should_wakeup:1;
---
-2.39.5
-
+++ /dev/null
-From 68ac17b8f6584d7d8e5174cac4f2f25e9bdf98a2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 9 Jan 2024 17:59:22 +0100
-Subject: PM: sleep: Restore asynchronous device resume optimization
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit 3e999770ac1c7c31a70685dd5b88e89473509e9c ]
-
-Before commit 7839d0078e0d ("PM: sleep: Fix possible deadlocks in core
-system-wide PM code"), the resume of devices that were allowed to resume
-asynchronously was scheduled before starting the resume of the other
-devices, so the former did not have to wait for the latter unless
-functional dependencies were present.
-
-Commit 7839d0078e0d removed that optimization in order to address a
-correctness issue, but it can be restored with the help of a new device
-power management flag, so do that now.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/base/power/main.c | 117 +++++++++++++++++++++-----------------
- include/linux/pm.h | 1 +
- 2 files changed, 65 insertions(+), 53 deletions(-)
-
-diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
-index 9c5a5f4dba5a6..fadcd0379dc2d 100644
---- a/drivers/base/power/main.c
-+++ b/drivers/base/power/main.c
-@@ -579,7 +579,7 @@ bool dev_pm_skip_resume(struct device *dev)
- }
-
- /**
-- * __device_resume_noirq - Execute a "noirq resume" callback for given device.
-+ * device_resume_noirq - Execute a "noirq resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
-@@ -587,7 +587,7 @@ bool dev_pm_skip_resume(struct device *dev)
- * The driver of @dev will not receive interrupts while this function is being
- * executed.
- */
--static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_noirq(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -674,16 +674,22 @@ static bool dpm_async_fn(struct device *dev, async_func_t func)
- {
- reinit_completion(&dev->power.completion);
-
-- if (!is_async(dev))
-- return false;
--
-- get_device(dev);
-+ if (is_async(dev)) {
-+ dev->power.async_in_progress = true;
-
-- if (async_schedule_dev_nocall(func, dev))
-- return true;
-+ get_device(dev);
-
-- put_device(dev);
-+ if (async_schedule_dev_nocall(func, dev))
-+ return true;
-
-+ put_device(dev);
-+ }
-+ /*
-+ * Because async_schedule_dev_nocall() above has returned false or it
-+ * has not been called at all, func() is not running and it is safe to
-+ * update the async_in_progress flag without extra synchronization.
-+ */
-+ dev->power.async_in_progress = false;
- return false;
- }
-
-@@ -691,18 +697,10 @@ static void async_resume_noirq(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_noirq(dev, pm_transition, true);
-+ device_resume_noirq(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_noirq(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_noirq))
-- return;
--
-- __device_resume_noirq(dev, pm_transition, false);
--}
--
- static void dpm_noirq_resume_devices(pm_message_t state)
- {
- struct device *dev;
-@@ -712,18 +710,28 @@ static void dpm_noirq_resume_devices(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_noirq_list, power.entry)
-+ dpm_async_fn(dev, async_resume_noirq);
-+
- while (!list_empty(&dpm_noirq_list)) {
- dev = to_device(dpm_noirq_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_late_early_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_noirq(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_noirq(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -747,14 +755,14 @@ void dpm_resume_noirq(pm_message_t state)
- }
-
- /**
-- * __device_resume_early - Execute an "early resume" callback for given device.
-+ * device_resume_early - Execute an "early resume" callback for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- *
- * Runtime PM is disabled for @dev while this function is being executed.
- */
--static void __device_resume_early(struct device *dev, pm_message_t state, bool async)
-+static void device_resume_early(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -820,18 +828,10 @@ static void async_resume_early(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume_early(dev, pm_transition, true);
-+ device_resume_early(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume_early(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume_early))
-- return;
--
-- __device_resume_early(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume_early - Execute "early resume" callbacks for all devices.
- * @state: PM transition of the system being carried out.
-@@ -845,18 +845,28 @@ void dpm_resume_early(pm_message_t state)
- mutex_lock(&dpm_list_mtx);
- pm_transition = state;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_late_early_list, power.entry)
-+ dpm_async_fn(dev, async_resume_early);
-+
- while (!list_empty(&dpm_late_early_list)) {
- dev = to_device(dpm_late_early_list.next);
-- get_device(dev);
- list_move_tail(&dev->power.entry, &dpm_suspended_list);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ get_device(dev);
-
-- device_resume_early(dev);
-+ mutex_unlock(&dpm_list_mtx);
-
-- put_device(dev);
-+ device_resume_early(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ put_device(dev);
-+
-+ mutex_lock(&dpm_list_mtx);
-+ }
- }
- mutex_unlock(&dpm_list_mtx);
- async_synchronize_full();
-@@ -876,12 +886,12 @@ void dpm_resume_start(pm_message_t state)
- EXPORT_SYMBOL_GPL(dpm_resume_start);
-
- /**
-- * __device_resume - Execute "resume" callbacks for given device.
-+ * device_resume - Execute "resume" callbacks for given device.
- * @dev: Device to handle.
- * @state: PM transition of the system being carried out.
- * @async: If true, the device is being resumed asynchronously.
- */
--static void __device_resume(struct device *dev, pm_message_t state, bool async)
-+static void device_resume(struct device *dev, pm_message_t state, bool async)
- {
- pm_callback_t callback = NULL;
- const char *info = NULL;
-@@ -975,18 +985,10 @@ static void async_resume(void *data, async_cookie_t cookie)
- {
- struct device *dev = data;
-
-- __device_resume(dev, pm_transition, true);
-+ device_resume(dev, pm_transition, true);
- put_device(dev);
- }
-
--static void device_resume(struct device *dev)
--{
-- if (dpm_async_fn(dev, async_resume))
-- return;
--
-- __device_resume(dev, pm_transition, false);
--}
--
- /**
- * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
- * @state: PM transition of the system being carried out.
-@@ -1006,16 +1008,25 @@ void dpm_resume(pm_message_t state)
- pm_transition = state;
- async_error = 0;
-
-+ /*
-+ * Trigger the resume of "async" devices upfront so they don't have to
-+ * wait for the "non-async" ones they don't depend on.
-+ */
-+ list_for_each_entry(dev, &dpm_suspended_list, power.entry)
-+ dpm_async_fn(dev, async_resume);
-+
- while (!list_empty(&dpm_suspended_list)) {
- dev = to_device(dpm_suspended_list.next);
-
- get_device(dev);
-
-- mutex_unlock(&dpm_list_mtx);
-+ if (!dev->power.async_in_progress) {
-+ mutex_unlock(&dpm_list_mtx);
-
-- device_resume(dev);
-+ device_resume(dev, state, false);
-
-- mutex_lock(&dpm_list_mtx);
-+ mutex_lock(&dpm_list_mtx);
-+ }
-
- if (!list_empty(&dev->power.entry))
- list_move_tail(&dev->power.entry, &dpm_prepared_list);
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 629c1633bbd00..943b553720f82 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -681,6 +681,7 @@ struct dev_pm_info {
- bool wakeup_path:1;
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
-+ bool async_in_progress:1; /* Owned by the PM core */
- unsigned int must_resume:1; /* Owned by the PM core */
- unsigned int may_skip_resume:1; /* Set by subsystems */
- #else
---
-2.39.5
-
+++ /dev/null
-From a7c49715eabc9705990ba3d1a04dec93ac36cd21 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 22 Jan 2024 17:11:26 +0100
-Subject: PM: sleep: Use bool for all 1-bit fields in struct dev_pm_info
-
-From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-[ Upstream commit b017500ab53c06441ff7d3a681484e37039b4f57 ]
-
-For some 1-bit fields in struct dev_pm_info the data type is bool, while
-for some other 1-bit fields in there it is unsigned int, and these
-differences are somewhat arbitrary.
-
-For consistency, change the data type of the latter to bool, so that all
-of the 1-bit fields in struct dev_pm_info fields are bool.
-
-No intentional functional impact.
-
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/pm.h | 30 +++++++++++++++---------------
- 1 file changed, 15 insertions(+), 15 deletions(-)
-
-diff --git a/include/linux/pm.h b/include/linux/pm.h
-index 943b553720f82..9e1c60cd60e5a 100644
---- a/include/linux/pm.h
-+++ b/include/linux/pm.h
-@@ -662,8 +662,8 @@ struct pm_subsys_data {
-
- struct dev_pm_info {
- pm_message_t power_state;
-- unsigned int can_wakeup:1;
-- unsigned int async_suspend:1;
-+ bool can_wakeup:1;
-+ bool async_suspend:1;
- bool in_dpm_list:1; /* Owned by the PM core */
- bool is_prepared:1; /* Owned by the PM core */
- bool is_suspended:1; /* Ditto */
-@@ -682,10 +682,10 @@ struct dev_pm_info {
- bool syscore:1;
- bool no_pm_callbacks:1; /* Owned by the PM core */
- bool async_in_progress:1; /* Owned by the PM core */
-- unsigned int must_resume:1; /* Owned by the PM core */
-- unsigned int may_skip_resume:1; /* Set by subsystems */
-+ bool must_resume:1; /* Owned by the PM core */
-+ bool may_skip_resume:1; /* Set by subsystems */
- #else
-- unsigned int should_wakeup:1;
-+ bool should_wakeup:1;
- #endif
- #ifdef CONFIG_PM
- struct hrtimer suspend_timer;
-@@ -696,17 +696,17 @@ struct dev_pm_info {
- atomic_t usage_count;
- atomic_t child_count;
- unsigned int disable_depth:3;
-- unsigned int idle_notification:1;
-- unsigned int request_pending:1;
-- unsigned int deferred_resume:1;
-- unsigned int needs_force_resume:1;
-- unsigned int runtime_auto:1;
-+ bool idle_notification:1;
-+ bool request_pending:1;
-+ bool deferred_resume:1;
-+ bool needs_force_resume:1;
-+ bool runtime_auto:1;
- bool ignore_children:1;
-- unsigned int no_callbacks:1;
-- unsigned int irq_safe:1;
-- unsigned int use_autosuspend:1;
-- unsigned int timer_autosuspends:1;
-- unsigned int memalloc_noio:1;
-+ bool no_callbacks:1;
-+ bool irq_safe:1;
-+ bool use_autosuspend:1;
-+ bool timer_autosuspends:1;
-+ bool memalloc_noio:1;
- unsigned int links_count;
- enum rpm_request request;
- enum rpm_status runtime_status;
---
-2.39.5
-
net-stmmac-limit-the-number-of-mtl-queues-to-hardwar.patch
net-stmmac-limit-fifo-size-by-hardware-capability.patch
perf-trace-fix-runtime-error-of-index-out-of-bounds.patch
-pm-sleep-restore-asynchronous-device-resume-optimiza.patch
-pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch
-pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch
bluetooth-btnxpuart-fix-glitches-seen-in-dual-a2dp-s.patch
vsock-allow-retrying-on-connect-failure.patch
bgmac-reduce-max-frame-size-to-support-just-mtu-1500.patch