From: Greg Kroah-Hartman Date: Thu, 6 Feb 2025 15:00:24 +0000 (+0100) Subject: drop pm patch that breaks tegra boards X-Git-Tag: v6.6.76~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a7c078d9b8b6f2fa6e669557f4d597221fb9c6c0;p=thirdparty%2Fkernel%2Fstable-queue.git drop pm patch that breaks tegra boards --- diff --git a/queue-5.10/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch b/queue-5.10/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch deleted file mode 100644 index 06d78793bb..0000000000 --- a/queue-5.10/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 1856343e6435d557ab04729f9707bc14b961039a Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Tested-by: Manivannan Sadhasivam -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Johan Hovold -Tested-by: Johan Hovold -Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.10/pm-sleep-restore-asynchronous-device-resume-optimiza.patch b/queue-5.10/pm-sleep-restore-asynchronous-device-resume-optimiza.patch deleted file mode 100644 index a7ae71ac89..0000000000 --- a/queue-5.10/pm-sleep-restore-asynchronous-device-resume-optimiza.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 46afbb4961503f331dbc45ed832299fd5a613a10 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 9 Jan 2024 17:59:22 +0100 -Subject: PM: sleep: Restore asynchronous device resume optimization - -From: Rafael J. Wysocki - -[ 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 -Reviewed-by: Stanislaw Gruszka -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.10/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch b/queue-5.10/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch deleted file mode 100644 index 1724e355e5..0000000000 --- a/queue-5.10/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 6eaa9e0ddeb12a1936d188b0b17c0cd1c1abbb2b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Reviewed-by: Greg Kroah-Hartman -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.10/series b/queue-5.10/series index fe82523738..a07f987c33 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -114,9 +114,6 @@ net-rose-fix-timer-races-against-user-threads.patch 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 diff --git a/queue-5.15/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch b/queue-5.15/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch deleted file mode 100644 index fe5139d95a..0000000000 --- a/queue-5.15/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 4059106177b70a7510345b9463b375e2da51f702 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Tested-by: Manivannan Sadhasivam -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Johan Hovold -Tested-by: Johan Hovold -Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.15/pm-sleep-restore-asynchronous-device-resume-optimiza.patch b/queue-5.15/pm-sleep-restore-asynchronous-device-resume-optimiza.patch deleted file mode 100644 index fff0d93b77..0000000000 --- a/queue-5.15/pm-sleep-restore-asynchronous-device-resume-optimiza.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 6585d5c43ceac9a984ca2eb2cf6e02aa64ea7685 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 9 Jan 2024 17:59:22 +0100 -Subject: PM: sleep: Restore asynchronous device resume optimization - -From: Rafael J. Wysocki - -[ 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 -Reviewed-by: Stanislaw Gruszka -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.15/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch b/queue-5.15/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch deleted file mode 100644 index 4e7c32548b..0000000000 --- a/queue-5.15/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 402a16325d0ef46e9c9d76c937274902475110a5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Reviewed-by: Greg Kroah-Hartman -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.15/series b/queue-5.15/series index 1f1ee81b41..3bc8e58ff3 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -170,9 +170,6 @@ net-netdevsim-try-to-close-udp-port-harness-races.patch 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 diff --git a/queue-6.1/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch b/queue-6.1/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch deleted file mode 100644 index 65d4b71c21..0000000000 --- a/queue-6.1/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch +++ /dev/null @@ -1,119 +0,0 @@ -From e3acb3160dd133197b9ae1d36d7ad2c8b3a1f1c5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Tested-by: Manivannan Sadhasivam -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Johan Hovold -Tested-by: Johan Hovold -Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.1/pm-sleep-restore-asynchronous-device-resume-optimiza.patch b/queue-6.1/pm-sleep-restore-asynchronous-device-resume-optimiza.patch deleted file mode 100644 index 3060390782..0000000000 --- a/queue-6.1/pm-sleep-restore-asynchronous-device-resume-optimiza.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 4359a38f3f1b57a16412a59fa23d2ee64a524fdf Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 9 Jan 2024 17:59:22 +0100 -Subject: PM: sleep: Restore asynchronous device resume optimization - -From: Rafael J. Wysocki - -[ 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 -Reviewed-by: Stanislaw Gruszka -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.1/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch b/queue-6.1/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch deleted file mode 100644 index d01629722f..0000000000 --- a/queue-6.1/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch +++ /dev/null @@ -1,86 +0,0 @@ -From be53be67be3d256fa4d7c77c694df6c33eb96b0e Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Reviewed-by: Greg Kroah-Hartman -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.1/series b/queue-6.1/series index d9fa968ac2..b7c6e4ef68 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -227,9 +227,6 @@ net-netdevsim-try-to-close-udp-port-harness-races.patch 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 diff --git a/queue-6.12/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch b/queue-6.12/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch deleted file mode 100644 index d63cf4f007..0000000000 --- a/queue-6.12/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0887934a9d3a42c18e6b039b265bb8d93cc24b1c Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Tested-by: Manivannan Sadhasivam -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Johan Hovold -Tested-by: Johan Hovold -Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.12/series b/queue-6.12/series index 51f35ed148..fc31c56991 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -501,7 +501,6 @@ net-stmmac-limit-fifo-size-by-hardware-capability.patch 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 diff --git a/queue-6.13/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch b/queue-6.13/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch deleted file mode 100644 index 3f7c99856f..0000000000 --- a/queue-6.13/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0210d62ffbe664322af62b70d101bc8c916e3f3d Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Tested-by: Manivannan Sadhasivam -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Johan Hovold -Tested-by: Johan Hovold -Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.13/series b/queue-6.13/series index b92bc82a34..35898ee5c8 100644 --- a/queue-6.13/series +++ b/queue-6.13/series @@ -536,7 +536,6 @@ bonding-correctly-support-gso-esp-offload.patch 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 diff --git a/queue-6.6/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch b/queue-6.6/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch deleted file mode 100644 index c36425ebaa..0000000000 --- a/queue-6.6/pm-sleep-core-synchronize-runtime-pm-status-of-paren.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 30a4530dee525c5f9befb6db9f8729504eab634c Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Tested-by: Manivannan Sadhasivam -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Johan Hovold -Tested-by: Johan Hovold -Link: https://patch.msgid.link/12619233.O9o76ZdvQC@rjwysocki.net -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.6/pm-sleep-restore-asynchronous-device-resume-optimiza.patch b/queue-6.6/pm-sleep-restore-asynchronous-device-resume-optimiza.patch deleted file mode 100644 index aa38fbaf82..0000000000 --- a/queue-6.6/pm-sleep-restore-asynchronous-device-resume-optimiza.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 68ac17b8f6584d7d8e5174cac4f2f25e9bdf98a2 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 9 Jan 2024 17:59:22 +0100 -Subject: PM: sleep: Restore asynchronous device resume optimization - -From: Rafael J. Wysocki - -[ 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 -Reviewed-by: Stanislaw Gruszka -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.6/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch b/queue-6.6/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch deleted file mode 100644 index 61793628ae..0000000000 --- a/queue-6.6/pm-sleep-use-bool-for-all-1-bit-fields-in-struct-dev.patch +++ /dev/null @@ -1,86 +0,0 @@ -From a7c49715eabc9705990ba3d1a04dec93ac36cd21 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -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 - -[ 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 -Reviewed-by: Greg Kroah-Hartman -Stable-dep-of: 3775fc538f53 ("PM: sleep: core: Synchronize runtime PM status of parents and children") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.6/series b/queue-6.6/series index 89eaa3bf93..0788ac5409 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -334,9 +334,6 @@ ptp-properly-handle-compat-ioctls.patch 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