linux/kernel/power
Florian Schmaus 41112a787f PM: hibernate: Freeze kernel threads after image preallocation
Commit 783c810984 ("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 <flo@geekplace.eu>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Tested-by: Matthew Leach <matthew.leach@collabora.com>
Reviewed-by: Matthew Leach <matthew.leach@collabora.com>
Link: https://patch.msgid.link/20260920-fix-hibernation-v1-1-f9940c2d7d7f@geekplace.eu
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2026-09-22 21:09:51 +02:00
..
autosleep.c PM: sleep: autosleep: don't include 'pm_wakeup.h' directly 2024-12-05 12:14:26 +01:00
console.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
em_netlink_autogen.c PM: EM: Add dump to get-perf-domains in the EM YNL spec 2026-01-09 21:44:46 +01:00
em_netlink_autogen.h PM: EM: Add dump to get-perf-domains in the EM YNL spec 2026-01-09 21:44:46 +01:00
em_netlink.c PM: EM: Fix NULL pointer dereference when perf domain ID is not found 2026-03-30 21:43:51 +02:00
em_netlink.h PM: EM: Implement em_notify_pd_created/updated() 2025-10-22 21:44:38 +02:00
energy_model.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hibernate.c PM: hibernate: Freeze kernel threads after image preallocation 2026-09-22 21:09:51 +02:00
Kconfig PM: sleep: Allow disabling DPM watchdog by default 2026-07-23 15:46:34 +02:00
main.c PM: sleep: Drop spurious WARN_ON() from pm_restore_gfp_mask() 2026-03-23 13:54:53 +01:00
Makefile PM: EM: Add a skeleton code for netlink notification 2025-10-22 21:44:37 +02:00
power.h PM: sleep: Add support for wakeup during filesystem sync 2025-11-20 22:29:40 +01:00
poweroff.c
process.c Revert "PM: sleep: Make pm_wakeup_clear() call more clear" 2025-10-23 12:48:04 +02:00
qos.c PM: QoS: Fix misc device registration unwind 2026-06-09 18:10:46 +02:00
snapshot.c PM: hibernate: Fix memory leak in snapshot_write_next() error path 2026-07-23 15:21:13 +02:00
suspend_test.c rtc: class: make rtc_class constant 2024-03-08 12:05:10 +01:00
suspend.c PM: sleep: Fix suspend_test() at the TEST_CORE level 2025-12-28 13:01:39 +01:00
swap.c PM: hibernate: swap: defer linking the next map page 2026-07-23 15:25:00 +02:00
user.c mm/swap, PM: hibernate: fix swapoff race in uswsusp by pinning swap device 2026-06-08 18:21:31 -07:00
wakelock.c PM: sleep: Fix off-by-one in wakelocks number limit check 2026-07-06 20:58:23 +02:00