GERENCIAMENTO DE MEMÓRIA NO LINUX

June 24, 2017 | Autor: Teste Test | Categoría: Linux Kernel
Share Embed


Descripción

GERENCIAMENTO DE MEMÓRIA NO LINUX


1.INTRODUÇÃO
2.MEMÓRIA FÍSICA
3.MEMÓRIA VIRTUAL
3.1.REGIÕES DA MEMÓRIA VIRTUAL
3.2.TEMPO DE VIDA DO ESPAÇO DE ENDEREÇAMENTO VIRTUAL
3.3.TROCA DE PROCESSOS E PAGINAÇÃO
3.3.1.PAGINAÇÃO
3.3.2.MEMÓRIA
3.3.2.1.DIRETÓRIO DE PÁGINA
3.3.2.2.DIRETÓRIO INTERMEDIÁRIO DE PÁGINA
3.3.2.3.TABELA DE PÁGINA
3.3.3.SWAPPING
3.3.3.1.TIPOS E ESTRUTURA DE SWAPPING
3.4. MEMÓRIA VIRTUAL DO NÚCLEO

1.INTRODUÇÃO

O Linux é um sistema multiprocessos e multiusuários. Então devemos ter um
controle rígido sobre a memória para que um processo não sobreponha os
recursos (memória) utilizados pelo outro.
Ele possui dois sistemas de gerenciamento de memória. O primeiro é o
sistema de gerenciamento de memória física. Ele cuida da alocação e
liberação de blocos de memória. O segundo é o sistema de gerenciamento de
memória virtual. Este tem o papel de "enganar" os processos dizendo que há
memória suficiente quando não há. Esta técnica pode melhorar a performance
do sistema operacional.
A seguir veremos algumas estratégias usadas pelos dois componentes para
aumentar a performance do processamento.

2.MEMÓRIA FÍSICA

O administrador de memória física principal no Linux é o alocador de
páginas. Esse processo é responsável por alocar e liberar páginas físicas,
sendo capaz de alocar grupos de páginas contíguas. O alocador de páginas
usa um algoritmo de alocação de regiões vizinhas, que combina unidades de
alocação adjacentes em uma única unidade. Cada região de memória que pode
ser alocada possui uma região adjacente correspondente, ou vizinha. Sempre
que duas regiões vizinhas são liberadas, elas são combinadas para formar
uma região maior. Essa região maior também tem uma vizinha, com a qual pode
ser combinada para formar uma região livre ainda maior. Como alternativa,
quando não existir uma região de memória disponível pequena para satisfazer
a uma requisição de uma pequena porção de memória, uma região maior de
memória é subdividida em duas vizinhas. O sistema utiliza listas ligadas
para áreas disponíveis de cada tamanho permitido. No Linux, o menor tamanho
de área que pode ser alocada usando esse mecanismo corresponde ao de uma
única página física.
As alocações de memória no núcleo do Linux ocorrem estaticamente, por
rotinas de controle que reservam uma área contígua de memória no momento da
carga do sistema, ou dinamicamente, pelo controlador de páginas.
Entretanto, as funções do núcleo não precisam usar o alocador de páginas
para reservar memória. Existem vários outros subsistemas de gerenciamento
de memória especializados, que usam o controlador de páginas subjacente
para gerenciar seu próprio espaço de memória. Os subsistemas de memória
mais importantes são o sistema de memória virtual, o sistema de alocação de
áreas de memória de tamanho variável, kmalloc, e o sistema de alocação de
espaço nas duas memórias cache de dados persistentes do núcleo: a memória
cache de áreas de armazenamento temporário e a memória cache de páginas.
Muitos componentes do Linux precisam alocar espaço a páginas inteiras, mas
freqüentemente pode ser necessário alocar blocos menores de memória. O
núcleo oferece um subsistema adicional para a alocação de áreas de memória
de tamanho variável, sem tamanho previamente definido, podendo ser de
apenas alguns bytes, em vez de uma página inteira. Esse serviço, fornecido
pela rotina kmalloc, análoga á rotina malloc da linguagem C, aloca blocos a
páginas inteiras, sob demanda, mas subdivide esses blocos em partes
menores. O núcleo armazena dados sobre os blocos em uso pelo sistema
kmalloc, em listas que contêm, cada uma, apenas blocos que foram
subdivididos em partes de um tamanho especifico. A alocação de memória
envolve selecionar a lista apropriada e retirar a primeira área disponível
dessa lista, ou alocar espaço a uma página e subdividi-lo.
Tanto o controlador de páginas, quanto o kmalloc, não podem ser
interrompidos. Uma rotina que deseje alocar uma área de memória informa a
prioridade da sua requisição à rotina de alocação. Rotinas de interrupção
utilizam uma prioridade atômica, que garante que a requisição seja
satisfeita ou que falhe imediatamente, caso não exista mais memória
disponível. Em contraposição, para uma requisição de memória de um processo
comum de usuário, uma área de memória livre é procurada, sendo o processo
bloqueado até que uma área de memória se torne disponível. A prioridade de
alocação também pode ser usada para especificar a requisição de memória de
acesso direto (DMA). Esse recurso é usado em algumas arquiteturas, como em
PCs, onde certas requisições de DMA não podem ser realizadas sobre qualquer
bloco da memória física.
As regiões de memória solicitadas pelo sistema kmalloc ficam alocadas até
que sejam explicitamente liberadas. O sistema kmalloc não pode transferir
essas regiões de uma posição para outra ou liberá-las em resposta a uma
diminuição do espaço livre em memória.
Os outros três subsistemas principais de memória que realizam um
gerenciamento próprio de blocos de memória física são fortemente
relacionados entre si. Esses sistemas gerenciam o uso da memória cache de
áreas de armazenamento temporário, da memória cache de páginas e da memória
virtual. A memória cache de áreas de armazenamento temporário é a principal
memória cache do núcleo para dispositivos de E/S baseada em blocos; além
disso constitui o principal mecanismo por meio do qual as operações de E/S
sobre esses dispositivos são realizadas. A memória cache de páginas
armazena páginas inteiras de dados de arquivos e não é restrita apenas aos
dispositivos que fazem E/S usando blocos. Ela também pode ser usada para
armazenar dados transmitidos por meio da rede e é utilizada tanto pelos
sistemas de arquivos originais do Linux, que usam discos, quanto pelo
sistema de arquivos de rede NES. O sistema de memória virtual gerencia o
espaço de endereçamento de cada processo.
Esses três sistemas de memória interagem entre si. A leitura de uma página
de dados para a memória cache de páginas usa a memória cache de áreas de
armazenamento temporário. As páginas da memória cache de páginas podem
também usar o sistema de memória virtual, caso um processo tenha mapeado o
arquivo correspondente no seu espaço de endereçamento. O núcleo usa um
contador de referências a cada página na memória física para que as páginas
compartilhadas por dois ou mais desses subsistemas possam ser liberadas,
quando elas não estiverem mais sendo usadas em nenhum deles.

3.MEMÓRIA VIRTUAL

O sistema de memória virtual do Linux é responsável pelo uso do espaço de
endereçamento de cada processo. Esse sistema aloca espaço de memória
virtual sob demanda e gerencia a transferência de páginas entre o disco e a
memória, quando necessário. No Linux, o administrador de memória virtual
usa duas visões do espaço de endereçamento de um processo: como um conjunto
de regiões separadas e como um conjunto de páginas.
A primeira dessas visões do espaço de endereçamento é a visão lógica, que
descreve as instruções recebidas pelo sistema de memória virtual relativas
á organização do espaço de endereçamento. Nessa visão, o espaço de
endereçamento consiste em regiões separadas, cada qual consistindo em um
espaço contíguo de páginas. Essa região é descrita, internamente, por uma
única estrutura vrn_area_struct, que define as propriedades dessa região,
incluindo os direitos de acesso do processo para realizar operações de
leitura, escrita e execução nessa região, assim como dados relativos aos
arquivos associados á região. As regiões de cada espaço de endereçamento
são organizadas em uma árvore binária balanceada, para possibilitar uma
pesquisa eficiente por uma região correspondente a um endereço virtual.
O núcleo usa uma segunda visão de cada espaço de endereçamento. Essa visão
é armazenada nas tabelas de páginas do processo. As entradas nessa tabela
de páginas determinam a posição atual de cada página da memória virtual,
esteja ela em disco ou na memória física. Essa visão do espaço físico é
gerenciada por um conjunto de rotinas, chamadas por tratadores de
interrupções de software do núcleo do sistema, sempre que um processo usa
uma página que não está presente na tabela de páginas. Cada vrn_area_struct
contém um apontador para uma tabela de rotinas que implementam as operações
fundamentais de gerenciamento de páginas. Todas as requisições de leitura
ou escrita de páginas não disponíveis são eventualmente tratadas por uma
rotina apropriada, contida na tabela vrn_area_struct, de forma que as
rotinas centrais de gerenciamento de memória não precisam lidar com
detalhes específicos de cada tipo de região de memória.

3.1 REGIÕES DA MEMÓRIA VIRTUAL

O Linux usa regiões da memória virtual de várias maneiras. Uma região pode
ser caracterizada pela memória persistente para onde as páginas dessa
região são copiadas ou de onde suas páginas são lidas. A maioria das
regiões de memória possui uma cópia reserva em um arquivo ou então não
possui cópias reservas. Uma região que não possui cópias reservas constitui
o tipo mais simples de memória virtual. Essas regiões representam memórias
de demanda zero: quando um processo tenta ler uma página dessa região, ele
simplesmente recebe uma página de memória totalmente preenchida com zeros.
Uma região com cópia em um arquivo funciona como uma visão de uma seção
desse arquivo: sempre que um processo tenta usar uma página dessa região, a
tabela de páginas e preenchida com o endereço de uma página da memória
cache do núcleo, correspondente ao endereço da página requerida do arquivo.
A mesma página de memória física é usada tanto pela memória cache de
páginas quanto pelas tabelas de páginas do processo, de modo que qualquer
alteração feita sobre o arquivo, pelo sistema de arquivos, é imediatamente
visível a qualquer processo que tenha essa página mapeada em seu espaço de
endereçamento virtual. Vários processos podem mapear, em seu espaço de
endereçamento, uma mesma região de um determinado arquivo, resultando na
utilização da mesma página de memória física por todos esses processos.
Uma região de memória virtual é também definida pela forma como são
tratadas as operações de escrita sobre essa região. O mapeamento de uma
região no espaço de endereçamento de um processo pode ser privado ou
compartilhado. Se um processo escreve em uma região privada, o controlador
de páginas detecta que é necessária uma cópia-em-escrita, para manter essas
atualizações locais ao processo. Por outro lado, uma operação de escrita
sobre uma região compartilhada resulta na atualização da cópia dessa região
mantida na memória, de modo que essa atualização seja imediatamente visível
a todos os processos que usam essa região.

3.2 TEMPO DE VIDA DO ESPAÇO DE ENDEREÇAMENTO VIRTUAL

Existem exatamente duas situações em que o núcleo do sistema cria um novo
espaço de endereçamento virtual: quando um processo executa um novo
programa, por meio de uma chamada à rotina do sistema exec, ou na criação
de um novo processo, por meio da rotina de sistema fork. O primeiro caso é
fácil: quando um novo programa vai ser executado, o processo recebe um novo
espaço de endereçamento virtual, completamente vazio. É responsabilidade
das rotinas do sistema carregar o programa, preenchendo o espaço de
endereçamento com regiões da memória virtual.
No segundo caso, a criação de um novo processo pela rotina fork envolve a
criação de uma cópia completa do espaço de endereçamento virtual do
processo existente. O núcleo do sistema copia os descritores
vrn_area_struct do processo pai e cria um novo conjunto de tabelas de
páginas para o processo filho. As tabelas de páginas do processo pai são
diretamente copiadas nas tabelas do processo filho, incrementando o
contador de referências de cada página. Portanto, após uma chamada á rotina
fork, o processo pai e o processo filho compartilham as mesmas páginas
físicas de memória em seus espaços de endereçamento.
Um caso especial ocorre quando essa operação de cópia envolve uma região
privada da memória. Qualquer página que tenha sido escrita pelo processo
pai nessa região é uma página privada, e as alterações subseqüentes dessa
página, sejam pelo processo pai, ou pelo processo filho, não devem ser
refletidas na página do espaço de endereçamento do outro processo. Quando
as entradas da tabela de páginas correspondentes a essas páginas são
copiadas, elas são reservadas apenas para leitura e marcadas como páginas
de cópia-em-escrita. Se essas páginas nunca forem modificadas por qualquer
um dos processos, ambos continuam compartilhando a mesma página de memória
física. Entretanto, se qualquer um dos processos tentar modificar uma
página marcada como página de cópia-em-escrita, o contador de referências
dessa página será verificado. Se a página ainda continuar compartilhada, o
processo copiará seu conteúdo para uma nova página de memória física e
usará essa nova cópia. Esse mecanismo assegura que páginas de dados
privados sejam compartilhadas entre processos sempre que possível: serão
feitas cópias somente quando for absolutamente necessário.

3.3 TROCA DE PROCESSOS E PAGINAÇÃO

Uma tarefa importante do sistema de memória virtual é a transferência de
páginas, da memória física para o disco, quando necessário. Os primeiros
sistemas UNIX transferiam todos os dados de um processo de uma única vez.
Sistemas UNIX mais modernos usam o mecanismo de paginação, que transfere
páginas da memória virtual individualmente entre a memória física e o
disco. O Linux usa o mecanismo de paginação, em vez de transferir todos os
dados de um processo de uma única vez.

3.3.1 Paginação

Com a ajuda de tabelas, o sistema operacional mapeia um grande espaço de
endereçamento lógico num espaço de endereçamento físico menor. Quando os
processos precisam de mais memória principal do que está fisicamente
presente, segmentos individuais de memória lógica que não foram
referenciados recentemente são realocados no Disco Rígido.
Quando um programa acessa um endereço lógico que está atualmente localizado
no Disco Rígido, o respectivo segmento de memória (chamado página) é
carregado na memória principal, enquanto outro segmento de memória precisa
ser escrito para o Disco Rígido para compensar. Devido ao tempo de acesso
do Disco Rígido ser significativamente mais alto se comparado com a memória
principal, há naturalmente um preço a ser pago em termos de velocidade de
execução.
A fim de ser capaz de usar o Disco Rígido para o gerenciamento de memória
virtual e a memória principal lógica, swap files (arquivos de troca) ou
swap partitions (partições de troca) devem ser criados no Disco Rígido. Sem
tais partições ou arquivos, a memória principal é limitada ao seu tamanho
físico disponível realmente.
O sistema de paginação pode ser dividido em duas partes. A primeira
consiste no algoritmo que define a política de substituição de páginas, que
escolhe a página que vai ser copiada da memória para o disco e determina
quando essa página deve ser copiada. A segunda consiste no mecanismo de
paginação, que realiza a transferência dos dados entre a memória e o disco,
quando necessário.
A política de substituição de páginas do Linux usa uma versão modificada do
algoritmo do relógio (ou de segunda chance). O Linux usa um relógio de
vários passos e cada página tem uma idade, ajustada a cada passo do
relógio. Mais precisamente, a idade é uma medida da juventude da página,
isto é, de quantas vezes a página foi usada recentemente. As páginas
freqüentemente usadas terão idade maior e a idade de uma página pouco usada
vai caindo gradualmente, a cada passo do relógio, até atingir o valor zero.
Essa informação sobre a idade das páginas permite que o algoritmo de
substituição selecione uma página com base na política MRU.
O mecanismo de paginação oferece suporte ao gerenciamento de páginas, tanto
para dispositivos e partições dedicados à troca de processos, como para
arquivos comuns, embora a troca de páginas de arquivos comuns seja
substancialmente mais lenta, em razão da sobrecarga extra, devida ao
sistema de arquivos. Os blocos são alocados a partir dos dispositivos de
troca, de acordo com uma tabela de blocos em uso, que é armazenada na
memória principal. O processo que faz a alocação usa um algoritmo que
escolhe a próxima área de tamanho suficiente para armazenar os dados
requeridos, tentando escrever as páginas em blocos contíguos do disco, para
obter melhor desempenho. Para registrar a informação de que uma página foi
escrita de volta no disco, esse processo usa uma técnica disponível nas
tabelas de páginas de processadores modernos: ele liga o bit de página não
presente da entrada correspondente à página na tabela de páginas,
possibilitando que o restante dessa entrada seja preenchido com o endereço
onde a página foi escrita no disco.

3.3.2 Memória

Os níveis do cache são inicializados pela BIOS e portanto, tornam-se
transparentes à programação. Por essa razão, os níveis do cache não são
mapeados pelo modelo de memória de arquitetura independente e o termo
memória física em geral é usada para se referir à RAM. A memória física é
dividida em páginas, na qual é definida no arquivo "asm/page.h" com tamanho
de 4 KB para processadores x86 e 8 KB para processadores Alpha.
A conversão do endereço da memória linear para o endereço da memória física
é feita pelo processador ou pela MMU (Memory Management Unit). Esta
conversão é feita em 3 níveis, na qual o endereço linear é dividido em 4
partes. A primeira parte é usada como um índice no diretório de página
(page directory) e sua entrada faz referência ao diretório intermediário de
página (page middle directory). A segunda parte é usada como índice do
diretório intermediário de páginas, que por sua vez, faz referência à
Tabela de Páginas (page table). A terceira parte é um índice da Tabela de
Página, que aponta (se possível) para uma página na memória física.
Finalmente, a quarta parte do endereço fornece o deslocamento dentro da
página de memória física selecionada.
Os processadores x86 suportam apenas conversões em dois níveis. Neste caso,
o tamanho do diretório de página intermediária (pmd) é definida como um e a
entrada do diretório de página (pgd) passa a ser interpretada como um
diretório de página intermediária (pmd). Entretanto, a conversão do
endereço linear deve ser dado em 3 níveis (segundo a definição do modelo de
memória de arquitetura independente). Como consequência, há um aumento da
pgd e da tabela de página.

3.3.2.1 Diretório de Página (Page Directory)

As definições de como tipos de dados, funções e macros acessam e modificam
páginas da tabela ou diretório estão nos arquivos "asm/page.h" e
"asm/pgtable.h".
As entradas do diretório de página são dados do tipo pgd_t, que é definida
como estrutura e acessado pelo método pgd_val().
Os métodos que devem ser selecionados quando o arquivo "asm/pgtable.h" é
compilado são:

pgd_alloc() "Aloca uma página para o diretório de páginas e preenche-a com
zero " "pgd_bad()
" "Pode ser usado para testar se a entrada no diretório"
" "de página é válida "


pgd_clear()
" "Apaga a entrada no diretório de páginas "


pgd_free()
" "Libera a página de memória alocada para o diretório "
" "de páginas "


pgd_inuse()
" "Confere se o diretório de páginas está sendo usado "
" "por algum processo "


pgd_none()
" "Testa se a entrada foi inicializada "


pgd_offset()
" "Retorna o ponteiro para a entrada no diretório de "
" "páginas de um endereço linear "


pgd_page()
" "O endereço da página a qual a entrada no diretório "
" "de página se refere - usualmente o endereço base de "
" "um diretório intermediário de página. Na arquitetura"
" "X86 esta função retorna o endereço base de uma "
" "tabela de páginas se THREE_LEVEL não é setada "


pgd_present()
" "Mostra se a entrada no diretório de página se refere"
" "a um diretório intermediário de páginas. Na "
" "arquitetura X86, se a macro THREE_LEVEL não estiver "
" "definida, esta função testa se o diretório de "
" "páginas se refere a uma tabela de páginas "


pgd_reuse()
" "O contador de uso do diretório de páginas é "
" "incrementado em um "


pgd_set()
" "A entrada no diretório de páginas é setada para o "
" "endereço base de um diretório intermediário de "
" "páginas. Na arquitetura X86, se a macro THREE_LEVEL "
" "não estiver definida, esta função é programada para "
" "setar o endereço base de uma tabela de páginas "


SET_PAGE_DIR()
" "Esta macro/função reseta o endereço base do "
" "diretório de páginas para uma tarefa "

3.3.2.2 Diretório Intermediário de Página (Page Middle Directory)

As entradas do diretório intermediário de página são dados do tipo pmd_t e
o acesso é feito pelo método pmd_val(). As funções abaixo são definidas:


pmd_alloc()
" "Aloca um diretório intermediário de página na área "
" "do usuário "


pmd_alloc_kernel()
" "Aloca um diretório intermediário de página para a "
" "memória no segmento do kernel. Todos os dados são "
" "setados para inválidos "


pmd_bad()
" "Testa a validade do diretório intermediária de "
" "página "


pmd_clear()
" "Deleta a entrada do diretório intermediário de "
" "página "


pmd_free()
" "Libera a entrada da diretório intermediário de "
" "página "


pmd_free_kernel()
" "Libera um diretório intermediário de página da "
" "memória do segmento de kernel "


pmd_inuse()
" "Testa se o diretório intermediário de página está "
" "sendo usado por um ou mais processos "


pmd_none()
" "Testa se o diretório intermediário de página foi "
" "setado "


pmd_offset()
" "Retorna o endereço de uma entrada no diretório "
" "intermediário de página, na qual o endereço no "
" "argumento é alocado: a entrada do diretório correto "
" "deve ser passado como parâmetro "


pmd_page()
" "Retorna o endereço base de uma tabela de página para"
" "o qual a entrada se refere "


pmd_present()
" "Testa a presença de uma tabela de página referente a"
" "entrada no diretório intermediário de página "


pmd_set()
" "Seta a entrada no diretório intermediário de página "
" "para a base de endereço de uma tabela de página (não"
" "é definido para arquitetura x86) "


pmd_reuse()
" "Incrementa o contador para os processos usando o "
" "diretório intermediário de página referenciado por "
" "parâmetro "

3.3.2.3 Tabela de Página (Page Table)

Uma entrada na tabela de páginas é definida pelo tipo de dados pte_t. Como
antes, há uma macro pte_val(), que fornece acesso ao valor do tipo de
dados.
Uma entrada na tabela de páginas define um número de atributos para a
página de memória referenciada. Estes começam com um número de atributos de
proteção de memória, permitindo que a página seja lida, escrita e
executada. Além disso, existem os atributos 'copy-on-write', 'dirty' e
'age'. Há outros atributos como estes, mas estes não podem ser modificados
individualmente pela funções fornecidas no modelo de memória de arquitetura
independente. Portanto, as seguintes combinações de atributos são definidas
como macros do tipo pgprot_t :

PAGE_NONE
" "Nenhuma página da memória é referenciada pela "
" "entrada na tabela de páginas "


PAGE_SHARED
" "Esta página de memória pode ser referenciada por "
" "um número de processos. Todos os tipos de acesso "
" "são permitidos "


PAGE_COPY
" "Esta página de memória pode ser referenciada por "
" "um número de processos. O atributo "
" "'copy-on-write' é setado "


PAGE_READONLY
" "É permitido somente acesso de leitura ou execução"
" "para esta página de memória "


PAGE_KERNEL
" "Acesso a esta página de memória é permitido "
" "somente no segmento do kernel "

Uma série de funções foram definidas para manipular as entradas na tabela
de páginas e seus atributos. Note que as funções são descritas aqui pela
referência a atributos explicados acima. Para arquiteturas que não suportam
todos os atributos para páginas definidas no modelo de memória de
arquitetura independente, os significados podem variar.

mk_pte()
" "Retorna uma entrada na tabela de páginas gerada do "
" "endereço de memória de uma página e uma variável do "
" "tipo pgprot_t, que descreve a proteção de memória "
" "para a página "


pte_alloc()
" "Aloca uma nova tabela de páginas "


pte_alloc_kernel()
" "Aloca uma nova tabela de páginas para a memória no "
" "segmento do kernel "


pte_clear()
" "Limpa a entrada na tabela de páginas "


pte_cow()
" "Verifica a entrada na tabela de páginas para ver se "
" "o atributo 'copy-on-write' está setado "


pte_dirty()
" "Verifica se o atributo 'dirty' está setado "


pte_exec()
" "Verifica se a execução de código na página de "
" "memória referenciada é permitida, isto é, se o "
" "atributo 'execute' está setado "


pte_exprotect()
" "Limpa o atributo 'execute' "


pte_free()
" "Libera a tabela de páginas "


pte_free_kernel()
" "Libera a tabela de páginas responsável por gerenciar"
" "as páginas no segmento do kernel "


pte_inuse()
" "Verifica se a tabela de páginas está sendo "
" "referenciada por quaisquer processos "


pte_mkclean()
" "Limpa o atributo 'dirty' "


pte_mkcow()
" "Seta o atributo 'copy-on-write' para a página de "
" "memória referenciada "


pte_mkdirty()
" "Seta o atributo 'dirty' "


pte_mkexec()
" "Seta o atributo 'execute', código de permissão na "
" "página a ser executada "


pte_mkold()
" "Seta o atributo 'age' "


pte_mkread()
" "Seta o atributo 'read' para conceder acesso à "
" "leitura para a página "


pte_mkwrite()
" "Seta o atributo 'write' para conceder acesso à "
" "leitura para a página "


pte_mkyoung()
" "Limpa o atributo 'age' "


pte_modify()
" "O atributo de proteção para a página de memória "
" "referenciada pela entrada na tabela de páginas é "
" "modificada conforme definido no parâmetro "


pte_none()
" "Verifica se a entrada na tabela de páginas está "
" "setada "


pte_offset()
" "Retorna um ponteiro para a entrada na tabela de "
" "páginas referenciando a página de memória à qual o "
" "endereço passado como um parâmetro faz referência. "
" "Portanto, o parâmetro passado deve ser a entrada no "
" "diretório intermediário de páginas válida para esta "
" "página "


pte_page()
" "Retorna o endereço da página referenciada pela "
" "entrada na tabela de páginas "


pte_present()
" "Verifica se uma página na memória física é "
" "referenciada pela entrada na tabela de páginas "


pte_rdprotect()
" "Limpa o atributo 'read' para proteger a página "
" "referenciada pela entrada na tabela de páginas "
" "contra acessos de leitura "


pte_read()
" "Verifica se o atributo 'read' está setado "


pte_reuse()
" "Incrementa de 1 o contador para o número de "
" "processos usando esta tabela de páginas "


pte_uncow()
" "Limpa copy-on-write para a página referenciada "


pte_write()
" "Verifica a autorização de escrita para a página "
" "referenciada testando o atributo 'write' "


pte_wrprotect()
" "Seta o atributo 'write' para ativar a proteção de "
" "escrita para a página referenciada "


pte_young()
" "Verifica que o atributo 'age' não está setado "

3.3.3 Swapping

É uma operação realizada pelo Sistema Operacional quando há a necessidade
de um processo trazer uma página virtual para a memória física e não há
páginas físicas livres disponíveis. Neste caso, o Sistema Operacional
prioriza esta página, descartando outra página de memória física.
Se a página a ser descartada da memória física veio de arquivo de uma
imagem ou de dados e não foi escrita para a página então, ela não precisa
ser gravada. Ao invés disso, pode ser descartada e se o processo precisar
daquela página novamente, ela pode ser trazida de volta do arquivo de
imagem ou de dados para a memória.
Portanto, se a página foi modificada, o Sistema Operacional deve preservar
o conteúdo de cada página a fim de que possam ser acessadas posteriormente.
Este tipo de página é conhecida como uma dirty page e quando é removida da
memória, ela é gravada num grupo especial de arquivos chamado swap file
(arquivo de troca). Acessos ao swap file são muito grandes em relação à
velocidade do processador e à memória física e o Sistema Operacional deve
atender à necessidade de escrever páginas para o disco com a necessidade de
conservá-las na memória para serem usadas novamente.
Se o algoritmo decide quais páginas descartar ou trocar (o algoritmo de
swap (troca) não é eficiente) então uma condição conhecida como thrashing
ocorre. Neste caso, as páginas estão constantemente sendo escritas para o
disco e estão sendo lidas de volta e o Sistema Operacional está ocupado
demais para permitir que muito trabalho real seja realizado. Se, por
exemplo, o quadro de página física número 1 está sendo regularmente
acessado então ele não é um bom candidato para o swapping para o Disco
Rígido. O conjunto de páginas que um processo está atualmente usando é
chamado de working set (conjunto de trabalho). Um esquema de swap eficiente
teria certeza de que todos os processos têm seu conjunto de trabalho na
memória física.
O Linux usa uma técnica chamada página LRU (Least Recently Used - Menos
Usada Recentemente) que permite escolher páginas que podem ser removidas do
sistema. Este esquema envolve cada página no sistema tendo uma idade que
muda quando a página é acessada. Quanto mais a página é acessada, mais nova
ela é; quanto menos ela é acessada, mais antiga e mais passada ela se
torna. Páginas antigas são boas candidatas para o swapping.

3.3.3.1 Tipos e Estrutura de Swapping

O Linux executa o swapping de duas formas. Na primeira, o chamado
dispositivo de swap, usa-se um bloco completo de um dispositivo como
arquivo de swap, uma partição do Disco Rígido. Na segunda, o chamado
arquivo de swap, usa-se arquivos de tamanho fixo. Para facilitar, será
usado o termo espaço de swap para referência dos dispositivos de swap e
arquivos de swap.
Existe uma estrutura definida para espaço de swap. Os primeiros 4096 bytes
contém um mapa de bits. Os bits setados indicam que a página de memória
está disponível para paginação. O número do espaço de swap contido nos bits
setados corresponde ao deslocamento de bits a partir do início do espaço.
Do byte 4086 em diante é armazenado uma string de caracteres "SWAP_SPACE"
como um identificador. Isso significa que apenas 4086 x 8 - 1 páginas de
memória (130784 KB) podem ser gerenciados no espaço de swap. O Linux
permite, além disso, administrar 8 espaços de swap em paralelo, conforme
especificado em MAX_SWAPFILES; mas este valor pode ser acrescido para 64.
A vantagem de se usar dispositivos de swap ao invés de arquivos de swap é
que a página é sempre salva em blocos consecutivos. Em arquivos de swap,
uma página pode ser salva em vários blocos não contíguos dependendo de como
o sistema de arquivo fragmentou o arquivo quando ele foi criado. Estes
blocos então precisam ser encontrados por meio do inode do arquivo de swap.

Num dispositivo de swap, o primeiro bloco é dado diretamente pelo
deslocamento para a página de memória a ser gravada ou lida. O restante
então segue este primeiro bloco. Quando um dispositivo de swap é usado,
somente um pedido de leitura ou escrita é feito para cada página, enquanto
um arquivo de swap pede um número dependendo da proporção entre o tamanho
de página e o tamanho do bloco. Num caso típico (quando um tamanho de bloco
de 1024 bytes é usado) isto é agrupado em quatro pedidos separados, para
áreas de leitura no meio externo que pode não necessariamente seguir um
após o outro. No Disco Rígido, isto causa movimentos da cabeça de
leitura/escrita, o que afeta a velocidade de acesso.
A chamada de sistema swapon loga num dispositivo de swap ou arquivo para o
kernel.
int sys_swapon(const char * special_file);

3.4 MEMÓRIA VIRTUAL DO NÚCLEO

O Linux reserva, para seu próprio uso, uma região do espaço de
endereçamento virtual de cada processo, de tamanho constante e independente
do processador. As entradas da tabela de páginas correspondentes a essas
páginas do núcleo são marcadas como protegidas, para que essas páginas não
sejam visíveis ou modificáveis, para processos que estejam sendo executados
em modo usuário. Essa área de memória virtual do núcleo contém duas
regiões. A primeira região é uma área estática, que contém as referências
da tabela de páginas e é utilizada para facilitar a tradução de endereços
físicos em endereços virtuais, quando o núcleo está sendo executado. A
parte central do núcleo, juntamente com todas as páginas alocadas pelo
alocador de páginas, residem nessa área.
O restante da seção reservada ao núcleo, no espaço de endereçamento virtual
de um processo, não é destinado a nenhum propósito específico. As entradas
na tabela de páginas correspondentes a essa faixa de endereços podem ser
modificadas pelo núcleo, se desejado, de modo a apontar para outras áreas
de memória. O núcleo oferece duas rotinas que possibilitam a um processo
usar essa memória virtual. A rotina vmalloc aloca um número arbitrário de
páginas de memória física e associa essas páginas a uma única região da
memória virtual do núcleo, possibilitando a alocação de uma grande área de
memória contígua, mesmo que não exista um número suficiente de páginas de
memória física contíguas para satisfazer a requisição. A rotina vremap
associa uma seqüência de endereços de memória virtual a uma área de memória
usada por um controlador de dispositivo, para ser usada para E/S mapeada em
memória.
Lihat lebih banyak...

Comentarios

Copyright © 2017 DATOSPDF Inc.