Gerenciamento de Memória

44
Gerenciamento de Memória Leandro Marzulo

description

Gerenciamento de Memória. Leandro Marzulo. Roteiro. 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?. Roteiro. Páginas Zonas Operações com Páginas kmalloc() - PowerPoint PPT Presentation

Transcript of Gerenciamento de Memória

Page 1: Gerenciamento de Memória

Gerenciamento de MemóriaLeandro Marzulo

Page 2: Gerenciamento de Memória

Roteiro 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?

Page 3: Gerenciamento de Memória

Roteiro 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?

Page 4: Gerenciamento de Memória

Páginas Unidade básica de Gerenciamento de memória Tamanho relacionado com a arquitetura (4KB ou 8

KB)

Struct page <linux/mm.h> struct page {

page_flags_t flags; //Status da página//<linux/page-flags.h>

atomic_t _count; //Contador de referências//page_count()

atomic_t _mapcount; unsigned long private;struct address_space *mapping; //cachepgoff_t index; struct list_head lru; void *virtual; //endereço virtual

//NULL para HIGH MEM};

Page 5: Gerenciamento de Memória

Pá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 bytes40 * 262144 = 10485760 bytes = 10MBMenos de 1% da memória total

Page 6: Gerenciamento de Memória

Roteiro 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?

Page 7: Gerenciamento de Memória

Zonas 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 <linux/mmzone.h>

Zona Descrição L. Física (x86)

ZONE_DMA Páginas que podem ser usadas para DMA

< 16MB

ZONE_NORMAL Páginas endereçadas normalmente

Entre 16MB e 896MB

ZONE_HIGHMEM Páginas mapeadas dinamicamente

> 896MB

Page 8: Gerenciamento de Memória

Zonas

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

Page 9: Gerenciamento de Memória

ZONAS Struct zone <linux/mmzone.h>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)

// <mm/page_aloc.c> unsigned long spanned_pages; unsigned long present_pages;};

Page 10: Gerenciamento de Memória

Roteiro 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?

Page 11: Gerenciamento de Memória

Operações com Páginas Pegando páginas <linux/gfp.h>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)

Page 12: Gerenciamento de Memória

Operaçõ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)

Page 13: Gerenciamento de Memória

Operações com Páginas

Exemplounsigned long page;

page = __get_free_pages(GFP_KERNEL, 3);if (!page) { // TRATAR ERRO – MEMÓRIA INSUFICIENTE return ENOMEM;}

.

.

.

free_pages(page, 3);

Page 14: Gerenciamento de Memória

Roteiro 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?

Page 15: Gerenciamento de Memória

Kmalloc() Interface para obter memória em bytes ao

invés de páginas = malloc + flags Declaração <linux/slab.h>

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 ... */

Page 16: Gerenciamento de Memória

Kmalloc() Flags <linux/gfp.h>

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

Exemploptr = kmalloc(size, __GFP_WAIT | __GFP_IO | __GFP_FS);

Page 17: Gerenciamento de Memória

Kmalloc() Action Modifiers

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.

Page 18: Gerenciamento de Memória

Kmalloc() 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.

Page 19: Gerenciamento de Memória

Kmalloc() Type Flags

Flag DescriçãoGFP_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.

Page 20: Gerenciamento de Memória

Kmalloc() Type Flags – Composição

Flag Modifiers FlagsGFP_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

Page 21: Gerenciamento de Memória

Kmalloc() Flags – Uso

Situação SoluçãoContexto 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)

Page 22: Gerenciamento de Memória

Kmalloc()

E para liberar a memória? Kfree() <linuxslab.h>

Exemplo

void kfree(const void *ptr)

char *buf;

buf = kmalloc(BUF_SIZE, GFP_ATOMIC);

if (!buf)

/* error allocting memory ! */

.

.

.

kfree(buf);

Page 23: Gerenciamento de Memória

Roteiro 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?

Page 24: Gerenciamento de Memória

Vmalloc() 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 <linux/vmalloc.h>

<mm/vmalloc.c>

Para liberar a memória

void * vmalloc(unsigned long size)

void vfree(void *addr)

Page 25: Gerenciamento de Memória

Roteiro 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?

Page 26: Gerenciamento de Memória

Slab 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

Page 27: Gerenciamento de Memória

Slab Layer Design

Page 28: Gerenciamento de Memória

Slab 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

Page 29: Gerenciamento de Memória

Slab 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()

Page 30: Gerenciamento de Memória

Slab 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->gfpflags; addr = (void*) __get_free_pages(flags, cachep->gfporder);

return addr;

}

kmem_freepages() free_pages()

Page 31: Gerenciamento de Memória

Slab Layer Criação de cachekmem_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

Page 32: Gerenciamento de Memória

Slab 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)

Page 33: Gerenciamento de Memória

Slab 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)

Page 34: Gerenciamento de Memória

Roteiro 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?

Page 35: Gerenciamento de Memória

Alocaçã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

Page 36: Gerenciamento de Memória

Roteiro 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?

Page 37: Gerenciamento de Memória

High 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)

Page 38: Gerenciamento de Memória

Roteiro 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?

Page 39: Gerenciamento de Memória

Alocação “Per-CPU”

Razões para usar Evitar Locks Reduzir Invalidação de cache

Page 40: Gerenciamento de Memória

Alocaçã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 Antigaunsigned long my_percpu[NR_CPUS];

int cpu; cpu = get_cpu(); //pega o proc e desablita preemp

my_percpu[cpu]++;

smp_processor_id(); //não desabilita preemp

printk("my_percpu on cpu=%d is %lu\n", cpu, my_percpu[cpu]); put_cpu(); //habilita preemp

Page 41: Gerenciamento de Memória

Alocação “Per-CPU”

Nova InterfaceDEFINE_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);

Page 42: Gerenciamento de Memória

Roteiro 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?

Page 43: Gerenciamento de Memória

Qual 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

Page 44: Gerenciamento de Memória

OBRIGADO!!!!!!