From baa86f09e5c14d767294fc4757d499422f895e4a Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 25 Feb 2021 18:48:08 +0100 Subject: [PATCH] Real-time fixes (#2630) * Fix path of cpu.rt_runtime_us sysfs file Fix detection of CPU bandwidth allocation (CONFIG_RT_GROUP_SCHED) option by checking the correct file location. * Set priority limit and memory lock limit Set a soft limit of real-time priority 90 and hard limit of 99. The maximum is 99, to avoid add-ons using such a high priority without second thought set the soft limit to 90. This allows a process to higher the limit to 99, if really required. Also set max locked memory to 128MB. Locking memory from getting paged out is often used for the real-time process/thread to avoid delays due to swapping/pageing in. Ideally a real-time process should only do the real-time job, hence not need too much memory. * Remove check for support_cpu_realtime and set correct limit for audio plug-in --- supervisor/docker/__init__.py | 2 +- supervisor/docker/addon.py | 8 ++++++-- supervisor/docker/audio.py | 5 ++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/supervisor/docker/__init__.py b/supervisor/docker/__init__.py index 4c1bc984d..471f77f20 100644 --- a/supervisor/docker/__init__.py +++ b/supervisor/docker/__init__.py @@ -61,7 +61,7 @@ class DockerInfo: @property def support_cpu_realtime(self) -> bool: """Return true, if CONFIG_RT_GROUP_SCHED is loaded.""" - if not Path("/sys/fs/cgroup/cpu.rt_runtime_us").exists(): + if not Path("/sys/fs/cgroup/cpu/cpu.rt_runtime_us").exists(): return False return bool(os.environ.get(ENV_SUPERVISOR_CPU_RT, 0)) diff --git a/supervisor/docker/addon.py b/supervisor/docker/addon.py index 927799e25..4f33fee59 100644 --- a/supervisor/docker/addon.py +++ b/supervisor/docker/addon.py @@ -265,8 +265,12 @@ class DockerAddon(DockerInterface): limits: List[docker.types.Ulimit] = [] # Need schedule functions - if self.addon.with_realtime and self.sys_docker.info.support_cpu_realtime: - limits.append(docker.types.Ulimit(name="rtprio", soft=99)) + if self.addon.with_realtime: + limits.append(docker.types.Ulimit(name="rtprio", soft=90, hard=99)) + + # Set available memory for memlock to 128MB + mem = 128 * 1024 * 1024 + limits.append(docker.types.Ulimit(name="memlock", soft=mem, hard=mem)) # Return None if no capabilities is present if limits: diff --git a/supervisor/docker/audio.py b/supervisor/docker/audio.py index 2f9a27454..a7e5198ee 100644 --- a/supervisor/docker/audio.py +++ b/supervisor/docker/audio.py @@ -59,9 +59,8 @@ class DockerAudio(DockerInterface, CoreSysAttributes): @property def ulimits(self) -> List[docker.types.Ulimit]: """Generate ulimits for audio.""" - if not self.sys_docker.info.support_cpu_realtime: - return None - return [docker.types.Ulimit(name="rtprio", soft=99)] + # Pulseaudio by default tries to use real-time scheduling with priority of 5. + return [docker.types.Ulimit(name="rtprio", soft=10, hard=10)] @property def cpu_rt_runtime(self) -> Optional[int]: