Fedora 29 (kernel 3.15.10-201.fc20.x86_64) This worked in F19.

I'm trying to use cgroups to limit memory usage for some apps that are prone to misbehaviour, and I'm encountering problems. I'm testing with a small single-purpose program.

I have this in my /etc/cgconfig.conf file:

group memtest {
    memory {
        memory.limit_in_bytes = "209715200";
        memory.soft_limit_in_bytes = "104857600";

and this in /etc/cgrules.conf:

*:memtest   memory      memtest/

The memtest.c file simply malloc's 1GiB, sleeps for 30 seconds, and then frees the buffer and exits.

When the memtest program is running, its PID is properly listed in /sys/fs/cgroup/memory/memtest/tasks, showing that it's being classified correctly. However, its memory use is not being limited.

Using ulimit the behaviour is as expected:

$ (ulimit -S -v 200000 ; ./memtest )
malloc failed: Cannot allocate memory

Here's the source of memtest.c:

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

main() {
    char    *buf;
    size_t  bytes = (1 * 1<<30);

    errno = 0;
    buf = malloc(bytes);
    if (errno != 0) {
        int errno_copy = errno;
        perror("malloc failed");
        return errno_copy;
    printf("%d bytes allocated (requested %d)\n",
    return 0;

Why is the task getting properly classified, but not limited in its memory use? What changed between F19 and F20? (I only upgraded to F20 last week.)


migrated from stackoverflow.com Sep 20 '14 at 4:38

This question came from our site for professional and enthusiast programmers.


At first glance the only thing I can think of is that somewhere along the line processing (by the system) of the cgconfig.conf became more stringent. Rather than defining the limits as a quoted string, what happens if you remove the quotes. So something like:

group memtest {
    memory {
        memory.limit_in_bytes = 209715200;
        memory.soft_limit_in_bytes = 104857600;

After contemplation I think memory.limit_in_bytes only limits the physical user memory but does allow for swap to be used. Is it possible all you need to do is set memory.memsw.limit_in_bytes to be the same value as memory.limit_in_bytes so something like:

group memtest {
    memory {
        memory.limit_in_bytes = 209715200;
        memory.memsw.limit_in_bytes = 209715200;
        memory.soft_limit_in_bytes = 104857600;

memory.memsw.limit_in_bytes includes user memory AND swap. So if you want 0 swap space then one must set memory.memsw.limit_in_bytes equal to memory.limit_in_bytes

When you do ulimit -S -v 200000 that restricts virtual memory (swap, shared data, AND physical ram) to a specific amount so your application won't have enough space. However the normal system settings you had didn't limit swap space so it probably had ample room to use the maximum user memory + plus unused swap space.

Had you turned swap off (and not used ulimit) prior to doing your tests I would expect your program would have failed to allocate the memory it requested.

  • I don't think that's it; the controller's fields have the correct values: cat /sys/fs/cgroup/memory/memtest/memory.{soft_,}limit_in_bytes => 104857600 and 209715200. (Confounded no-codeblock in comments.. Or preview..) – RoUS Sep 17 '14 at 20:05
  • I have made an edit regarding memory.memsw.limit_in_bytes to also ensure no swap space can be used beyond the user memory limit by making both the same. – Michael Petch Sep 17 '14 at 20:32
  • I tried adding the memsw value a while ago, but it didn't make any difference. Changing the malloc() to calloc() did, though -- then the limit came into play. However, it went straight to the oom_killer rather than blowing out on the soft limit with (12) Cannot allocate memory as it does with the ulimit approach. – RoUS Sep 17 '14 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.