limite de memória do kernel 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 4 MB, mas o vemos nesses poucos sistemas com solicitações de ~ 2,3 MB. Ou seja, os CDBs estão se preparando para alocar uma transferência de 2,3mb. Não deve haver nenhum problema aqui: 2.3 <4.0.

Agora, o perfil da máquina. É uma CPU de 64 bits, mas executa 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 distribuição do CentOS é 2.6.32. Eles têm 16GB de RAM.

Aqui está a aparência do uso de memória no sistema (no entanto, como esse erro ocorre durante o teste automatizado, ainda não verifiquei se isso reflete o estado em que esse erro é retornado pelo 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

Encontrei este artigo do Linux Journal, que trata da 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 1 GB de memória (embora não esteja totalmente claro no texto se esses 1 GB são físicos e virtuais ou totais). Gostaria de 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, estou me perguntando sobre a veracidade da reivindicação da 2.6.32. Então, qual é o limite real de memória para o kernel? Pode ser necessário considerar 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 o mesmo problema.

Andrew Falanga
fonte

Respostas:

21

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

Vamos levar a máquina de recuperação até o início dos anos 90, quando o Linux estava sendo criado. Naquela época, discutíamos se o Linux poderia ser executado em 2 MiB de RAM ou se realmente precisava de 4 MiB inteiros . Obviamente, os snobs de ponta estavam 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 que você obtém do endereçamento simples de 32 bits. Alguns sistemas operacionais apenas dividiram ao meio, tratando o bit superior do endereço como o "sinalizador do kernel": os endereços 0 a 2 31 -1 tiveram o bit superior limpo e destinavam-se ao código de espaço do usuário e os endereços 2 31 a 2 32 - Eu tinha o bit superior definido e era para o kernel. Você pode simplesmente olhar o endereço e dizer: 0x80000000 e acima, é espaço no kernel, caso contrário, é espaço no usuário.

À medida que os tamanhos de memória do PC aumentavam para o limite 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 reivindicações em muita RAM, mas como nosso objetivo em ter um computador geralmente é executar programas do usuário, em vez de executar kernels, os sistemas operacionais começaram a brincar com a divisão usuário / kernel. A divisão de 3/1 é um compromisso comum.

Quanto à sua pergunta sobre físico versus virtual, isso realmente não importa. Tecnicamente falando, é um limite de memória virtual, mas isso ocorre apenas porque o Linux é um sistema operacional baseado em VM. Instalar 32 GiB de RAM física não mudará nada, nem ajudará em swaponuma partição de troca de 32 GiB. Não importa o que você faça, um kernel Linux de 32 bits nunca poderá abordar mais de 4 GiB simultaneamente.

(Sim, eu sei sobre o PAE . Agora que os sistemas operacionais de 64 bits estão finalmente assumindo o controle, espero que possamos começar a esquecer esse truque desagradável. Não acredito que possa ajudá-lo nesse caso.)

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

64 bits é realmente a resposta certa.

Warren Young
fonte
1
Obrigado. Este artigo é ótimo. Eu encontrei a divisão 2/2 comumente usada no Windows. Naquela época, eu aprendi que o Linux usava uma divisão de 3/1. Eu gostaria de ter pensado nisso ao ler o artigo, acho que teria ligado os pontos. Então ... parece que vou ter que manter isso em mente. Provavelmente não está muito longe de pensar que esses sistemas estão atingindo os limites, considerando a natureza dos testes. A grande questão é: por que os outros sistemas também não estão enfrentando isso? Obrigado novamente.
Andrew Falanga
1
@AndrewFalanga: Na verdade, o Windows moderno também usa uma divisão difusa de 3/1 .
22815 Warren Young
1
Alguns de nós foram capazes de combinar a memória de três máquinas diferentes herdadas do SSC para obter um servidor de 12 MB. Então, muito memória que poderia fazer qualquer coisa que queríamos ...
dmckee --- gatinho ex-moderador
3
"Sim, eu sei sobre o modelo de memória segmentada x86 . Agora que os sistemas operacionais de 32 bits estão finalmente assumindo o controle, espero que possamos começar a esquecer esse truque desagradável".
um CVn
Há duas vezes mais dobras entre 32 e 64 bits do que entre 16 e 32, o que dobra a quantidade de tempo que temos para adiar esses hacks, sendo o resto igual. Mas tudo o mais não é igual, com o pôr do sol da Lei de Moore. Obtivemos duas décadas da computação x86 de 32 bits. Podemos tirar séculos de 64 bits. Uma leitura de passagem única de 2⁶⁴ bytes de RAM nas larguras de banda DRAM atuais levaria cerca de 30 anos . De onde virá o aumento da largura de banda para nos aproximarmos do limite de 64 bits?
9114 Warren Young
2

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

O espaço de endereço do kernel de 1 GB é dividido em duas partes. 128 MB são para vmalloce 896 MB para lowmem. Não importa o que 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 piscina que tenha espaço livre.

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

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

64 bits é realmente a resposta certa.

Ugoren
fonte
Eu tenho uma pergunta relacionada à sua resposta. Para esse espaço de memória chamado lowmem , é daí que vem a memória de chamadas como kmalloc e kzmalloc?
Andrew Falanga
@AndrewFalanga, sim, essas funções usam lowmem.
ugoren