mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 12:53:14 +01:00
Commit783c810984("PM: hibernate: call preallocate_image() after freeze prepare") moved hibernate_preallocate_memory() after dpm_prepare() so that device drivers have the opportunity to release pinned/unswappable memory during their ->prepare() callback before memory is preallocated for the snapshot image. However, that commit also placed hibernate_preallocate_memory() after freeze_kernel_threads(). While it was assumed during review that swap I/O submitted via submit_bio() is synchronous and would not depend on frozen kernel threads, this does not hold in practice. Calling hibernate_preallocate_memory() with kernel threads frozen leads to intermittent deadlocks during hibernation. Inside hibernate_preallocate_memory(), shrink_all_memory() is invoked with .may_writepage = 1 and .may_swap = 1 to aggressively reclaim and swap out pages. Any writeback or swap I/O that relies on freezable kernel threads, block device helpers, or WQ_FREEZABLE workqueues (such as those in storage drivers, device mapper, or filesystems) deadlocks waiting on tasks that are stuck in the refrigerator. Fix this by reordering hibernation_snapshot(): 1. Call dpm_prepare(PMSG_FREEZE) first, allowing device drivers to release pinned resources while kernel threads are still active. 2. Call hibernate_preallocate_memory() second, performing page reclaim and swapout while storage layers, workqueues, and kernel threads are alive. 3. Call freeze_kernel_threads() third, only after all memory preallocation and swap I/O have completed. Additionally, restore the call to swsusp_free() in the cleanup path so that preallocated image memory is properly freed if freeze_kernel_threads() fails or if TEST_FREEZER is enabled. Fixes:783c810984("PM: hibernate: call preallocate_image() after freeze prepare") Signed-off-by: Florian Schmaus <[email protected]> Reviewed-by: Mario Limonciello (AMD) <[email protected]> Tested-by: Matthew Leach <[email protected]> Reviewed-by: Matthew Leach <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Rafael J. Wysocki <[email protected]>