Re: [RFC PATCH] freezer: Restrict unsafe freezable tasks to system sleep

Stanislav Kinsburskii <[email protected]> Wed, 5 Aug 2026 11:05:35 -0700
Newsgroups gmane.linux.nfs,gmane.linux.power-management.general,gmane.linux.kernel.cifs,gmane.network.samba.internals,gmane.linux.kernel
Message-ID <anN7b-WbFvqAsO4l@skinsburskii>
On Tue, Jul 14, 2026 at 09:39:51AM -0700, Stanislav Kinsburskii wrote:
> TASK_FREEZABLE_UNSAFE is used by network filesystems for sleeps that may
> happen while a task holds locks or transport resources needed by other
> tasks. Allowing the freezer to park such tasks for administrative freezer
> requests can therefore block unrelated users of the same mount until the
> task is thawed.
> 
> The original purpose of these unsafe freezable sleeps is to keep system
> sleep from being blocked indefinitely by RPC or filesystem waits. Preserve
> that behavior for suspend and hibernation, but do not freeze
> TASK_FREEZABLE_UNSAFE tasks for non-PM freezer requests.
> 
> Make __TASK_FREEZABLE_UNSAFE independent of CONFIG_LOCKDEP so the freezer
> can test the unsafe state in all builds. The lockdep check still uses the
> same bit to suppress the locks-held warning for these known unsafe waits.
> 
> Document the PM-only freezer semantics for TASK_FREEZABLE_UNSAFE.
> 

A gentle ping on this one.

I understand that this change may not look like a pressing matter, but
allowing a process to be frozen in the middle of a request, while
holding a lot of locked state and without any guarantee that it will be
thawed, does not look right.

Some applications, such as Mesos, use the freezer to quiesce processes,
and if they are killed, they may leave those processes frozen. If the
frozen process leaves access to the NFS server locked, other
applications cannot access it, which may lead to an inability to log in
to the host.

Thanks,
Stanislav

> Signed-off-by: Stanislav Kinsburskii <[email protected]>
> ---
>  Documentation/power/freezing-of-tasks.rst |    3 +++
>  include/linux/sched.h                     |    2 +-
>  kernel/freezer.c                          |   10 ++++++++++
>  3 files changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/power/freezing-of-tasks.rst b/Documentation/power/freezing-of-tasks.rst
> index df9755bfbd94..0ccf2ea041cf 100644
> --- a/Documentation/power/freezing-of-tasks.rst
> +++ b/Documentation/power/freezing-of-tasks.rst
> @@ -16,6 +16,9 @@ II. How does it work?
>  
>  There is one per-task flag (PF_NOFREEZE) and three per-task states
>  (TASK_FROZEN, TASK_FREEZABLE and __TASK_FREEZABLE_UNSAFE) used for that.
> +Tasks sleeping in TASK_FREEZABLE_UNSAFE may hold locks or other resources
> +that make them unsafe to freeze for administrative freezer requests, so the
> +freezer only freezes them during system-wide suspend or hibernation.
>  The tasks that have PF_NOFREEZE unset (all user space tasks and some kernel
>  threads) are regarded as 'freezable' and treated in a special way before the
>  system enters a sleep state as well as before a hibernation image is created
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 908aff695ef8..67e052dee1c4 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -122,7 +122,7 @@ struct user_event_mm;
>  #define TASK_NEW			0x00000800
>  #define TASK_RTLOCK_WAIT		0x00001000
>  #define TASK_FREEZABLE			0x00002000
> -#define __TASK_FREEZABLE_UNSAFE	       (0x00004000 * IS_ENABLED(CONFIG_LOCKDEP))
> +#define __TASK_FREEZABLE_UNSAFE		0x00004000
>  #define TASK_FROZEN			0x00008000
>  #define TASK_STATE_MAX			0x00010000
>  
> diff --git a/kernel/freezer.c b/kernel/freezer.c
> index a76bf957fb32..bf7bb15c144f 100644
> --- a/kernel/freezer.c
> +++ b/kernel/freezer.c
> @@ -124,6 +124,16 @@ static int __set_task_frozen(struct task_struct *p, void *arg)
>  	if (!(state & (TASK_FREEZABLE | __TASK_STOPPED | __TASK_TRACED)))
>  		return 0;
>  
> +	/*
> +	 * TASK_FREEZABLE_UNSAFE waiters may hold locks or other resources that
> +	 * other tasks need in order to make forward progress.  Only freeze
> +	 * them for system-wide suspend or hibernation, where failing to freeze
> +	 * them can prevent the sleep transition from making progress.
> +	 */
> +	if ((state & __TASK_FREEZABLE_UNSAFE) &&
> +	    !pm_freezing && !pm_nosig_freezing)
> +		return 0;
> +
>  	/*
>  	 * Only TASK_NORMAL can be augmented with TASK_FREEZABLE, since they
>  	 * can suffer spurious wakeups.
> 
>