lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4dd9d86f-7c20-40fa-838c-b7634bbebf9a@kernel.org>
Date: Wed, 29 Oct 2025 10:22:18 -0500
From: Mario Limonciello <superm1@...nel.org>
To: "Rafael J. Wysocki" <rafael@...nel.org>,
 Linux PM <linux-pm@...r.kernel.org>
Cc: Askar Safin <safinaskar@...il.com>, LKML <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v1] PM: sleep: Allow pm_restrict_gfp_mask() stacking

On 10/28/25 3:52 PM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@...el.com>
> 
> Allow pm_restrict_gfp_mask() to be called many times in a row to avoid
> issues with calling dpm_suspend_start() when the GFP mask has been
> already restricted.
> 
> Only the first invocation of pm_restrict_gfp_mask() will actually
> restrict the GFP mask and the subsequent calls will warn if there is
> a mismatch between the expected allowed GFP mask and the actual one.
> 
> Moreover, if pm_restrict_gfp_mask() is called many times in a row,
> pm_restore_gfp_mask() needs to be called matching number of times in
> a row to actually restore the GFP mask.  Calling it when the GFP mask
> has not been restricted will cause it to warn.
> 
> This is necessary for the GFP mask restriction starting in
> hibernation_snapshot() to continue throughout the entire hibernation
> flow until it completes or it is aborted (either by a wakeup event or
> by an error).
> 
> Fixes: 449c9c02537a1 ("PM: hibernate: Restrict GFP mask in hibernation_snapshot()")
> Fixes: 469d80a3712c ("PM: hibernate: Fix hybrid-sleep")
> Reported-by: Askar Safin <safinaskar@...il.com>
> Closes: https://lore.kernel.org/linux-pm/20251025050812.421905-1-safinaskar@gmail.com/
> Link: https://lore.kernel.org/linux-pm/20251028111730.2261404-1-safinaskar@gmail.com/
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@...el.com>

Great idea.  Looks good to me, and it passes the S4 tests on my side.

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

> ---
> 
> This supersedes
> 
> https://lore.kernel.org/linux-pm/20251026033115.436448-1-superm1@kernel.org/
> 
> as it allows the GFP mask to be restricted across the entire hibernation path.
> 
> ---
>   kernel/power/hibernate.c |    4 ----
>   kernel/power/main.c      |   22 +++++++++++++++++-----
>   2 files changed, 17 insertions(+), 9 deletions(-)
> 
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -706,7 +706,6 @@ static void power_down(void)
>   
>   #ifdef CONFIG_SUSPEND
>   	if (hibernation_mode == HIBERNATION_SUSPEND) {
> -		pm_restore_gfp_mask();
>   		error = suspend_devices_and_enter(mem_sleep_current);
>   		if (!error)
>   			goto exit;
> @@ -746,9 +745,6 @@ static void power_down(void)
>   		cpu_relax();
>   
>   exit:
> -	/* Match the pm_restore_gfp_mask() call in hibernate(). */
> -	pm_restrict_gfp_mask();
> -
>   	/* Restore swap signature. */
>   	error = swsusp_unmark();
>   	if (error)
> --- a/kernel/power/main.c
> +++ b/kernel/power/main.c
> @@ -31,23 +31,35 @@
>    * held, unless the suspend/hibernate code is guaranteed not to run in parallel
>    * with that modification).
>    */
> +static unsigned int saved_gfp_count;
>   static gfp_t saved_gfp_mask;
>   
>   void pm_restore_gfp_mask(void)
>   {
>   	WARN_ON(!mutex_is_locked(&system_transition_mutex));
> -	if (saved_gfp_mask) {
> -		gfp_allowed_mask = saved_gfp_mask;
> -		saved_gfp_mask = 0;
> -	}
> +
> +	if (WARN_ON(!saved_gfp_count) || --saved_gfp_count)
> +		return;
> +
> +	gfp_allowed_mask = saved_gfp_mask;
> +	saved_gfp_mask = 0;
> +
> +	pm_pr_dbg("GFP mask restored\n");
>   }
>   
>   void pm_restrict_gfp_mask(void)
>   {
>   	WARN_ON(!mutex_is_locked(&system_transition_mutex));
> -	WARN_ON(saved_gfp_mask);
> +
> +	if (saved_gfp_count++) {
> +		WARN_ON((saved_gfp_mask & ~(__GFP_IO | __GFP_FS)) != gfp_allowed_mask);
> +		return;
> +	}
> +
>   	saved_gfp_mask = gfp_allowed_mask;
>   	gfp_allowed_mask &= ~(__GFP_IO | __GFP_FS);
> +
> +	pm_pr_dbg("GFP mask restricted\n");
>   }
>   
>   unsigned int lock_system_sleep(void)
> 
> 
> 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ