linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce
@ 2025-07-16  6:26 Zihuan Zhang
  2025-07-16  6:26 ` [PATCH v4] PM / Freezer: Skip zombie/dead processes to reduce freeze latency Zihuan Zhang
  2025-07-16 12:26 ` [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce Rafael J. Wysocki
  0 siblings, 2 replies; 13+ messages in thread
From: Zihuan Zhang @ 2025-07-16  6:26 UTC (permalink / raw)
  To: rafael J . wysocki, Peter Zijlstra
  Cc: Oleg Nesterov, len brown, pavel machek, linux-pm, linux-kernel,
	Zihuan Zhang

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


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2025-07-21 10:39 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-16  6:26 [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce Zihuan Zhang
2025-07-16  6:26 ` [PATCH v4] PM / Freezer: Skip zombie/dead processes to reduce freeze latency Zihuan Zhang
2025-07-16 16:38   ` Oleg Nesterov
2025-07-16 18:36     ` Peter Zijlstra
2025-07-17  1:30       ` Zihuan Zhang
2025-07-17  1:43         ` Oleg Nesterov
2025-07-17  1:16     ` Zihuan Zhang
2025-07-17  1:31       ` Oleg Nesterov
2025-07-17  8:45         ` Zihuan Zhang
2025-07-16 12:26 ` [PATCH v4 0/1] PM / Freezer: Skip zombie/dead processes to reduce Rafael J. Wysocki
2025-07-17  1:02   ` Zihuan Zhang
2025-07-17  9:50     ` Rafael J. Wysocki
2025-07-21 10:39       ` Zihuan Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).