[PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce

Zihuan Zhang posted 1 patch 2 months, 3 weeks ago
kernel/power/process.c | 2 +-
1 file changed, 9 insertion(+), 1 deletion(-)
[PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce
Posted by Zihuan Zhang 2 months, 3 weeks ago
Hi all,

This patch series improves the performance of the process freezer by
skipping zombie tasks during freezing.

In the suspend and hibernation paths, the freezer traverses all tasks
and attempts to freeze them. However, zombie tasks (EXIT_ZOMBIE with
PF_EXITING) are already dead — they are not schedulable and cannot enter
the refrigerator. Attempting to freeze such tasks is redundant and
unnecessarily increases freezing time.

In particular, on systems under fork storm conditions (e.g., many
short-lived processes quickly becoming zombies), the number of zombie tasks
can spike into the thousands or more. We observed that this causes the
freezer loop to waste significant time processing tasks that are guaranteed
to not need freezing.

Testing and Results

Platform:
- Architecture: x86_64
- CPU: ZHAOXIN KaiXian KX-7000
- RAM: 16 GB
- Kernel: v6.6.93

result without the patch:
dmesg | grep elap
[  219.608992] Freezing user space processes completed (elapsed 0.010 seconds)
[  219.617355] Freezing remaining freezable tasks completed (elapsed 0.008 seconds)
[  228.029119] Freezing user space processes completed (elapsed 0.013 seconds)
[  228.040672] Freezing remaining freezable tasks completed (elapsed 0.011 seconds)
[  236.879065] Freezing user space processes completed (elapsed 0.020 seconds)
[  236.897976] Freezing remaining freezable tasks completed (elapsed 0.018 seconds)
[  246.276679] Freezing user space processes completed (elapsed 0.026 seconds)
[  246.298636] Freezing remaining freezable tasks completed (elapsed 0.021 seconds)
[  256.221504] Freezing user space processes completed (elapsed 0.030 seconds)
[  256.248955] Freezing remaining freezable tasks completed (elapsed 0.027 seconds)
[  266.674987] Freezing user space processes completed (elapsed 0.040 seconds)
[  266.709811] Freezing remaining freezable tasks completed (elapsed 0.034 seconds)
[  277.701679] Freezing user space processes completed (elapsed 0.046 seconds)
[  277.742048] Freezing remaining freezable tasks completed (elapsed 0.040 seconds)
[  289.246611] Freezing user space processes completed (elapsed 0.046 seconds)
[  289.290753] Freezing remaining freezable tasks completed (elapsed 0.044 seconds)
[  301.516854] Freezing user space processes completed (elapsed 0.041 seconds)
[  301.576287] Freezing remaining freezable tasks completed (elapsed 0.059 seconds)
[  314.422499] Freezing user space processes completed (elapsed 0.043 seconds)
[  314.465804] Freezing remaining freezable tasks completed (elapsed 0.043 seconds)

result with the patch:
dmesg | grep elap
[   54.161674] Freezing user space processes completed (elapsed 0.007 seconds)
[   54.171536] Freezing remaining freezable tasks completed (elapsed 0.009 seconds)
[   62.556462] Freezing user space processes completed (elapsed 0.006 seconds)
[   62.566496] Freezing remaining freezable tasks completed (elapsed 0.010 seconds)
[   71.395421] Freezing user space processes completed (elapsed 0.009 seconds)
[   71.402820] Freezing remaining freezable tasks completed (elapsed 0.007 seconds)
[   80.785463] Freezing user space processes completed (elapsed 0.010 seconds)
[   80.793914] Freezing remaining freezable tasks completed (elapsed 0.008 seconds)
[   90.962659] Freezing user space processes completed (elapsed 0.012 seconds)
[   90.973519] Freezing remaining freezable tasks completed (elapsed 0.010 seconds)
[  101.435638] Freezing user space processes completed (elapsed 0.013 seconds)
[  101.449023] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
[  112.669786] Freezing user space processes completed (elapsed 0.015 seconds)
[  112.683540] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
[  124.585681] Freezing user space processes completed (elapsed 0.017 seconds)
[  124.599553] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
[  136.826635] Freezing user space processes completed (elapsed 0.016 seconds)
[  136.841840] Freezing remaining freezable tasks completed (elapsed 0.015 seconds)
[  149.686575] Freezing user space processes completed (elapsed 0.016 seconds)
[  149.701549] Freezing remaining freezable tasks completed (elapsed 0.014 seconds)

Here is the user-space fork storm simulator used for testing:

```c
// create_zombie.c

void usage(const char *prog) {
    fprintf(stderr, "Usage: %s <number_of_zombies>\n", prog);
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        usage(argv[0]);
    }

    long num_zombies = strtol(argv[1], NULL, 10);
    if (num_zombies <= 0 || num_zombies > 1000000) {
        fprintf(stderr, "Invalid number of zombies: %ld\n", num_zombies);
        exit(EXIT_FAILURE);
    }

    printf("Creating %ld zombie processes...\n", num_zombies);

    for (long i = 0; i < num_zombies; i++) {
        pid_t pid = fork();
        if (pid < 0) {
            perror("fork failed");
            exit(EXIT_FAILURE);
        } else if (pid == 0) {
            // Child exits immediately
            exit(0);
        }
        // Parent does NOT wait, leaving zombie
    }

    printf("All child processes created. Sleeping for 60 seconds...\n");
    sleep(60);

    printf("Parent exiting, zombies will be reaped by init.\n");
    return 0;
}
```

And we used a shell loop to suspend repeatedly:

```bash
LOOPS=10

echo none > /sys/power/pm_test
echo 5 > /sys/module/suspend/parameters/pm_test_delay
for ((i=1; i<=LOOPS; i++)); do
echo "===== Test round $i/$LOOPS ====="
./create_zombie $((i * 3000)) &
sleep 5
echo mem > /sys/power/state

pkill create_zombie
echo "Round $i complete. Waiting 5s..."
sleep 5

done
echo "==== All $LOOPS rounds complete ===="
```

Zihuan Zhang (1):
  PM / Freezer: Skip zombie/dead processes to reduce freeze latency

 kernel/power/process.c | 2 +-
 1 file changed, 9 insertion(+), 1 deletion(-)

-- 
2.25.1
Re: [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce
Posted by Rafael J. Wysocki 2 months, 3 weeks ago
Hi,

On Wed, Jul 16, 2025 at 8:26 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote:
>
> Hi all,
>
> This patch series improves the performance of the process freezer by
> skipping zombie tasks during freezing.
>
> In the suspend and hibernation paths, the freezer traverses all tasks
> and attempts to freeze them. However, zombie tasks (EXIT_ZOMBIE with
> PF_EXITING) are already dead — they are not schedulable and cannot enter
> the refrigerator. Attempting to freeze such tasks is redundant and
> unnecessarily increases freezing time.
>
> In particular, on systems under fork storm conditions (e.g., many
> short-lived processes quickly becoming zombies), the number of zombie tasks
> can spike into the thousands or more. We observed that this causes the
> freezer loop to waste significant time processing tasks that are guaranteed
> to not need freezing.

I think that the discussion with Peter regarding this has not been concluded.

I thought that there was an alternative patch proposed during that
discussion.  If I'm not mistaken about this, what happened to that
patch?

Thanks!

> Testing and Results
>
> Platform:
> - Architecture: x86_64
> - CPU: ZHAOXIN KaiXian KX-7000
> - RAM: 16 GB
> - Kernel: v6.6.93
>
> result without the patch:
> dmesg | grep elap
> [  219.608992] Freezing user space processes completed (elapsed 0.010 seconds)
> [  219.617355] Freezing remaining freezable tasks completed (elapsed 0.008 seconds)
> [  228.029119] Freezing user space processes completed (elapsed 0.013 seconds)
> [  228.040672] Freezing remaining freezable tasks completed (elapsed 0.011 seconds)
> [  236.879065] Freezing user space processes completed (elapsed 0.020 seconds)
> [  236.897976] Freezing remaining freezable tasks completed (elapsed 0.018 seconds)
> [  246.276679] Freezing user space processes completed (elapsed 0.026 seconds)
> [  246.298636] Freezing remaining freezable tasks completed (elapsed 0.021 seconds)
> [  256.221504] Freezing user space processes completed (elapsed 0.030 seconds)
> [  256.248955] Freezing remaining freezable tasks completed (elapsed 0.027 seconds)
> [  266.674987] Freezing user space processes completed (elapsed 0.040 seconds)
> [  266.709811] Freezing remaining freezable tasks completed (elapsed 0.034 seconds)
> [  277.701679] Freezing user space processes completed (elapsed 0.046 seconds)
> [  277.742048] Freezing remaining freezable tasks completed (elapsed 0.040 seconds)
> [  289.246611] Freezing user space processes completed (elapsed 0.046 seconds)
> [  289.290753] Freezing remaining freezable tasks completed (elapsed 0.044 seconds)
> [  301.516854] Freezing user space processes completed (elapsed 0.041 seconds)
> [  301.576287] Freezing remaining freezable tasks completed (elapsed 0.059 seconds)
> [  314.422499] Freezing user space processes completed (elapsed 0.043 seconds)
> [  314.465804] Freezing remaining freezable tasks completed (elapsed 0.043 seconds)
>
> result with the patch:
> dmesg | grep elap
> [   54.161674] Freezing user space processes completed (elapsed 0.007 seconds)
> [   54.171536] Freezing remaining freezable tasks completed (elapsed 0.009 seconds)
> [   62.556462] Freezing user space processes completed (elapsed 0.006 seconds)
> [   62.566496] Freezing remaining freezable tasks completed (elapsed 0.010 seconds)
> [   71.395421] Freezing user space processes completed (elapsed 0.009 seconds)
> [   71.402820] Freezing remaining freezable tasks completed (elapsed 0.007 seconds)
> [   80.785463] Freezing user space processes completed (elapsed 0.010 seconds)
> [   80.793914] Freezing remaining freezable tasks completed (elapsed 0.008 seconds)
> [   90.962659] Freezing user space processes completed (elapsed 0.012 seconds)
> [   90.973519] Freezing remaining freezable tasks completed (elapsed 0.010 seconds)
> [  101.435638] Freezing user space processes completed (elapsed 0.013 seconds)
> [  101.449023] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
> [  112.669786] Freezing user space processes completed (elapsed 0.015 seconds)
> [  112.683540] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
> [  124.585681] Freezing user space processes completed (elapsed 0.017 seconds)
> [  124.599553] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
> [  136.826635] Freezing user space processes completed (elapsed 0.016 seconds)
> [  136.841840] Freezing remaining freezable tasks completed (elapsed 0.015 seconds)
> [  149.686575] Freezing user space processes completed (elapsed 0.016 seconds)
> [  149.701549] Freezing remaining freezable tasks completed (elapsed 0.014 seconds)
>
> Here is the user-space fork storm simulator used for testing:
>
> ```c
> // create_zombie.c
>
> void usage(const char *prog) {
>     fprintf(stderr, "Usage: %s <number_of_zombies>\n", prog);
>     exit(EXIT_FAILURE);
> }
>
> int main(int argc, char *argv[]) {
>     if (argc != 2) {
>         usage(argv[0]);
>     }
>
>     long num_zombies = strtol(argv[1], NULL, 10);
>     if (num_zombies <= 0 || num_zombies > 1000000) {
>         fprintf(stderr, "Invalid number of zombies: %ld\n", num_zombies);
>         exit(EXIT_FAILURE);
>     }
>
>     printf("Creating %ld zombie processes...\n", num_zombies);
>
>     for (long i = 0; i < num_zombies; i++) {
>         pid_t pid = fork();
>         if (pid < 0) {
>             perror("fork failed");
>             exit(EXIT_FAILURE);
>         } else if (pid == 0) {
>             // Child exits immediately
>             exit(0);
>         }
>         // Parent does NOT wait, leaving zombie
>     }
>
>     printf("All child processes created. Sleeping for 60 seconds...\n");
>     sleep(60);
>
>     printf("Parent exiting, zombies will be reaped by init.\n");
>     return 0;
> }
> ```
>
> And we used a shell loop to suspend repeatedly:
>
> ```bash
> LOOPS=10
>
> echo none > /sys/power/pm_test
> echo 5 > /sys/module/suspend/parameters/pm_test_delay
> for ((i=1; i<=LOOPS; i++)); do
> echo "===== Test round $i/$LOOPS ====="
> ./create_zombie $((i * 3000)) &
> sleep 5
> echo mem > /sys/power/state
>
> pkill create_zombie
> echo "Round $i complete. Waiting 5s..."
> sleep 5
>
> done
> echo "==== All $LOOPS rounds complete ===="
> ```
>
> Zihuan Zhang (1):
>   PM / Freezer: Skip zombie/dead processes to reduce freeze latency
>
>  kernel/power/process.c | 2 +-
>  1 file changed, 9 insertion(+), 1 deletion(-)
>
> --
> 2.25.1
>
Re: [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce
Posted by Zihuan Zhang 2 months, 3 weeks ago
HI Rafael,

在 2025/7/16 20:26, Rafael J. Wysocki 写道:
> Hi,
>
> On Wed, Jul 16, 2025 at 8:26 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote:
>> Hi all,
>>
>> This patch series improves the performance of the process freezer by
>> skipping zombie tasks during freezing.
>>
>> In the suspend and hibernation paths, the freezer traverses all tasks
>> and attempts to freeze them. However, zombie tasks (EXIT_ZOMBIE with
>> PF_EXITING) are already dead — they are not schedulable and cannot enter
>> the refrigerator. Attempting to freeze such tasks is redundant and
>> unnecessarily increases freezing time.
>>
>> In particular, on systems under fork storm conditions (e.g., many
>> short-lived processes quickly becoming zombies), the number of zombie tasks
>> can spike into the thousands or more. We observed that this causes the
>> freezer loop to waste significant time processing tasks that are guaranteed
>> to not need freezing.
> I think that the discussion with Peter regarding this has not been concluded.
>
> I thought that there was an alternative patch proposed during that
> discussion.  If I'm not mistaken about this, what happened to that
> patch?
>
> Thanks!
>

Currently, the general consensus from the discussion is that skipping 
zombie or dead tasks can help reduce locking overhead during freezing. 
The remaining question is how best to implement that.

Peter suggested skipping all tasks with PF_NOFREEZE, which would make 
the logic more general and cover all cases. However, as Oleg pointed 
out, the current implementation based on PF_NOFREEZE might be problematic.

My current thought is that exit_state already reliably covers all 
exiting user processes, and it’s a good fit for skipping user-space 
tasks. For the kernel side, we may safely skip a few kernel threads like 
kthreadd that set PF_NOFREEZE and never change it — we can consider 
refining this further in the future.


>> Testing and Results
>>
>> Platform:
>> - Architecture: x86_64
>> - CPU: ZHAOXIN KaiXian KX-7000
>> - RAM: 16 GB
>> - Kernel: v6.6.93
>>
>> result without the patch:
>> dmesg | grep elap
>> [  219.608992] Freezing user space processes completed (elapsed 0.010 seconds)
>> [  219.617355] Freezing remaining freezable tasks completed (elapsed 0.008 seconds)
>> [  228.029119] Freezing user space processes completed (elapsed 0.013 seconds)
>> [  228.040672] Freezing remaining freezable tasks completed (elapsed 0.011 seconds)
>> [  236.879065] Freezing user space processes completed (elapsed 0.020 seconds)
>> [  236.897976] Freezing remaining freezable tasks completed (elapsed 0.018 seconds)
>> [  246.276679] Freezing user space processes completed (elapsed 0.026 seconds)
>> [  246.298636] Freezing remaining freezable tasks completed (elapsed 0.021 seconds)
>> [  256.221504] Freezing user space processes completed (elapsed 0.030 seconds)
>> [  256.248955] Freezing remaining freezable tasks completed (elapsed 0.027 seconds)
>> [  266.674987] Freezing user space processes completed (elapsed 0.040 seconds)
>> [  266.709811] Freezing remaining freezable tasks completed (elapsed 0.034 seconds)
>> [  277.701679] Freezing user space processes completed (elapsed 0.046 seconds)
>> [  277.742048] Freezing remaining freezable tasks completed (elapsed 0.040 seconds)
>> [  289.246611] Freezing user space processes completed (elapsed 0.046 seconds)
>> [  289.290753] Freezing remaining freezable tasks completed (elapsed 0.044 seconds)
>> [  301.516854] Freezing user space processes completed (elapsed 0.041 seconds)
>> [  301.576287] Freezing remaining freezable tasks completed (elapsed 0.059 seconds)
>> [  314.422499] Freezing user space processes completed (elapsed 0.043 seconds)
>> [  314.465804] Freezing remaining freezable tasks completed (elapsed 0.043 seconds)
>>
>> result with the patch:
>> dmesg | grep elap
>> [   54.161674] Freezing user space processes completed (elapsed 0.007 seconds)
>> [   54.171536] Freezing remaining freezable tasks completed (elapsed 0.009 seconds)
>> [   62.556462] Freezing user space processes completed (elapsed 0.006 seconds)
>> [   62.566496] Freezing remaining freezable tasks completed (elapsed 0.010 seconds)
>> [   71.395421] Freezing user space processes completed (elapsed 0.009 seconds)
>> [   71.402820] Freezing remaining freezable tasks completed (elapsed 0.007 seconds)
>> [   80.785463] Freezing user space processes completed (elapsed 0.010 seconds)
>> [   80.793914] Freezing remaining freezable tasks completed (elapsed 0.008 seconds)
>> [   90.962659] Freezing user space processes completed (elapsed 0.012 seconds)
>> [   90.973519] Freezing remaining freezable tasks completed (elapsed 0.010 seconds)
>> [  101.435638] Freezing user space processes completed (elapsed 0.013 seconds)
>> [  101.449023] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
>> [  112.669786] Freezing user space processes completed (elapsed 0.015 seconds)
>> [  112.683540] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
>> [  124.585681] Freezing user space processes completed (elapsed 0.017 seconds)
>> [  124.599553] Freezing remaining freezable tasks completed (elapsed 0.013 seconds)
>> [  136.826635] Freezing user space processes completed (elapsed 0.016 seconds)
>> [  136.841840] Freezing remaining freezable tasks completed (elapsed 0.015 seconds)
>> [  149.686575] Freezing user space processes completed (elapsed 0.016 seconds)
>> [  149.701549] Freezing remaining freezable tasks completed (elapsed 0.014 seconds)
>>
>> Here is the user-space fork storm simulator used for testing:
>>
>> ```c
>> // create_zombie.c
>>
>> void usage(const char *prog) {
>>      fprintf(stderr, "Usage: %s <number_of_zombies>\n", prog);
>>      exit(EXIT_FAILURE);
>> }
>>
>> int main(int argc, char *argv[]) {
>>      if (argc != 2) {
>>          usage(argv[0]);
>>      }
>>
>>      long num_zombies = strtol(argv[1], NULL, 10);
>>      if (num_zombies <= 0 || num_zombies > 1000000) {
>>          fprintf(stderr, "Invalid number of zombies: %ld\n", num_zombies);
>>          exit(EXIT_FAILURE);
>>      }
>>
>>      printf("Creating %ld zombie processes...\n", num_zombies);
>>
>>      for (long i = 0; i < num_zombies; i++) {
>>          pid_t pid = fork();
>>          if (pid < 0) {
>>              perror("fork failed");
>>              exit(EXIT_FAILURE);
>>          } else if (pid == 0) {
>>              // Child exits immediately
>>              exit(0);
>>          }
>>          // Parent does NOT wait, leaving zombie
>>      }
>>
>>      printf("All child processes created. Sleeping for 60 seconds...\n");
>>      sleep(60);
>>
>>      printf("Parent exiting, zombies will be reaped by init.\n");
>>      return 0;
>> }
>> ```
>>
>> And we used a shell loop to suspend repeatedly:
>>
>> ```bash
>> LOOPS=10
>>
>> echo none > /sys/power/pm_test
>> echo 5 > /sys/module/suspend/parameters/pm_test_delay
>> for ((i=1; i<=LOOPS; i++)); do
>> echo "===== Test round $i/$LOOPS ====="
>> ./create_zombie $((i * 3000)) &
>> sleep 5
>> echo mem > /sys/power/state
>>
>> pkill create_zombie
>> echo "Round $i complete. Waiting 5s..."
>> sleep 5
>>
>> done
>> echo "==== All $LOOPS rounds complete ===="
>> ```
>>
>> Zihuan Zhang (1):
>>    PM / Freezer: Skip zombie/dead processes to reduce freeze latency
>>
>>   kernel/power/process.c | 2 +-
>>   1 file changed, 9 insertion(+), 1 deletion(-)
>>
>> --
>> 2.25.1
>>
Re: [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce
Posted by Rafael J. Wysocki 2 months, 3 weeks ago
On Thu, Jul 17, 2025 at 3:02 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote:
>
> HI Rafael,
>
> 在 2025/7/16 20:26, Rafael J. Wysocki 写道:
> > Hi,
> >
> > On Wed, Jul 16, 2025 at 8:26 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote:
> >> Hi all,
> >>
> >> This patch series improves the performance of the process freezer by
> >> skipping zombie tasks during freezing.
> >>
> >> In the suspend and hibernation paths, the freezer traverses all tasks
> >> and attempts to freeze them. However, zombie tasks (EXIT_ZOMBIE with
> >> PF_EXITING) are already dead — they are not schedulable and cannot enter
> >> the refrigerator. Attempting to freeze such tasks is redundant and
> >> unnecessarily increases freezing time.
> >>
> >> In particular, on systems under fork storm conditions (e.g., many
> >> short-lived processes quickly becoming zombies), the number of zombie tasks
> >> can spike into the thousands or more. We observed that this causes the
> >> freezer loop to waste significant time processing tasks that are guaranteed
> >> to not need freezing.
> > I think that the discussion with Peter regarding this has not been concluded.
> >
> > I thought that there was an alternative patch proposed during that
> > discussion.  If I'm not mistaken about this, what happened to that
> > patch?
> >
> > Thanks!
> >
>
> Currently, the general consensus from the discussion is that skipping
> zombie or dead tasks can help reduce locking overhead during freezing.

Peter doesn't seem to be convinced that this is the case.

> The remaining question is how best to implement that.
>
> Peter suggested skipping all tasks with PF_NOFREEZE, which would make
> the logic more general and cover all cases. However, as Oleg pointed
> out, the current implementation based on PF_NOFREEZE might be problematic.
>
> My current thought is that exit_state already reliably covers all
> exiting user processes, and it’s a good fit for skipping user-space
> tasks. For the kernel side, we may safely skip a few kernel threads like
> kthreadd that set PF_NOFREEZE and never change it — we can consider
> refining this further in the future.

There is the counter argument of special-casing of p->exit_state and
the relatively weak justification for it.

You have created a synthetic workload where it matters, but how likely
is it to be the case in practice?
Re: [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce
Posted by Zihuan Zhang 2 months, 2 weeks ago
在 2025/7/17 17:50, Rafael J. Wysocki 写道:
> On Thu, Jul 17, 2025 at 3:02 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote:
>> HI Rafael,
>>
>> 在 2025/7/16 20:26, Rafael J. Wysocki 写道:
>>> Hi,
>>>
>>> On Wed, Jul 16, 2025 at 8:26 AM Zihuan Zhang <zhangzihuan@kylinos.cn> wrote:
>>>> Hi all,
>>>>
>>>> This patch series improves the performance of the process freezer by
>>>> skipping zombie tasks during freezing.
>>>>
>>>> In the suspend and hibernation paths, the freezer traverses all tasks
>>>> and attempts to freeze them. However, zombie tasks (EXIT_ZOMBIE with
>>>> PF_EXITING) are already dead — they are not schedulable and cannot enter
>>>> the refrigerator. Attempting to freeze such tasks is redundant and
>>>> unnecessarily increases freezing time.
>>>>
>>>> In particular, on systems under fork storm conditions (e.g., many
>>>> short-lived processes quickly becoming zombies), the number of zombie tasks
>>>> can spike into the thousands or more. We observed that this causes the
>>>> freezer loop to waste significant time processing tasks that are guaranteed
>>>> to not need freezing.
>>> I think that the discussion with Peter regarding this has not been concluded.
>>>
>>> I thought that there was an alternative patch proposed during that
>>> discussion.  If I'm not mistaken about this, what happened to that
>>> patch?
>>>
>>> Thanks!
>>>
>> Currently, the general consensus from the discussion is that skipping
>> zombie or dead tasks can help reduce locking overhead during freezing.
> Peter doesn't seem to be convinced that this is the case.
>

Yeah.

>> The remaining question is how best to implement that.
>>
>> Peter suggested skipping all tasks with PF_NOFREEZE, which would make
>> the logic more general and cover all cases. However, as Oleg pointed
>> out, the current implementation based on PF_NOFREEZE might be problematic.
>>
>> My current thought is that exit_state already reliably covers all
>> exiting user processes, and it’s a good fit for skipping user-space
>> tasks. For the kernel side, we may safely skip a few kernel threads like
>> kthreadd that set PF_NOFREEZE and never change it — we can consider
>> refining this further in the future.
> There is the counter argument of special-casing of p->exit_state and
> the relatively weak justification for it.
>
> You have created a synthetic workload where it matters, but how likely
> is it to be the case in practice?


Our initial thought was that the freezer should primarily focus on tasks 
that can be frozen. If a task is not freezable and its state will not 
change (such as kernel threads that have PF_NOFREEZE set permanently),

  it should be safe to skip it during the iteration. This helps to 
reduce unnecessary overhead when handling a large number of such tasks.

We do not insist that this is the only correct way to implement the 
optimization — if there’s a better approach that is equally safe and 
more general, we are happy to adopt it.

In practice, the improvement becomes noticeable only when there are a 
lot of tasks present. So the benefit is scenario-dependent, and we agree 
that real-world relevance should be considered carefully.

Thanks again for the discussion.