Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+20 -4
+19
drivers/base/power/main.c
··· 1280 1280 dpm_async_with_cleanup(dev->parent, func); 1281 1281 } 1282 1282 1283 + static void dpm_async_suspend_complete_all(struct list_head *device_list) 1284 + { 1285 + struct device *dev; 1286 + 1287 + guard(mutex)(&async_wip_mtx); 1288 + 1289 + list_for_each_entry_reverse(dev, device_list, power.entry) { 1290 + /* 1291 + * In case the device is being waited for and async processing 1292 + * has not started for it yet, let the waiters make progress. 1293 + */ 1294 + if (!dev->power.work_in_progress) 1295 + complete_all(&dev->power.completion); 1296 + } 1297 + } 1298 + 1283 1299 /** 1284 1300 * resume_event - Return a "resume" message for given "suspend" sleep state. 1285 1301 * @sleep_state: PM message representing a sleep state. ··· 1472 1456 mutex_lock(&dpm_list_mtx); 1473 1457 1474 1458 if (error || async_error) { 1459 + dpm_async_suspend_complete_all(&dpm_late_early_list); 1475 1460 /* 1476 1461 * Move all devices to the target list to resume them 1477 1462 * properly. ··· 1675 1658 mutex_lock(&dpm_list_mtx); 1676 1659 1677 1660 if (error || async_error) { 1661 + dpm_async_suspend_complete_all(&dpm_suspended_list); 1678 1662 /* 1679 1663 * Move all devices to the target list to resume them 1680 1664 * properly. ··· 1969 1951 mutex_lock(&dpm_list_mtx); 1970 1952 1971 1953 if (error || async_error) { 1954 + dpm_async_suspend_complete_all(&dpm_prepared_list); 1972 1955 /* 1973 1956 * Move all devices to the target list to resume them 1974 1957 * properly.
+1 -4
kernel/power/suspend.c
··· 384 384 return 0; 385 385 386 386 dpm_save_failed_step(SUSPEND_FREEZE); 387 + filesystems_thaw(); 387 388 pm_notifier_call_chain(PM_POST_SUSPEND); 388 389 Restore: 389 390 pm_restore_console(); ··· 541 540 return error; 542 541 543 542 Recover_platform: 544 - pm_restore_gfp_mask(); 545 543 platform_recover(state); 546 544 goto Resume_devices; 547 545 } ··· 593 593 ksys_sync_helper(); 594 594 trace_suspend_resume(TPS("sync_filesystems"), 0, false); 595 595 } 596 - if (filesystem_freeze_enabled) 597 - filesystems_freeze(); 598 596 599 597 pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]); 600 598 pm_suspend_clear_flags(); ··· 612 614 pm_pr_dbg("Finishing wakeup.\n"); 613 615 suspend_finish(); 614 616 Unlock: 615 - filesystems_thaw(); 616 617 mutex_unlock(&system_transition_mutex); 617 618 return error; 618 619 }