Power management fixes for 6.16-rc7

- Fix a deadlock that may occur on asynchronous device suspend
    failures due to missing completion updates in error paths (Rafael
    Wysocki).
 
  - Drop a misplaced pm_restore_gfp_mask() call, which may cause
    swap to be accessed too early if system suspend fails, from
    suspend_devices_and_enter() (Rafael Wysocki).
 
  - Remove duplicate filesystems_freeze/thaw() calls, which sometimes
    cause systems to be unable to resume, from enter_state() (Zihuan
    Zhang).
 -----BEGIN PGP SIGNATURE-----
 
 iQFGBAABCAAwFiEEcM8Aw/RY0dgsiRUR7l+9nS/U47UFAmh5IE4SHHJqd0Byand5
 c29ja2kubmV0AAoJEO5fvZ0v1OO12LYH/3CULHOIoshuWu+G9nIKokqO0oNYmxh1
 qgkh+o9sBz9uTyfCSd1qDT9j1LjzUnOJUe67IzHJFuZcHbnWU4k9VYWV+H8TKyNp
 CcQ+9g5gCqOzxWH7G7C2ekciSnnBlObwJ7ZsDlUOeuJ16GVCjqrFPZbJ6No0A+Hz
 8Ed7R4o1MKrURLU9IZWpqV1a54Z9ySv2yrx9T4G0c8WV2VRJZJ76e1hAGcOr4owj
 kM1+MPnsfU/RvBUUEKjUEm70ZBXGbXT+D9p/L/AuoYyhI94kvoImK1/2An5noHCO
 czK5nDB867z6hu5jTVPt/RoIK/49H/a2CDNYl3ZiZnVVZIoPN/wt3C8=
 =wkHb
 -----END PGP SIGNATURE-----

Merge tag 'pm-6.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
 "These address three issues introduced during the current development
  cycle and related to system suspend and hibernation, one triggering
  when asynchronous suspend of devices fails, one possibly affecting
  memory management in the core suspend code error path, and one due to
  duplicate filesystems freezing during system suspend:

   - Fix a deadlock that may occur on asynchronous device suspend
     failures due to missing completion updates in error paths (Rafael
     Wysocki)

   - Drop a misplaced pm_restore_gfp_mask() call, which may cause swap
     to be accessed too early if system suspend fails, from
     suspend_devices_and_enter() (Rafael Wysocki)

   - Remove duplicate filesystems_freeze/thaw() calls, which sometimes
     cause systems to be unable to resume, from enter_state() (Zihuan
     Zhang)"

* tag 'pm-6.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PM: sleep: Update power.completion for all devices on errors
  PM: suspend: clean up redundant filesystems_freeze/thaw() handling
  PM: suspend: Drop a misplaced pm_restore_gfp_mask() call
This commit is contained in:
Linus Torvalds 2025-07-17 09:46:37 -07:00
commit e6e82e5bed
2 changed files with 20 additions and 4 deletions

View file

@ -1280,6 +1280,22 @@ static void dpm_async_suspend_parent(struct device *dev, async_func_t func)
dpm_async_with_cleanup(dev->parent, func);
}
static void dpm_async_suspend_complete_all(struct list_head *device_list)
{
struct device *dev;
guard(mutex)(&async_wip_mtx);
list_for_each_entry_reverse(dev, device_list, power.entry) {
/*
* In case the device is being waited for and async processing
* has not started for it yet, let the waiters make progress.
*/
if (!dev->power.work_in_progress)
complete_all(&dev->power.completion);
}
}
/**
* resume_event - Return a "resume" message for given "suspend" sleep state.
* @sleep_state: PM message representing a sleep state.
@ -1456,6 +1472,7 @@ static int dpm_noirq_suspend_devices(pm_message_t state)
mutex_lock(&dpm_list_mtx);
if (error || async_error) {
dpm_async_suspend_complete_all(&dpm_late_early_list);
/*
* Move all devices to the target list to resume them
* properly.
@ -1658,6 +1675,7 @@ int dpm_suspend_late(pm_message_t state)
mutex_lock(&dpm_list_mtx);
if (error || async_error) {
dpm_async_suspend_complete_all(&dpm_suspended_list);
/*
* Move all devices to the target list to resume them
* properly.
@ -1951,6 +1969,7 @@ int dpm_suspend(pm_message_t state)
mutex_lock(&dpm_list_mtx);
if (error || async_error) {
dpm_async_suspend_complete_all(&dpm_prepared_list);
/*
* Move all devices to the target list to resume them
* properly.

View file

@ -384,6 +384,7 @@ static int suspend_prepare(suspend_state_t state)
return 0;
dpm_save_failed_step(SUSPEND_FREEZE);
filesystems_thaw();
pm_notifier_call_chain(PM_POST_SUSPEND);
Restore:
pm_restore_console();
@ -540,7 +541,6 @@ int suspend_devices_and_enter(suspend_state_t state)
return error;
Recover_platform:
pm_restore_gfp_mask();
platform_recover(state);
goto Resume_devices;
}
@ -593,8 +593,6 @@ static int enter_state(suspend_state_t state)
ksys_sync_helper();
trace_suspend_resume(TPS("sync_filesystems"), 0, false);
}
if (filesystem_freeze_enabled)
filesystems_freeze();
pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
pm_suspend_clear_flags();
@ -614,7 +612,6 @@ static int enter_state(suspend_state_t state)
pm_pr_dbg("Finishing wakeup.\n");
suspend_finish();
Unlock:
filesystems_thaw();
mutex_unlock(&system_transition_mutex);
return error;
}