From c47ac8d2eb8e6c28f0b5af1dd212cab72b758d94 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sun, 12 Apr 2026 21:43:18 +0200 Subject: [PATCH] Fix pytest OOM: nested 2GB cgroup per package with MemorySwapMax=0 Each pytest package runs in its own systemd-run scope with: - MemoryMax=2G per package (nested inside the 4GB parent cgroup) - MemorySwapMax=0 to prevent zram thrashing (the real cause of freezes) - gc.collect() between packages to free Python heap --- scripts/pytest_changed_packages.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/scripts/pytest_changed_packages.py b/scripts/pytest_changed_packages.py index e2c0ae8..75c4170 100755 --- a/scripts/pytest_changed_packages.py +++ b/scripts/pytest_changed_packages.py @@ -11,11 +11,14 @@ all tests are run as a fallback. from __future__ import annotations +import gc from pathlib import Path, PurePosixPath +import shutil import subprocess import sys _MIN_SUBPACKAGE_DEPTH = 2 +_PER_PACKAGE_MEM = "2G" def _affected_packages(files: list[str]) -> set[str] | None: @@ -88,9 +91,24 @@ def main() -> int: return 0 # Run each package in its own subprocess so memory is freed between runs. + # Wrap each in a nested cgroup with MemorySwapMax=0 so it gets killed + # instantly at the limit instead of thrashing swap/zram. + use_cgroup = shutil.which("systemd-run") is not None for pkg in sorted(packages): cmd = _build_pytest_command({pkg}) + if use_cgroup: + cmd = [ + "systemd-run", + "--user", + "--scope", + "-p", + f"MemoryMax={_PER_PACKAGE_MEM}", + "-p", + "MemorySwapMax=0", + *cmd, + ] result = subprocess.run(cmd, check=False) + gc.collect() if result.returncode != 0: return result.returncode return 0