Title: Gerenciamento de Mem
1Gerenciamento de Memória
2Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
3Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
4Páginas
- Unidade básica de Gerenciamento de memória
- Tamanho relacionado com a arquitetura (4KB ou 8
KB) - Struct page ltlinux/mm.hgt
struct page page_flags_t flags //Status da
página //ltlinux/page-flags.hgt atomic_t
_count //Contador de referências //page_coun
t() atomic_t _mapcount unsigned long
private struct address_space mapping
//cache pgoff_t index struct list_head lru
void virtual //endereço virtual //NULL
para HIGH MEM
5Páginas
- Struct page - páginas físicas
- Estrutura descreve algo transiente
- Descrição da memória física
- Saber quais são as páginas livres
- Saber quem é o dono de cada página ocupada
- TAMANHO OCUPADO PELAS STRUCTS
- 1GB 262144 páginas (de 4KB)
- Struct page 40 bytes
- 40 262144 10485760 bytes 10MB
- Menos de 1 da memória total
6Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
7Zonas
- Arquiteturas que fazem DMA apenas em alguns
endereços - Arquiteturas que podem endereçar fisicamente mais
memória do que podem endereçar virtualmente - Zonas ltlinux/mmzone.hgt
Zona Descrição L. Física (x86)
ZONE_DMA Páginas que podem ser usadas para DMA lt 16MB
ZONE_NORMAL Páginas endereçadas normalmente Entre 16MB e 896MB
ZONE_HIGHMEM Páginas mapeadas dinamicamente gt 896MB
8Zonas
- Pooling independente
- Alocação para DMA só pode vir da ZONE_DMA
- Alocação normal vem, preferencialmente de
ZONE_NORMAL, mas pode vir de ZONE_DMA
9ZONAS
- Struct zone ltlinux/mmzone.hgt
struct zone spinlock_t
lock //Proteção contra //acessos
concorrentes unsigned long
free_pages //num de pgs. livres unsigned
long pages_min //kernel tenta
manter //o mín livre (swap) unsigned
long pages_low unsigned long
pages_high . . . unsigned long
zone_start_pfn char
name //nome da zona DMA
//Normal e HighMem //(inicializado
no boot) // ltmm/page_aloc.cgt
unsigned long spanned_pages
unsigned long present_pages
10Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
11Operações com Páginas
- Pegando páginas ltlinux/gfp.hgt
struct page alloc_pages(unsigned int gfp_mask,
unsigned int order) //Aloca 2order páginas
contíguas void page_address(struct page
page) //retorna ponteiro para o endereço
lógico unsigned long __get_free_pages(unsigned
int gfp_mask, unsigned int order) //retorna o
endereço lógico / PARA ALOCAR UMA PÁGINA
/ struct page alloc_page(unsigned int
gfp_mask) unsigned long __get_free_page(unsigned
int gfp_mask)
12Operações com Páginas
- Pegando uma página Zerada
- Liberando páginas
unsigned long get_zeroed_page(unsigned int
gfp_mask)
void __free_pages(struct page page, unsigned int
order) void free_pages(unsigned long addr,
unsigned int order) void free_page(unsigned long
addr)
13Operações com Páginas
unsigned long page page __get_free_pages(GFP_K
ERNEL, 3) if (!page) // TRATAR ERRO
MEMÓRIA INSUFICIENTE return
ENOMEM . . . free_pages(page, 3)
14Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
15Kmalloc()
- Interface para obter memória em bytes ao invés de
páginas - malloc flags
- Declaração ltlinux/slab.hgt
- Exemplo
void kmalloc(size_t size, int flags) / retorna
um ponteiro para região fisicamente contínua de
no mínimo size bytes (alocação é feita em
páginas na realidade)/
struct dog ptr ptr kmalloc(sizeof(struct
dog), GFP_KERNEL) if (!ptr) / Erro ... /
16Kmalloc()
- Flags ltlinux/gfp.hgt
- Action Modifiers como o kernel deve alocar a
memória requisitada (Manipuladores de interrupção
? kernel não pode dormir) - Zone Modifiers de onde o kernel deve alocar a
memória requisitada - Type flags combinação de Action Modifiers e
Zone Modifiers necessários para um determinado
tipo de alocação - Exemplo
ptr kmalloc(size, __GFP_WAIT __GFP_IO
__GFP_FS)
17Kmalloc()
Flag Descrição
__GFP_WAIT The allocator can sleep.
__GFP_HIGH The allocator can access emergency pools.
__GFP_IO The allocator can start disk I/O.
__GFP_FS The allocator can start filesystem I/O.
__GFP_COLD The allocator should use cache cold pages.
__GFP_NOWARN The allocator will not print failure warnings.
__GFP_REPEAT The allocator will repeat the allocation if it fails, but the allocation can potentially fail.
__GFP_NORMAL The allocator will indefinitely repeat the allocation. The allocation cannot fail.
__GFP_NORETRY The allocator will never retry if the allocation fails.
__GFP_NO_GROW Used internally by the slab layer.
__GFP_COMP Add compound page metadata. Used internally by the hugetlb code.
18Kmalloc()
- Zone Modifiers
- Default ZONE_NORMAL
- __GFP_HIGHMEM não pode ser usado em
__get_free_pages() ou kmalloc(). É usado com
alloc_pages()
Flag Descrição
__GFP_DMA Aloca memória apenas da ZONE_DMA.
__GFP_HIGHMEM Aloca memória da ZONe_HIGHMEM ou ZONE_NORMAL.
19Kmalloc()
Flag Descrição
GFP_ATOMIC Não pode dormir.
GFP_NOIO Pode bloquear, mas não pode iniciar I/O no disco.
GFP_NOFS Pode bloquear e fazer I/O no disco, mas não pode iniciar uma operação no filesystem. Usado em código do filesystem onde não se pode iniciar outra operação de filesystem.
GFP_KERNEL Alocação normal. Usada no contexto do processo onde é seguro dormir. O kernel fará de tudo para obter a memória requerida.
GFP_USER Alocação normal. Usada para alocar memória para processos do usuário.
GFP_HIGHUSER Alocação na ZONE_HIGHMEM que pode bloquear. Usada para alocar memória para processos do usuário.
GFP_DMA Alocação na ZONE_DMA.
20Kmalloc()
Flag Modifiers Flags
GFP_ATOMIC __GFP_HIGH
GFP_NOIO __GFP_WAIT
GFP_NOFS (__GFP_WAIT __GFP_IO)
GFP_KERNEL (__GFP_WAIT __GFP_IO __GFP_FS)
GFP_USER (__GFP_WAIT __GFP_IO __GFP_FS)
GFP_HIGHUSER (__GFP_WAIT __GFP_IO __GFP_FS __GFP_HIGHMEM)
GFP_DMA __GFP_DMA
21Kmalloc()
Situação Solução
Contexto do Processo. Pode dormir GFP_KERNEL
Contexto do Processo. Não pode dormir GFP_ATOMIC ou GFP_KERNEL antes (qdo pode dormir
Manipuladores de Interrupção GFP_ATOMIC
Softirq GFP_ATOMIC
Tasklet GFP_ATOMIC
DMA e pode dormir (GFP_DMA GFP_KERNEL)
DMA e não pode dormir (GFP_DMA GFP_ATOMIC)
22Kmalloc()
- E para liberar a memória?
- Kfree() ltlinuxslab.hgt
- Exemplo
void kfree(const void ptr)
char buf buf kmalloc(BUF_SIZE,
GFP_ATOMIC) if (!buf) / error allocting
memory ! / . . . kfree(buf)
23Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
24Vmalloc()
- Semelhante ao kmalloc(), porém aloca memória
virtualmente contígua e não necessariamente
fisicamente contígua - A maior parte do kernel usa kmalloc()
- Performance do kmalloc é melhor (TLB)
- Declaração ltlinux/vmalloc.hgt ltmm/vmalloc.cgt
- Para liberar a memória
void vmalloc(unsigned long size)
void vfree(void addr)
25Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
26Slab Layer
- Free Lists
- Problema Controle Global Liberar memória
- Conceito de Slab Alocator
- Estruturas de dados frequentemente usadas tendem
a ser alocadas e liberadas constantemente CACHE - Fragmentação de memória as free lists na CACHE
são arrumadas continuamentea - Melhoria de performance
- O alocador conhece o tamanho do objeto, página e
da cache melhores decisões - Parte da cache é implementada por processador
(SMP lock desnecessário) - Se o alocador é NUMA-aware, ele pode procurar
alocar memória do nó que requisitou - Os objetos armazenados podem ser marcados para
prevenir que múltiplos objetos sejam mapeados na
mesma linha de cache
27Slab Layer
28Slab Layer
- Uma cache por tipo de objeto
- Kmalloc() usa uma família de caches de propósito
geral - Slabs compostas de uma ou mais paginas
fisicamente contíguas - Cada Slab contem um número de objetos
- Slab possui 3 estados full, partial ou empty
29Slab Layer
- Struct slab
- Criação de slabs feita em
struct slab struct list_head list / full,
partial, or empty list / unsigned long
colouroff / offset for the slab coloring /
void s_mem / first object in the slab /
unsigned int inuse / allocated objects in the
slab / kmem_bufctl_t free / first free
object, if any /
__get_free_pages()
30Slab Layer
- Exemplo
- Liberando memória (low mem ou cache destruida)
static inline void kmem_getpages(kmem_cache_t
cachep, unsigned long flags) void addr
flags cachep-gtgfpflags addr (void)
__get_free_pages(flags, cachep-gtgfporder)
return addr
kmem_freepages() ? free_pages()
31Slab Layer
kmem_cache_t kmem_cache_create( const char
name, //nome da cache size_t size, //tamanho de
cada elemento size_t align, //offset unsigned
long flags, //comportamento da cache void
(ctor)(void, kmem_cache_t , unsigned long),
//construtor void (dtor)(void, kmem_cache_t
, unsigned long)) //destrutor
Flag Descrição
SLAB_NO_REAP Slab Layer não faz reap automático
SLAB_HWCACHE_ALIGN Alinhar cada objeto com uma linha de cache
SLAB_MUST_HWCACHE_ALIGN Força alinhamento na cache dos objetos
SLAB_POISON Prenche a slab com (a5a5a5a5)
SLAB_RED_ZONE Ajuda na detecção de buffer overruns
SLAB_PANIC Quando a alocação não pode falhar
SLAB_CACHE_DMA Para usar DMA
32Slab Layer
- Destruindo a cache
- Invocada pelo shutdown de modulos que criam suas
próprias caches - Não pode ser chamada no contexto de interrupção
(pode dormir) - Todas as slabs devem estar vazias
- Ninguém pode acessar a cache durante ou depois
(sincronização)
int kmem_cache_destroy(kmem_cache_t cachep)
33Slab Layer
- Alocando um objeto da cache
- Liberando um objeto
void kmem_cache_alloc(kmem_cache_t cachep, int
flags)
void kmem_cache_free(kmem_cache_t cachep, void
objp)
34Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
35Alocação Estática na Pilha
- Pilha pequena e estática
- Duas formas
- 2 páginas por processo
- 1 página por processo 1 para manipuladores de
interrupção
36Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
37High Memory Mappings
- Mapeamento permanente (pode dormir)
- Mapeamento temporário
void kmap(struct page page) void kunmap(struct
page page)
void kmap_atomic(struct page page, enum km_type
type) void kunmap_atomic(void kvaddr, enum
km_type type)
38Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
39Alocação Per-CPU
- Razões para usar
- Evitar Locks
- Reduzir Invalidação de cache
40Alocação Per-CPU
- Problemas com preempção do kernel
- Código pode ser reescalonado em outro processador
(variável CPU não é mais válida - Se outra task faz preempção pode acessar o
my_percpu concorrentemente - Interface Antiga
unsigned long my_percpuNR_CPUS int cpu cpu
get_cpu() //pega o proc e desablita preemp
my_percpucpu smp_processor_id() //não
desabilita preemp printk("my_percpu on cpud is
lu\n", cpu, my_percpucpu) put_cpu()
//habilita preemp
41Alocação Per-CPU
DEFINE_PER_CPU(type, name) DECLARE_PER_CPU(type,
name) get_cpu_var(name) put_cpu_var(name)
/ preemption / per_cpu(name, cpu) void
alloc_percpu(type) / a macro / void
__alloc_percpu(size_t size, size_t align) void
free_percpu(const void ) get_cpu_ptr(ptr) /
return a void pointer to this processor's copy of
ptr / put_cpu_ptr(ptr) / done enable kernel
preemption / per_cpu_ptr(ptr, cpu)
42Roteiro
- Páginas
- Zonas
- Operações com Páginas
- kmalloc()
- vmalloc()
- Slab Layer
- Alocação estática na Pilha
- High Memory Mappings
- Alocação Per-CPU
- Qual método de alocação usar?
43Qual método de alocação usar?
Método Descrição
Kmalloc() Páginas fisicamente contíguas
alloc_pages() High Memory
Vmalloc() Lógicamente Contíguas apenas
Slab cache Criação e destruição de muitas estruturas grandes
44OBRIGADO!!!!!!