[RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes

Zihuan Zhang posted 9 patches 1 month, 4 weeks ago
[RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Zihuan Zhang 1 month, 4 weeks ago
Tasks marked with PF_SUSPEND_TASK are involved in system suspend or
hibernate operations. These tasks must not be frozen, as they are
responsible for coordinating or executing parts of the suspend/resume
sequence.

This patch explicitly sets their freeze_priority to FREEZE_PRIORITY_NEVER
during initialization. This makes their exemption from the freezer logic
clear in the new freeze-priority model and avoids redundant evaluations
during process traversal.

Signed-off-by: Zihuan Zhang <zhangzihuan@kylinos.cn>
---
 kernel/power/process.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/power/process.c b/kernel/power/process.c
index 06eafdb32abb..21bbca7040cf 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -147,6 +147,7 @@ int freeze_processes(void)
 
 	pm_wakeup_clear(0);
 	pm_freezing = true;
+	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);
 	error = try_to_freeze_tasks(true);
 	if (!error)
 		__usermodehelper_set_disable_depth(UMH_DISABLED);
@@ -218,6 +219,7 @@ void thaw_processes(void)
 	WARN_ON(!(curr->flags & PF_SUSPEND_TASK));
 	curr->flags &= ~PF_SUSPEND_TASK;
 
+	freeze_set_default_priority(current, FREEZE_PRIORITY_NORMAL);
 	usermodehelper_enable();
 
 	schedule();
-- 
2.25.1
Re: [RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Oleg Nesterov 1 month, 3 weeks ago
On 08/07, Zihuan Zhang wrote:
>
> --- a/kernel/power/process.c
> +++ b/kernel/power/process.c
> @@ -147,6 +147,7 @@ int freeze_processes(void)
>
>  	pm_wakeup_clear(0);
>  	pm_freezing = true;
> +	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);

But why?

Again, freeze_task() will return false anyway, this process is
PF_SUSPEND_TASK.

> @@ -218,6 +219,7 @@ void thaw_processes(void)
>  	WARN_ON(!(curr->flags & PF_SUSPEND_TASK));
>  	curr->flags &= ~PF_SUSPEND_TASK;
>
> +	freeze_set_default_priority(current, FREEZE_PRIORITY_NORMAL);
>  	usermodehelper_enable();

What if current->freeze_priority was changed via
/proc/pid/freeze_priority you add in 9/9 ?

Oleg.
Re: [RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Zihuan Zhang 1 month, 3 weeks ago
在 2025/8/8 22:39, Oleg Nesterov 写道:
> On 08/07, Zihuan Zhang wrote:
>> --- a/kernel/power/process.c
>> +++ b/kernel/power/process.c
>> @@ -147,6 +147,7 @@ int freeze_processes(void)
>>
>>   	pm_wakeup_clear(0);
>>   	pm_freezing = true;
>> +	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);
> But why?
>
> Again, freeze_task() will return false anyway, this process is
> PF_SUSPEND_TASK.

I  think there is resaon put it here. For example, systemd-sleep is a 
user-space process that executes the suspend flow.

  If we don’t set its freeze priority explicitly, our current code may 
end up with this user process being the last one that cannot freeze.

Of course, we could adjust the code logic to handle it differently, but 
in our model its freeze priority is considered the lowest, so setting it 
here ensures consistent behavior.


>> @@ -218,6 +219,7 @@ void thaw_processes(void)
>>   	WARN_ON(!(curr->flags & PF_SUSPEND_TASK));
>>   	curr->flags &= ~PF_SUSPEND_TASK;
>>
>> +	freeze_set_default_priority(current, FREEZE_PRIORITY_NORMAL);
>>   	usermodehelper_enable();
> What if current->freeze_priority was changed via
> /proc/pid/freeze_priority you add in 9/9 ?

Sorry, my oversight. You are right — in this case we probably should not 
allow user space to change the freeze_priority of a PF_SUSPEND_TASK. 
This would avoid unintended behavior during suspend.

>
> Oleg.
>
Re: [RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Oleg Nesterov 1 month, 3 weeks ago
On 08/11, Zihuan Zhang wrote:
> 
> 在 2025/8/8 22:39, Oleg Nesterov 写道:
> >On 08/07, Zihuan Zhang wrote:
> >>--- a/kernel/power/process.c
> >>+++ b/kernel/power/process.c
> >>@@ -147,6 +147,7 @@ int freeze_processes(void)
> >>
> >>  	pm_wakeup_clear(0);
> >>  	pm_freezing = true;
> >>+	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);
> >But why?
> >
> >Again, freeze_task() will return false anyway, this process is
> >PF_SUSPEND_TASK.
>
> I  think there is resaon put it here. For example, systemd-sleep is a
> user-space process that executes the suspend flow.
>
>  If we don’t set its freeze priority explicitly, our current code may end up
> with this user process being the last one that cannot freeze.

How so? sorry I don't follow.

Oleg.

Re: [RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Zihuan Zhang 1 month, 3 weeks ago
在 2025/8/11 17:32, Oleg Nesterov 写道:
> On 08/11, Zihuan Zhang wrote:
>> 在 2025/8/8 22:39, Oleg Nesterov 写道:
>>> On 08/07, Zihuan Zhang wrote:
>>>> --- a/kernel/power/process.c
>>>> +++ b/kernel/power/process.c
>>>> @@ -147,6 +147,7 @@ int freeze_processes(void)
>>>>
>>>>   	pm_wakeup_clear(0);
>>>>   	pm_freezing = true;
>>>> +	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);
>>> But why?
>>>
>>> Again, freeze_task() will return false anyway, this process is
>>> PF_SUSPEND_TASK.
>> I  think there is resaon put it here. For example, systemd-sleep is a
>> user-space process that executes the suspend flow.
>>
>>   If we don’t set its freeze priority explicitly, our current code may end up
>> with this user process being the last one that cannot freeze.
> How so? sorry I don't follow.

The problem is in this part:

+            if (user_only && !(p->flags & PF_KTHREAD) && round < 
p->freeze_priority)
+                continue;

PF_SUSPEND_TASK is a user process, so it meets the “needs freezing” 
condition and todo gets incremented. But it actually doesn’t need to 
freeze, so resulting in an infinite loop

> Oleg.
>
Re: [RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Oleg Nesterov 1 month, 3 weeks ago
On 08/11, Zihuan Zhang wrote:
> 
> 在 2025/8/11 17:32, Oleg Nesterov 写道:
> >On 08/11, Zihuan Zhang wrote:
> >>在 2025/8/8 22:39, Oleg Nesterov 写道:
> >>>On 08/07, Zihuan Zhang wrote:
> >>>>--- a/kernel/power/process.c
> >>>>+++ b/kernel/power/process.c
> >>>>@@ -147,6 +147,7 @@ int freeze_processes(void)
> >>>>
> >>>>  	pm_wakeup_clear(0);
> >>>>  	pm_freezing = true;
> >>>>+	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);
> >>>But why?
> >>>
> >>>Again, freeze_task() will return false anyway, this process is
> >>>PF_SUSPEND_TASK.
> >>I  think there is resaon put it here. For example, systemd-sleep is a
> >>user-space process that executes the suspend flow.
> >>
> >>  If we don’t set its freeze priority explicitly, our current code may end up
> >>with this user process being the last one that cannot freeze.
> >How so? sorry I don't follow.
>
> The problem is in this part:
>
> +            if (user_only && !(p->flags & PF_KTHREAD) && round <
> p->freeze_priority)
> +                continue;
>
> PF_SUSPEND_TASK is a user process, so it meets the “needs freezing”
> condition and todo gets incremented.
            ^^^^^^^^^^^^^^^^^^^^^^^^^

No.
	if (p == current || !freeze_task(p))
		continue;

	todo++;

Again, again, freeze_task(p) returns false.

> But it actually doesn’t need to freeze,
> so resulting in an infinite loop

I don't think so.

Oleg.

Re: [RFC PATCH v1 5/9] freezer: set default freeze priority for PF_SUSPEND_TASK processes
Posted by Zihuan Zhang 1 month, 3 weeks ago
在 2025/8/11 17:46, Oleg Nesterov 写道:
> On 08/11, Zihuan Zhang wrote:
>> 在 2025/8/11 17:32, Oleg Nesterov 写道:
>>> On 08/11, Zihuan Zhang wrote:
>>>> 在 2025/8/8 22:39, Oleg Nesterov 写道:
>>>>> On 08/07, Zihuan Zhang wrote:
>>>>>> --- a/kernel/power/process.c
>>>>>> +++ b/kernel/power/process.c
>>>>>> @@ -147,6 +147,7 @@ int freeze_processes(void)
>>>>>>
>>>>>>   	pm_wakeup_clear(0);
>>>>>>   	pm_freezing = true;
>>>>>> +	freeze_set_default_priority(current, FREEZE_PRIORITY_NEVER);
>>>>> But why?
>>>>>
>>>>> Again, freeze_task() will return false anyway, this process is
>>>>> PF_SUSPEND_TASK.
>>>> I  think there is resaon put it here. For example, systemd-sleep is a
>>>> user-space process that executes the suspend flow.
>>>>
>>>>   If we don’t set its freeze priority explicitly, our current code may end up
>>>> with this user process being the last one that cannot freeze.
>>> How so? sorry I don't follow.
>> The problem is in this part:
>>
>> +            if (user_only && !(p->flags & PF_KTHREAD) && round <
>> p->freeze_priority)
>> +                continue;
>>
>> PF_SUSPEND_TASK is a user process, so it meets the “needs freezing”
>> condition and todo gets incremented.
>              ^^^^^^^^^^^^^^^^^^^^^^^^^
>
> No.
> 	if (p == current || !freeze_task(p))
> 		continue;
>
> 	todo++;
>
> Again, again, freeze_task(p) returns false.
>
>> But it actually doesn’t need to freeze,
>> so resulting in an infinite loop
> I don't think so.
>
> Oleg.
Sorry, you’re right — it’s indeed unnecessary. In an earlier version, I 
incremented the counter before the continue, but I later removed that 
and forgot about it.