I am trying to restrict the swap usage of a process using MemorySwapMax
as mentioned in the doc with Ubuntu 18.04.
Environment
ubuntu@vrni-platform:/usr/lib/systemd/system$ uname -a
Linux vrni-platform 4.15.0-143-generic #147-Ubuntu SMP Wed Apr 14 16:10:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
ubuntu@vrni-platform:/usr/lib/systemd/system$ systemctl --version
systemd 237
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
My systemd unit file looks like below
[Unit]
Description=My service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=support
MemoryMax=2000M
KillMode=process
MemoryAccounting=true
OOMScoreAdjust=1000
MemorySwapMax=0
ExecStart=/usr/bin/java -cp /home/support -XX:NativeMemoryTracking=summary -Xmx10000m MemoryConsumer 100 200 1
I tried to disable swap for this process by specifying 0 for MemorySwapMax
. But it seems there was some issue in systemd which is fixed in systemd 239.
So I also tried setting MemorySwapMax=1M
. But that also seems to be not restricting the swap memory usage for this systemd service.
The documentation for MemorySwapMax
states this
This setting is supported only if the unified control group hierarchy is used and disables MemoryLimit=.
So as mentioned in this answer I can see cgroup v2 enabled on my setup.
ubuntu@vrni-platform:/tmp/debraj$ sudo mount -t cgroup2 none /tmp/debraj
ubuntu@vrni-platform:/tmp/debraj$ ls -l /tmp/debraj/
total 0
-r--r--r-- 1 root root 0 Jul 2 17:13 cgroup.controllers
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.max.depth
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.max.descendants
-rw-r--r-- 1 root root 0 Jun 30 14:42 cgroup.procs
-r--r--r-- 1 root root 0 Jul 2 17:13 cgroup.stat
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.subtree_control
-rw-r--r-- 1 root root 0 Jul 2 17:13 cgroup.threads
drwxr-xr-x 2 root root 0 Jun 30 14:42 init.scope
drwxr-xr-x 87 root root 0 Jul 2 15:05 system.slice
drwxr-xr-x 7 root root 0 Jun 30 15:22 user.slice
ubuntu@vrni-platform:/tmp/debraj$ sudo umount /tmp/debraj
MemoryConsumer.java is like below
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
public class MemoryConsumer {
public static void main(String[] args) throws InterruptedException, IOException {
int size = Integer.parseInt(args[0]);
int count = Integer.parseInt(args[1]);
int sleepMs = Integer.parseInt(args[2]);
List<ByteBuffer> list1 = new ArrayList<>();
List<byte[]> list2 = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i=0; i<count; i++) {
list1.add(ByteBuffer.allocateDirect(size*1024*1024));
//list2.add(new byte [size*1024*1024]);
long end = System.currentTimeMillis();
System.out.println("Allocated memory " + (i*size) + " MB\n" + (end-start) + " ms");
Thread.sleep(sleepMs);
}
}
}
Can someone suggest what could be going wrong here?
This has been answered in systemd mailing list.
Re-posting relevant parts.
Looks like your Ubuntu version is using the "hybrid" cgroup mode by default. Cgroup v2 is indeed enabled in your kernel, but not necessarily in use – in the hybrid mode, systemd still mounts all resource controllers (cpu, memory, etc.) in v1 mode and only sets up its own process tracking in the v2 tree. See
findmnt
.You could boot with the systemd.unified_cgroup_hierarchy=1 kernel option to switch everything to cgroups v2, but if you're using container software (docker, podman) make sure those are cgroups v2-compatible.
Hello Debraj.
On Thu, Jul 08, 2021 at 05:10:44PM +0530, Debraj Manna wrote:
Linux vrni-platform 4.15.0-143-generic #147-Ubuntu SMP Wed Apr 14 16:10:11 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux [...] GRUB_CMDLINE_LINUX="audit=1 rootdelay=180 nousb net.ifnames=0 biosdevname=0 fsck.mode=force fsck.repair=yes ipv6.disable=1 systemd.unified_cgroup_hierarchy=1"
Even after making these changes MemorySwapMax not taking into effect.
You need to add also swapaccount=1, swap accounting is enabled by default only since kernel v5.8.