limite de memória do kernel do Linux

12

Eu tenho um problema desconcertante. Eu tenho uma biblioteca que usa sg para executar CDBs personalizados. Existem alguns sistemas que rotineiramente têm problemas com a alocação de memória em sg . Normalmente, o driver sg tem um limite rígido de cerca de 4mb, mas estamos vendo isso nesses poucos sistemas com pedidos de ~ 2,3mb. Ou seja, os CDBs estão se preparando para alocar para uma transferência de 2,3 MB. Não deve haver qualquer problema aqui: 2.3 < 4.0.

Agora, o perfil da máquina. É uma CPU de 64 bits, mas roda o CentOS 6.0 de 32 bits (não os construí nem tenho nada a ver com essa decisão). A versão do kernel para esta distro do CentOS é 2.6.32. Eles têm 16GB de RAM.

Aqui está o que o uso de memória parece no sistema (embora, porque este erro ocorre durante o teste automatizado, eu ainda não verifiquei se isso reflete o estado quando este errno é retornado de sg ) .

top - 00:54:46 up 5 days, 22:05,  1 user,  load average: 0.00, 0.01, 0.21
Tasks: 297 total,   1 running, 296 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  15888480k total,  9460408k used,  6428072k free,   258280k buffers
Swap:  4194296k total,        0k used,  4194296k free,  8497424k cached

Eu encontrei este artigo do Linux Journal que é sobre a alocação de memória no kernel. O artigo é datado, mas parece pertencer a 2.6 (alguns comentários sobre o autor na cabeça). O artigo menciona que o kernel é limitado a cerca de 1gb de memória (embora não seja totalmente claro a partir do texto se esse 1gb para cada físico e virtual ou total). Eu estou querendo saber se esta é uma declaração precisa para 2.6.32. Por fim, estou me perguntando se esses sistemas estão atingindo esse limite.

Embora isso não seja realmente uma resposta para o meu problema, eu estou querendo saber sobre a veracidade da afirmação para 2.6.32. Então, qual é o limite real de memória para o kernel? Isso pode precisar ser considerado para a solução de problemas. Quaisquer outras sugestões são bem vindas. O que torna isso tão desconcertante é que esses sistemas são idênticos a muitos outros que não mostram esse mesmo problema.

    
por Andrew Falanga 04.11.2014 / 18:43

2 respostas

20

O limite de 1 GiB para a memória kernel do Linux em um sistema de 32 bits é uma conseqüência do endereçamento de 32 bits, e é um limite bastante rígido. Não é impossível mudar, mas está lá por uma boa razão; mudá-lo tem consequências.

Vamos pegar a máquina do caminho de volta ao início dos anos 90, quando o Linux estava sendo criado. Naquela época, nós tínhamos argumentos sobre se o Linux poderia ser executado em 2 MiB de RAM ou se realmente precisava de 4 MiB inteiro . É claro que os esnobes high-end estavam todos zombando de nós, com seus 16 servidores monstros MiB.

O que essa divertida pequena vinheta tem a ver com alguma coisa? Nesse mundo, é fácil tomar decisões sobre como dividir o espaço de endereço de 4 GiB obtido a partir de um simples endereçamento de 32 bits. Alguns sistemas operacionais o dividem ao meio, tratando o bit superior do endereço como o "sinalizador de kernel": os endereços 0 a 2 31 -1 tiveram o bit superior limpo, e foram para o código de espaço do usuário e os endereços 2 31 até 2 32 -1 tiveram o bit superior definido e foram para o kernel. Você poderia apenas olhar para o endereço e informar: 0x80000000 e acima, é o espaço do kernel, caso contrário, é espaço do usuário.

À medida que os tamanhos de memória do PC aumentaram em direção ao limite de memória de 4 GiB, essa divisão simples de 2/2 começou a se tornar um problema. O espaço do usuário e o espaço do kernel tinham boas declarações em muita memória RAM, mas como nosso propósito em ter um computador é geralmente rodar programas de usuário, ao invés de rodar kernels, sistemas operacionais começaram a brincar com o usuário / kernel. A divisão de 3/1 é um compromisso comum.

Quanto à sua pergunta sobre o físico vs virtual, na verdade não importa. Tecnicamente falando, é um limite de memória virtual, mas isso é apenas porque o Linux é um sistema operacional baseado em VM. A instalação de 32 GiB de RAM física não alterará nada nem ajudará a swapon a uma partição de permuta de 32 GiB. Não importa o que você faça, um kernel Linux de 32 bits nunca poderá endereçar mais de 4 GiB simultaneamente.

(Sim, eu sei sobre o PAE . Agora que os SOs de 64 bits estão finalmente assumindo, espero que possamos começar a esquecer esse corte desagradável.Eu não acredito que possa ajudá-lo neste caso de qualquer maneira.)

A conclusão é que, se você estiver executando o limite da VM do kernel de 1 GiB, poderá recompilar o kernel com uma divisão 2/2, mas isso impactará diretamente os programas de espaço do usuário.

64 bits é realmente a resposta certa.

    
por 04.11.2014 / 19:33
2

Eu quero adicionar um pouco à excelente resposta de Warren Young , porque as coisas são realmente piores do que ele escreve.

O espaço de endereço de 1 GB do kernel é dividido em duas partes. 128 MB são para vmalloc e 896 MB para lowmem . Não importa o que isso realmente significa. Ao alocar memória, o código do kernel deve escolher qual deles deseja. Você não pode simplesmente obter memória de qualquer pool que tenha espaço livre.

Se você escolher vmalloc , estará limitado a 128 MB. Agora 1GB não parece tão ruim ...

Se você escolher lowmem , estará limitado a 896MB. Não tão longe de 1GB, mas neste caso, todas as alocações são arredondadas para a próxima potência de 2. Assim, uma alocação de 2,3MB realmente consome 4MB. Além disso, você não pode alocar mais de 4 MB em uma chamada ao usar lowmem .

64 bits é realmente a resposta certa.

    
por 05.11.2014 / 13:52