[PATCH v1] PM: hibernate: Restrict GFP mask in hibernation_snapshot()

Rafael J. Wysocki posted 1 patch 3 months, 1 week ago
kernel/power/hibernate.c |    1 +
1 file changed, 1 insertion(+)
[PATCH v1] PM: hibernate: Restrict GFP mask in hibernation_snapshot()
Posted by Rafael J. Wysocki 3 months, 1 week ago
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Commit 12ffc3b1513e ("PM: Restrict swap use to later in the suspend
sequence") incorrectly removed a pm_restrict_gfp_mask() call from
hibernation_snapshot(), so memory allocations involving swap are not
prevented from being carried out in this code path any more which may
lead to serious breakage.

The symptoms of such breakage have become visible after adding a
shrink_shmem_memory() call to hibernation_snapshot() in commit
2640e819474f ("PM: hibernate: shrink shmem pages after dev_pm_ops.prepare()")
which caused this problem to be much more likely to manifest itself.

However, since commit 2640e819474f was initially present in the DRM
tree that did not include commit 12ffc3b1513e, the symptoms of this
issue were not visible until merge commit 260f6f4fda93 ("Merge tag
'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel")
that exposed it through an entirely reasonable merge conflict
resolution.

Fixes: 12ffc3b1513e ("PM: Restrict swap use to later in the suspend sequence")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220555
Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com>
Tested-by: Todd Brandt <todd.e.brandt@linux.intel.com>
Cc: 6.16+ <stable@vger.kernel.org> # 6.16+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

This is super-urgent, so I'm going to fast-track it.

---
 kernel/power/hibernate.c |    1 +
 1 file changed, 1 insertion(+)

--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -449,6 +449,7 @@ int hibernation_snapshot(int platform_mo
 	shrink_shmem_memory();
 
 	console_suspend_all();
+	pm_restrict_gfp_mask();
 
 	error = dpm_suspend(PMSG_FREEZE);
[REGRESSION][BISECTED] Hibernation: WARNING at kernel/power/main.c:48 pm_restrict_gfp_mask (was: "[PATCH v1] PM: hibernate: Restrict GFP mask in hibernation_snapshot()")
Posted by Askar Safin 1 month, 3 weeks ago
"Rafael J. Wysocki" <rafael@kernel.org>:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Commit 12ffc3b1513e ("PM: Restrict swap use to later in the suspend
> sequence") incorrectly removed a pm_restrict_gfp_mask() call from
> hibernation_snapshot(), so memory allocations involving swap are not
> prevented from being carried out in this code path any more which may
> lead to serious breakage.

#regzbot introduced: 449c9c02537a146ac97ef962327a221e21c9cab3

This commit introduced regression: now I see WARNING every time when
I hibernate. The bug reproduces both on real hardware and in Qemu.

Here is script I used to reproduce this bug in Qemu:
https://zerobin.net/?aadae7117a208c0a#Xh8aI5+u3pyk+vKwET7j+yXolLeoSLe/AedcvnNeCLs=

Here is resulting log (dmesg) on current master (43e9ad0c55a3):
https://zerobin.net/?471d17d0632e7f85#uYne0yUu+rP4KnDbOFFqtCrcDIi6UpQz2uIQw85lcdQ=

Here is the most interesting part:

[    1.735001] PM: Image saving progress:  90%
[    1.746611] PM: Image saving progress: 100%
[    1.747208] PM: Image saving done
[    1.747403] PM: hibernation: Wrote 30164 kbytes in 0.13 seconds (232.03 MB/s)
[    1.747837] PM: Image size after compression: 8908 kbytes
[    1.748190] PM: S|
[    1.750351] ------------[ cut here ]------------
[    1.750627] WARNING: CPU: 0 PID: 1 at kernel/power/main.c:48 pm_restrict_gfp_mask+0x3b/0x40

On real hardware exactly same thing happens (i. e. WARNING at kernel/power/main.c:48 pm_restrict_gfp_mask).

-- 
Askar Safin
Re: [REGRESSION][BISECTED] Hibernation: WARNING at kernel/power/main.c:48 pm_restrict_gfp_mask (was: "[PATCH v1] PM: hibernate: Restrict GFP mask in hibernation_snapshot()")
Posted by Mario Limonciello 1 month, 3 weeks ago

On 10/25/25 12:08 AM, Askar Safin wrote:
> "Rafael J. Wysocki" <rafael@kernel.org>:
>> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>>
>> Commit 12ffc3b1513e ("PM: Restrict swap use to later in the suspend
>> sequence") incorrectly removed a pm_restrict_gfp_mask() call from
>> hibernation_snapshot(), so memory allocations involving swap are not
>> prevented from being carried out in this code path any more which may
>> lead to serious breakage.
> 
> #regzbot introduced: 449c9c02537a146ac97ef962327a221e21c9cab3
> 
> This commit introduced regression: now I see WARNING every time when
> I hibernate. The bug reproduces both on real hardware and in Qemu.
> 
> Here is script I used to reproduce this bug in Qemu:
> https://zerobin.net/?aadae7117a208c0a#Xh8aI5+u3pyk+vKwET7j+yXolLeoSLe/AedcvnNeCLs=
> 
> Here is resulting log (dmesg) on current master (43e9ad0c55a3):
> https://zerobin.net/?471d17d0632e7f85#uYne0yUu+rP4KnDbOFFqtCrcDIi6UpQz2uIQw85lcdQ=
> 
> Here is the most interesting part:
> 
> [    1.735001] PM: Image saving progress:  90%
> [    1.746611] PM: Image saving progress: 100%
> [    1.747208] PM: Image saving done
> [    1.747403] PM: hibernation: Wrote 30164 kbytes in 0.13 seconds (232.03 MB/s)
> [    1.747837] PM: Image size after compression: 8908 kbytes
> [    1.748190] PM: S|
> [    1.750351] ------------[ cut here ]------------
> [    1.750627] WARNING: CPU: 0 PID: 1 at kernel/power/main.c:48 pm_restrict_gfp_mask+0x3b/0x40
> 
> On real hardware exactly same thing happens (i. e. WARNING at kernel/power/main.c:48 pm_restrict_gfp_mask).
> 

Thanks for the report, and especially for the simple reproducer!

This is pretty similar to the problem we had with hybrid sleep. [1]

Link: https://git.kernel.org/torvalds/c/469d80a3712c6 [1]

I believe this should help:

diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 14e85ff23551..e15907f28c4c 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -721,6 +721,7 @@ static void power_down(void)
                 kernel_restart(NULL);
                 break;
         case HIBERNATION_PLATFORM:
+               pm_restore_gfp_mask();
                 error = hibernation_platform_enter();
                 if (error == -EAGAIN || error == -EBUSY) {
                         events_check_enabled = false;
Re: [PATCH v1] PM: hibernate: Restrict GFP mask in hibernation_snapshot()
Posted by Mario Limonciello 3 months ago
On 9/10/25 4:41 AM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Commit 12ffc3b1513e ("PM: Restrict swap use to later in the suspend
> sequence") incorrectly removed a pm_restrict_gfp_mask() call from
> hibernation_snapshot(), so memory allocations involving swap are not
> prevented from being carried out in this code path any more which may
> lead to serious breakage.
> 
> The symptoms of such breakage have become visible after adding a
> shrink_shmem_memory() call to hibernation_snapshot() in commit
> 2640e819474f ("PM: hibernate: shrink shmem pages after dev_pm_ops.prepare()")
> which caused this problem to be much more likely to manifest itself.
> 
> However, since commit 2640e819474f was initially present in the DRM
> tree that did not include commit 12ffc3b1513e, the symptoms of this
> issue were not visible until merge commit 260f6f4fda93 ("Merge tag
> 'drm-next-2025-07-30' of https://gitlab.freedesktop.org/drm/kernel")
> that exposed it through an entirely reasonable merge conflict
> resolution.
> 
> Fixes: 12ffc3b1513e ("PM: Restrict swap use to later in the suspend sequence")
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220555
> Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com>
> Tested-by: Todd Brandt <todd.e.brandt@linux.intel.com>
> Cc: 6.16+ <stable@vger.kernel.org> # 6.16+
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> 
> This is super-urgent, so I'm going to fast-track it.

Thanks.  Looking at the codepaths again it makes sense.
It's a bit surprising to me this showed up, we had done stress testing 
before submitting.  Nonetheless, thank you for the fix.

Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>

> 
> ---
>   kernel/power/hibernate.c |    1 +
>   1 file changed, 1 insertion(+)
> 
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -449,6 +449,7 @@ int hibernation_snapshot(int platform_mo
>   	shrink_shmem_memory();
>   
>   	console_suspend_all();
> +	pm_restrict_gfp_mask();
>   
>   	error = dpm_suspend(PMSG_FREEZE);
>   
> 
> 
>