Com base em minha pesquisa sobre mmap(), entendo que mmap usa paginação por demanda para copiar dados para o cache de páginas do kernel somente quando o endereço da memória virtual é tocado, por meio de falha de página.
Se estivermos lendo arquivos maiores que o cache da página, alguma página obsoleta no cache da página terá que ser trocada e recuperada. Portanto, minha pergunta é: a tabela de páginas será atualizada para mapear o endereço de memória virtual correspondente ao endereço da página antiga e obsoleta no cache (agora contendo novos dados)? Como isso acontece? Isso faz parte da chamada do sistema mmap()?
Quando
mmap()
é chamado, cria um mapeamento no espaço de endereço virtual do processo para o arquivo especificado. Esse mapeamento apenas configura a capacidade dessas páginas serem carregadas quando são realmente acessadas, mas ainda não carrega nada na memória. Quando você acessa as páginas, uma falha de página é gerada, as entradas da tabela de páginas são atualizadas para mapear os endereços virtuais para os endereços físicos das páginas recém-carregadas e você pode então acessar o arquivo. Isso acontece emfilemap_fault
.É assim também que funciona se você acessar uma página mapeada que foi removida: o kernel trata a falha da página, coloca o conteúdo do arquivo de volta nas páginas e, da perspectiva do aplicativo, nada acontece.
Não há nada de especial
mmap()
aqui em si - é assim que a paginação por demanda funciona dentro do kernel do Linux em geral, usada para quase tudo - até mesmo memória regular de programa e entradas de cache de arquivo.Observe que, ao ler with
mmap()
, o kernel normalmente usará readahead para carregar mais conteúdo do que apenas a única página na qual você gerou uma falha de página, a menos que haja uma indicação de que isso seria inútil, comoMADV_RANDOM
ouMADV_DONTNEED
(indicado por usuário) ouMMAP_LOTSAMISS
(heurística do kernel).