Linux DAX (Acesso Direto) Detalhes

2

Eu estava procurando o DAX (Direct Access) e vi que ele é apresentado como uma substituição do XIP (Execute In Place); no entanto, tenho dúvidas se de fato faz com que os aplicativos sejam executados sem serem copiados para a RAM. Ele diz que é "Direct Access for files", mas um executável também é um arquivo para o kernel, não é? Então, o kernel executa arquivos sem copiá-los para a RAM? Se sim, como funciona? Mantém a região .text no lugar, mas cria uma cópia da região .data?

Eu tenho uma configuração experimental: eu configurei meu kernel Linux 4.6.2, com suporte a DAX. Criado um dispositivo de bloco com suporte de ram. Montou um ramdisk com a opção dax:

# mount -t ramfs -o dax,size=8m ext2 /ramdisk
# mount
rootfs on / type rootfs (rw,size=59124k,nr_inodes=14781)
proc on /proc type proc (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
ext2 on /ramdisk type ramfs (rw,relatime,dax,size=8m)
#

Agora, eu tenho o ramfs montado em / ramdisk, formatado com ext2 e tem suporte a dax. Se eu agora copiar um aplicativo para / ramdisk e executar; Como posso ter certeza de que não é copiado para qualquer outro lugar na RAM e executado a partir daí?

Infelizmente, o dax tem tão pouca documentação. A explicação do kernel diz que:

For block devices that are memory-like, the page cache pages would be unnecessary copies of the original storage. The DAX code removes the extra copy by performing reads and writes directly to the storage device. For file mappings, the storage device is mapped directly into userspace.

Isto parece que me dará a execução sem copiar o executável para um segundo lugar na RAM. No entanto, também é dito que:

Even if the kernel or its modules are stored on a filesystem that supports DAX on a block device that supports DAX, they will still be copied into RAM.

Em resumo, estou confuso com o recurso DAX e curioso se ele pode me fornecer uma maneira de executar aplicativos, sem copiá-los para outro lugar na RAM (Copiando para cache está fora do tópico para mim). Eu ficaria feliz em ouvir explicações de como isso funciona.

    
por baof 07.03.2017 / 17:48

2 respostas

1

Antes de discutir o seu exemplo, um pequeno aviso: esta é uma versão simplificada da realidade. Há muitos casos e exceções que eu não explico, mas deve ser suficiente para você entender o que está acontecendo. ..

Dispositivos de bloco

O que está confundindo você é o uso indiscriminado do termo "dispositivo de bloqueio". Dispositivos de bloco são tipicamente HDDs, CDs, SSDs, ... Como o próprio nome diz, você não pode ler / escrever um byte individual para estes dispositivos, você precisa escrevê-los em blocos (tipicamente 512 bytes de tamanho).

Os dispositivos de bloco têm alguns registradores e pequenas regiões de memória mapeadas para o espaço de endereço do processador que pode ser usado para ler o status do dispositivo, enviar comandos etc. No entanto, eles (geralmente) não fornecem um meio de acessar os dados que eles contêm diretamente. Isso normalmente é feito enviando comandos para o dispositivo e aguardando uma interrupção de hardware sinalizando que uma operação de DMA (para leitura ou gravação) foi concluída.

Então você vê, com esses tipos de dispositivos é um pouco difícil (se não impossível) não usar a memória principal (DRAM), uma vez que sua operação envolve operações de DMA e similares. O que o DAX faz nesses casos é remover algumas das despesas envolvidas no acesso aos dados, mas não muito mais que isso.

formato de DIMM * NVMs

No entanto, recentemente algumas memórias não-voláteis (NVMs) no formato DIMM foram introduzidas no mercado. Esses dispositivos mapeiam todo o seu conteúdo para o espaço de endereço do processador e, portanto, podem ser acessados diretamente pelo processador por meio de instruções de armazenamento e carregamento. O kernel nem precisa saber que esses dispositivos estão sendo acessados: por todos os motivos, é como se o processo estivesse acessando uma página de memória com suporte a DRAM regular.

* O formato DIMM foi apenas um exemplo. Existem também outras interfaces existentes, como PCI, que fazem exatamente isso ...

A parte confusa

Aí vem a confusão ... Até recentemente, "dispositivo de armazenamento" era praticamente sinônimo de "dispositivo de bloqueio". O kernel do Linux reconhece essas novas NVMs como dispositivos de armazenamento / dispositivos de bloco e as trata de acordo criando uma entrada em / dev da mesma maneira que faria com um SSD, por exemplo. (Se você não tiver um desses dispositivos com suporte a NVM, poderá simular isso especificando que um determinado intervalo de memória de sua DRAM regular deve ser tratado como NVM. Veja aqui para mais informações sobre como fazer isso.

Se você criar um sistema de arquivos em um dispositivo como esse, ele funcionará como se estivesse usando um disco rígido comum. Ele tentará melhorar o desempenho armazenando o conteúdo em cache na DRAM. O que os sistemas de arquivos habilitados para DAX fazem é evitar a criação de caches, que deveriam acelerar o acesso, mas que, nesses casos, provavelmente piorariam o desempenho.

Even if the kernel or its modules are stored on a file system that supports DAX on a block device that supports DAX, they will still be copied into RAM.

Não consegui encontrar uma razão sólida para esse comportamento, mas acho que isso é feito por razões de segurança e desempenho para garantir que o kernel e os módulos do kernel não sejam executados de forma lenta (mais lenta que a DRAM ) e que seu conteúdo não seria mexido durante a execução do kernel.

Não deve haver, no entanto, qualquer tipo de problema para executar o seu executável diretamente a partir da NVM usando apenas memória com suporte a NVM, desde que permaneça no espaço do usuário.

Dê uma olhada nos projetos Pmem.io da Intel e Atlas da HP. São interfaces de programação criadas especificamente para esse tipo de coisa.

Agora, sobre o seu exemplo:

# mount -t ramfs -o dax,size=8m ext2 /ramdisk
# mount
rootfs on / type rootfs (rw,size=59124k,nr_inodes=14781)
proc on /proc type proc (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
ext2 on /ramdisk type ramfs (rw,relatime,dax,size=8m)
#

Você não está criando um sistema de arquivos RAM-Backed EXT2. Você está criando um sistema de arquivos com RAM usando ramfs com um nome fictício ext2. Não faria diferença se você montasse assim:

# mount -t ramfs -o dax,size=8m winter_is_coming /ramdisk
    
por 25.05.2017 / 12:57
1

Does it keep the .text region in place, but create a copy of .data region?

Em qualquer caso, exec() funciona da mesma forma que mmap() com MAP_PRIVATE . As páginas são mapeadas no espaço de endereço virtual dos processos como somente leitura. Portanto, as gravações causam uma interrupção de falha de página. A maneira como essas falhas de página são tratadas é descrita como Copiar na gravação .

No caso do DAX, as páginas virtuais começam como mapeadas para páginas físicas no dispositivo. Mas gravar falhas de página no MAP_PRIVATE copiará os dados da página para uma nova página na RAM. (Em seguida, o mapeamento dos processos é atualizado de acordo e a instrução de programa interrompida é reiniciada).

Observe que o DAX é uma generalização do XIP para permitir gravações e leituras, ou seja, MAP_SHARED e MAP_PRIVATE. MAP_SHARED pode ser usado para arquivos de banco de dados, por exemplo.

Na verdade, .text também pode ser gravado no caso de bibliotecas compartilhadas. bibliotecas que não são executáveis independentes de posição e contêm referências a si mesmos, precisam que essas referências sejam atualizadas de acordo com o endereço no qual a biblioteca relevante foi carregada. Esse processo é chamado de "realocação". As bibliotecas também fazem referência a outras bibliotecas, e. libc; atualizar essas referências é chamado de "resolução de símbolo".

Even if the kernel or its modules are stored on a filesystem that supports DAX on a block device that supports DAX, they will still be copied into RAM.

Os módulos do kernel são especiais. Eles também exigem resolução de símbolo. Mas o kernel não usa COW. (De maneira mais geral, ele não usa paginação por demanda para seus segmentos de código e dados). Falhas de página dentro do kernel são fatais, porque manipulá-las pode causar recursão infinita! Portanto, antes do DAX, ficou claro que os módulos do kernel precisavam ser copiados para a RAM em sua totalidade. O código do kernel e os segmentos de dados são pequenos; quando o DAX foi implementado, não haveria nenhum benefício em usar isso em servidores com armazenamento endereçável por byte.

O kernel em si é historicamente comprimido, obviamente é descompactado na RAM.

Dito isto, o XIP é suportado para os kernels não comprimidos . Isto seria geralmente utilizado num sistema "incorporado", isto é, hardware bastante limitado. Nesse ponto, provavelmente não é um problema fazer com que a maioria dos códigos necessários seja incorporada, em vez de usar módulos carregáveis.

    
por 25.05.2017 / 14:09