Fedora 20 memory.limit_in_bytes não funciona

1

Fedora 29 (kernel 3.15.10-201.fc20.x86_64) Isso funcionou no F19.

Estou tentando usar o cgroups para limitar o uso de memória para alguns aplicativos que são propensos ao mau comportamento e estou encontrando problemas. Estou testando com um pequeno programa de propósito único.

Eu tenho isso no meu arquivo /etc/cgconfig.conf :

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

e isso em /etc/cgrules.conf :

*:memtest   memory      memtest/

O arquivo memtest.c simplesmente% 1 domalloc é 1GiB, dorme por 30 segundos e depois libera o buffer e sai.

Quando o programa memtest está em execução, seu PID está listado corretamente em /sys/fs/cgroup/memory/memtest/tasks , mostrando que está sendo classificado corretamente. No entanto, seu uso de memória não é limitado .

Usando ulimit , o comportamento é o esperado:

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

Aqui está a fonte de 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",
           malloc_usable_size(buf),
           bytes);
    sleep(30);
    printf("Freeing..\n");
    free(buf);
    return 0;
}

Por que a tarefa está sendo classificada corretamente, mas não limitada em seu uso de memória? O que mudou entre F19 e F20? (Eu só atualizei para o F20 na semana passada.)

Obrigado!

    
por RoUS 17.09.2014 / 21:52

1 resposta

0

À primeira vista, a única coisa em que consigo pensar é que em algum lugar ao longo do processamento da linha (pelo sistema) do cgconfig.conf se tornou mais rigoroso. Em vez de definir os limites como uma string entre aspas, o que acontece se você remover as aspas. Então, algo como:

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

Depois da contemplação, acho que memory.limit_in_bytes limita apenas a memória física do usuário, mas permite que a troca seja usada. É possível que tudo que você precisa fazer seja definir memory.memsw.limit_in_bytes como o mesmo valor que memory.limit_in_bytes , então algo como:

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 inclui memória do usuário E swap. Então, se você quiser um espaço de swap, deve-se definir memory.memsw.limit_in_bytes igual a memory.limit_in_bytes

Quando você executa ulimit -S -v 200000 que restringe a memória virtual (troca, dados compartilhados e RAM físico) a um valor específico, para que o aplicativo não tenha espaço suficiente. No entanto, as configurações normais do sistema que você tinha não limitavam o espaço de troca, de modo que ele provavelmente tinha bastante espaço para usar a memória máxima do usuário + mais espaço de troca não utilizado.

Se você tivesse desativado o swap (e não usado ulimit) antes de fazer seus testes, eu esperaria que seu programa não tivesse alocado a memória solicitada.

    
por 17.09.2014 / 22:02