folio_swapcache_freeable() refuses every folio for as long as pm_suspended_storage() holds, and that covers the whole window in which the hibernation image is written. Every reclaim attempt the allocator makes there drops the cluster lock, looks the folio up, trylocks it and gives up. swap_reclaim_full_clusters() walks a whole cluster to do it. Stop trying. The allocator is left with the slots that are already free, which is all reclaim could have given it anyway. Assisted-by: Claude:claude-opus-5 Signed-off-by: Youngjun Park --- mm/swapfile.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 07aefb782fbe..cf519c5569c4 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -903,7 +903,7 @@ static bool cluster_scan_range(struct swap_info_struct *si, if (swp_tb_is_null(swp_tb)) continue; if (swp_tb_is_folio(swp_tb) && !__swp_tb_get_count(swp_tb)) { - if (!vm_swap_full()) + if (!vm_swap_full() || pm_suspended_storage()) return false; *need_reclaim = true; continue; @@ -1050,6 +1050,10 @@ static void swap_reclaim_full_clusters(struct swap_info_struct *si, bool force) unsigned long swp_tb; int nr_reclaim; + /* Swap cache cannot be freed while storage is suspended. */ + if (pm_suspended_storage()) + return; + if (force) to_scan = swap_usage_in_pages(si) / SWAPFILE_CLUSTER; @@ -1315,7 +1319,7 @@ static void swap_range_alloc(struct swap_info_struct *si, unsigned int nr_entries) { if (swap_usage_add(si, nr_entries)) { - if (vm_swap_full()) + if (vm_swap_full() && !pm_suspended_storage()) schedule_work(&si->reclaim_work); } atomic_long_sub(nr_entries, &nr_swap_pages); -- 2.48.1