Desvantagens do módulo do kernel do Linux?

6

Estou tentando entender as desvantagens de usar módulos de kernel do Linux. Eu entendo os benefícios de usá-los: a capacidade de inserir código dinamicamente em um sistema em execução sem ter que recompilar e reinicializar o sistema básico. Dada essa strong vantagem, eu estava supondo que a maioria do código do kernel deveria estar nos módulos do kernel como parte do kernel base, mas esse não parece ser o caso - um bom número de subsistemas centrais (como gerenciamento de memória) ainda o kernel base.

Um dos motivos pelos quais posso pensar é que os módulos do kernel são carregados muito tarde no processo de inicialização e, portanto, a funcionalidade principal precisa estar no kernel base. Outra razão que li foi sobre fragmentação.

Eu realmente não entendi porque os módulos do kernel causam fragmentação de memória, alguém pode explicar por favor? Existem outras desvantagens de usar módulos do kernel?

    
por spa 20.02.2013 / 15:51

5 respostas

4

Sim, a razão pela qual componentes essenciais (como mm) não podem ser módulos carregáveis é porque eles são essenciais - o kernel não funcionará sem eles.

Não consigo encontrar referências que afirmem que os efeitos da fragmentação de memória em relação aos módulos carregáveis sejam significativos, mas esta parte do LLKM pode ser uma leitura interessante para você.

Eu acho que a questão é realmente parte integrante da questão da fragmentação da memória em geral, que acontece em dois níveis: a fragmentação da memória real, que o subsistema mm kernel gerencia, e a fragmentação do espaço de endereço virtual que pode ocorrer com aplicativos muito grandes (que eu presumo que seja em grande parte o resultado de como eles são projetados e compilados).

No que diz respeito à fragmentação da memória real, não creio que isso seja possível em uma granularidade mais fina do que a do tamanho da página (4 KB). Portanto, se você estivesse lendo 1 MB de espaço virtualmente contíguo, que na verdade é 100% fragmentado em 1024 páginas, pode ser 1000 operações menores extras envolvidas. Nessa parte do how-to, lemos:

The base kernel contains within its prized contiguous domain a large expanse of reusable memory -- the kmalloc pool. In some versions of Linux, the module loader tries first to get contiguous memory from that pool into which to load an LKM and only if a large enough space was not available, go to the vmalloc space. Andi Kleen submitted code to do that in Linux 2.5 in October 2002. He claims the difference is in the several per cent range.

Aqui, o espaço vmalloc, que é onde os aplicativos do espaço do usuário residem, seria aquele que é potencialmente propenso a se fragmentar em páginas. Esta é simplesmente a realidade dos sistemas operacionais contemporâneos (todos eles gerenciam memória via endereçamento virtual). Podemos inferir a partir disso que o endereçamento virtual poderia representar uma penalidade de desempenho de "vários por cento" no mundo do usuário também, mas na medida em que o endereçamento virtual é necessário e inescapável no mundo do usuário, é apenas em relação a algo completamente teórico.

Existe a possibilidade de fragmentação adicional da fragmentação do espaço de endereço virtual de um processo (em oposição à memória real por trás dele), mas isso nunca se aplicaria aos módulos do kernel (enquanto o último parágrafo aparentemente poderia). p>

Se você quer minha opinião, não vale muito a contemplação. Tenha em mente que mesmo com um kernel altamente modular, os componentes mais usados (fs, networking, etc) tenderão a ser carregados muito cedo e permanecerão carregados, portanto eles certamente estarão em uma região contígua de memória real, pelo que é vale a pena (o que pode ser uma razão para não carregar e descarregar módulos sem sentido ).

    
por 20.02.2013 / 16:35
5

Com um kernel monolítico, em teoria, um único bloco contíguo de memória pode ser alocado para o kernel. Se os módulos são carregados (e descarregados) sob demanda, então é improvável que toda a memória do kernel seja contígua e, portanto, por definição, ela será fragmentada. A desvantagem é que um kernel modular geralmente usa muito menos memória do que um kernel monolítico. Isto é certamente verdade com um kernel distrol monolítico padrão, que provavelmente tem muitos drivers não utilizados, embora menos verdade se você construir seu próprio kernel monolítico.

Alguns subsistemas simplesmente não se prestam a ser modulares, o gerenciamento de memória é claramente um, o SMP outro. O agendamento de processos não é modular, mas a estratégia de agendamento de E / S é. Outros subsistemas não são modulares devido a complexas interdependências, como o TCP / IP.

Outro problema com os módulos é que eles não são tão bons se eles direcionarem o dispositivo que você precisa para inicializar, soluções como initrd resolvem isso.

Uma consideração final é a segurança, permitindo que os módulos carregáveis sejam um risco potencial, por ex. rootkit kernel carregável como knark . Veja link e link . Você pode reduzir esse risco impondo módulos assinados (desde o kernel 3.7), carregando um módulo lockdown por último, ou outro endurecimento.

    
por 20.02.2013 / 16:36
3

Eu não sei quais outras desvantagens podem existir na compilação de código como um módulo carregável do kernel em vez de diretamente na imagem do kernel, mas para usar seu exemplo particular, suponha que o gerenciamento de memória foi construído como um módulo do kernel em vez de embutido na própria imagem binária do kernel.

  • Como o kernel alocaria a memória para um disco RAM inicial?
  • Como o kernel alocaria a memória para as estruturas necessárias para montar um sistema de arquivos?
  • Como o kernel alocaria a memória na qual carregar o módulo de gerenciamento de memória?
  • Como o módulo de gerenciamento de memória saberia qual memória já foi reivindicada por outras partes do kernel (possivelmente outros módulos carregáveis do kernel que foram necessários para acessar o módulo de gerenciamento de memória)?

Como você pode ver, isso imediatamente abre toda uma lata de worms em potencial. O agendamento de tarefas é outro conceito similar de núcleo.

De outra perspectiva, que trabalho útil o kernel poderia fazer sem o módulo de gerenciamento de memória? Não é como um driver de hardware que pode simplesmente ser desativado se o hardware não estiver instalado no sistema; é um recurso básico que o próprio kernel precisa para se autoinicializar.

Embora os microkernels verdadeiros tenham certos benefícios de uma separação entre o ponto de vista de preocupação e legibilidade do código / compreensibilidade, até eles precisam certas coisas dentro do próprio kernel para funcionar. A memória eo manuseio de tarefas estão entre os conceitos centrais de um kernel de sistema operacional multitarefa - e, conforme ilustrado na lista acima, são para todos os intentos e propósitos requeridos para que qualquer coisa funcione. Tentar separá-lo em um componente carregado separadamente iria, se nada mais, adicionar uma grande quantidade de complexidade para absolutamente nenhum ganho (já que todo mundo estaria carregando esse módulo de qualquer maneira).

    
por 20.02.2013 / 16:16
0

Acho que o efeito colateral mais importante dos LKM-s é a velocidade.

Quando você usa LKMs, pode atrasar o carregamento deles, resultando em uma exibição anterior do prompt de login. (em série, por ex.)

Mas isso também é uma desvantagem. Se você armazenar seus módulos em um sistema de arquivos não disponível durante a inicialização, é impossível carregá-los antes de montar esse sistema de arquivos, resultando em uma disponibilidade posterior e inicialização do dispositivo.

Caso contrário, como mr.spuratic apontou, você não deve compilar seus drivers do HDD e do sistema de arquivos como módulos, ou talvez seja impossível acessar os módulos (se você os armazenar no HDD no meu exemplo).

Uma vantagem relacionada ao uso de LKMs é que o blob do kernel compilado não será tão grande: você deve ter uma grande partição de inicialização disponível antes do início do kernel.

    
por 16.11.2018 / 19:49
0

O código do módulo do kernel Linux é alocado usando vmalloc() . vmalloc() não tem problema com fragmentação, porque é memória virtual. A memória é dividida em páginas, geralmente 4Kb, e a memória virtual permite remapear páginas físicas fragmentadas como um bloco virtual contíguo.

In the other corner is vmalloc(), which allocates virtually contiguous (but physically dispersed) pages in a separate virtual address space. vmalloc() is relatively slow, but it can perform large allocations that look contiguous to the kernel. It is thus used, for example, to allocate space for code from loadable modules.

https://lwn.net/Articles/57800/

    
por 16.11.2018 / 20:40