Sie sind auf Seite 1von 44

Gerenciamento de Memria

Leandro Marzulo

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Pginas

Unidade bsica de Gerenciamento de memria Tamanho relacionado com a arquitetura (4KB ou 8 KB) Struct page <linux/mm.h>
struct page { page_flags_t flags; atomic_t _count; //Status da pgina //<linux/page-flags.h> //Contador de referncias //page_count()

atomic_t _mapcount; unsigned long private; struct address_space *mapping; //cache pgoff_t index; struct list_head lru; void *virtual; //endereo virtual //NULL para HIGH MEM };

Pginas

Struct page - pginas fsicas Estrutura descreve algo transiente Descrio da memria fsica Saber quais so as pginas livres Saber quem o dono de cada pgina ocupada TAMANHO OCUPADO PELAS STRUCTS
1GB = 262144 pginas (de 4KB) Struct page = 40 bytes 40 * 262144 = 10485760 bytes = 10MB Menos de 1% da memria total

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Zonas

Arquiteturas que fazem DMA apenas em alguns endereos Arquiteturas que podem enderear fisicamente mais memria do que podem enderear virtualmente Zonas <linux/mmzone.h>
Descrio Pginas que podem ser usadas para DMA Pginas endereadas normalmente Pginas mapeadas dinamicamente L. Fsica (x86) < 16MB Entre 16MB e 896MB > 896MB

Zona ZONE_DMA ZONE_NORMAL ZONE_HIGHMEM

Zonas
Pooling independente Alocao para DMA s pode vir da ZONE_DMA Alocao normal vem, preferencialmente de ZONE_NORMAL, mas pode vir de ZONE_DMA

ZONAS

Struct zone <linux/mmzone.h>


unsigned long unsigned long unsigned long unsigned long lock; //Proteo contra //acessos concorrentes free_pages; //num de pgs. livres pages_min; //kernel tenta manter //o mn livre (swap) pages_low; pages_high; . . . unsigned long char zone_start_pfn; *name; //nome da zona DMA //Normal e HighMem //(inicializado no boot) // <mm/page_aloc.c> spanned_pages; present_pages;

struct zone { spinlock_t

unsigned long unsigned long };

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Operaes com Pginas

Pegando pginas <linux/gfp.h>

struct page * alloc_pages(unsigned int gfp_mask, unsigned int order) //Aloca 2order pginas contguas void * page_address(struct page *page) //retorna ponteiro para o endereo lgico unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order) //retorna o endereo lgico /* PARA ALOCAR UMA PGINA */ struct page * alloc_page(unsigned int gfp_mask) unsigned long __get_free_page(unsigned int gfp_mask)

Operaes com Pginas

Pegando uma pgina Zerada

unsigned long get_zeroed_page(unsigned int gfp_mask)

Liberando pginas

void __free_pages(struct page *page, unsigned int order) void free_pages(unsigned long addr, unsigned int order) void free_page(unsigned long addr)

Operaes com Pginas

Exemplo

unsigned long page; page = __get_free_pages(GFP_KERNEL, 3); if (!page) { // TRATAR ERRO MEMRIA INSUFICIENTE return ENOMEM; } . . . free_pages(page, 3);

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Kmalloc()

Interface para obter memria em bytes ao invs de pginas = malloc + flags Declarao <linux/slab.h>

void * kmalloc(size_t size, int flags) /* retorna um ponteiro para regio fisicamente contnua de no mnimo size bytes (alocao feita em pginas na realidade)*/

Exemplo

struct dog *ptr; ptr = kmalloc(sizeof(struct dog), GFP_KERNEL); if (!ptr) /* Erro ... */

Kmalloc()

Flags <linux/gfp.h>

Action Modifiers como o kernel deve alocar a memria requisitada (Manipuladores de interrupo kernel no pode dormir) Zone Modifiers de onde o kernel deve alocar a memria requisitada Type flags combinao de Action Modifiers e Zone Modifiers necessrios para um determinado tipo de alocao Exemplo

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

Kmalloc()

Flag

Action Modifiers

Descrio
The allocator can sleep. The allocator can access emergency pools. The allocator can start disk I/O. The allocator can start filesystem I/O. The allocator should use cache cold pages. The allocator will not print failure warnings. The allocator will repeat the allocation if it fails, but the allocation can potentially fail. The allocator will indefinitely repeat the allocation. The allocation cannot fail. The allocator will never retry if the allocation fails. Used internally by the slab layer. Add compound page metadata. Used internally by the hugetlb code.

__GFP_WAIT __GFP_HIGH __GFP_IO __GFP_FS __GFP_COLD __GFP_NOWARN __GFP_REPEAT __GFP_NORMAL __GFP_NORETRY __GFP_NO_GROW __GFP_COMP

Kmalloc()

Zone Modifiers

Default ZONE_NORMAL __GFP_HIGHMEM no pode ser usado em __get_free_pages() ou kmalloc(). usado com alloc_pages()
Descrio
Aloca memria apenas da ZONE_DMA.

Flag
__GFP_DMA

__GFP_HIGHMEM Aloca memria da ZONe_HIGHMEM ou ZONE_NORMAL.

Kmalloc()

Type Flags
Flag
GFP_ATOMIC GFP_NOIO GFP_NOFS

Descrio
No pode dormir. Pode bloquear, mas no pode iniciar I/O no disco. Pode bloquear e fazer I/O no disco, mas no pode iniciar uma operao no filesystem. Usado em cdigo do filesystem onde no se pode iniciar outra operao de filesystem. Alocao normal. Usada no contexto do processo onde seguro dormir. O kernel far de tudo para obter a memria requerida. Alocao normal. Usada para alocar memria para processos do usurio. Alocao na ZONE_HIGHMEM que pode bloquear. Usada para alocar memria para processos do usurio. Alocao na ZONE_DMA.

GFP_KERNEL

GFP_USER GFP_HIGHUSER

GFP_DMA

Kmalloc()

Type Flags Composio


Flag
GFP_ATOMIC GFP_NOIO GFP_NOFS GFP_KERNEL GFP_USER GFP_HIGHUSER GFP_DMA

Modifiers Flags
__GFP_HIGH __GFP_WAIT (__GFP_WAIT | __GFP_IO) (__GFP_WAIT | __GFP_IO | __GFP_FS) (__GFP_WAIT | __GFP_IO | __GFP_FS) (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM) __GFP_DMA

Kmalloc()

Flags Uso
Situao
Contexto do Processo. Pode dormir Contexto do Processo. No pode dormir Manipuladores de Interrupo Softirq Tasklet DMA e pode dormir DMA e no pode dormir

Soluo
GFP_KERNEL GFP_ATOMIC ou GFP_KERNEL antes (qdo pode dormir GFP_ATOMIC GFP_ATOMIC GFP_ATOMIC (GFP_DMA | GFP_KERNEL) (GFP_DMA | GFP_ATOMIC)

Kmalloc()

E para liberar a memria?

Kfree() <linuxslab.h>
void kfree(const void *ptr)

Exemplo
char *buf; buf = kmalloc(BUF_SIZE, GFP_ATOMIC); if (!buf) /* error allocting memory ! */ . . . kfree(buf);

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Vmalloc()

Semelhante ao kmalloc(), porm aloca memria virtualmente contgua e no necessariamente fisicamente contgua A maior parte do kernel usa kmalloc() Performance do kmalloc melhor (TLB) Declarao <linux/vmalloc.h> <mm/vmalloc.c>
void * vmalloc(unsigned long size)

Para liberar a memria


void vfree(void *addr)

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Slab Layer

Free Lists Problema: Controle Global Liberar memria Conceito de Slab Alocator

Estruturas de dados frequentemente usadas tendem a ser alocadas e liberadas constantemente CACHE Fragmentao de memria as free lists na CACHE so arrumadas continuamentea Melhoria de performance O alocador conhece o tamanho do objeto, pgina e da cache melhores decises Parte da cache implementada por processador (SMP lock desnecessrio) Se o alocador NUMA-aware, ele pode procurar alocar memria do n que requisitou Os objetos armazenados podem ser marcados para prevenir que mltiplos objetos sejam mapeados na mesma linha de cache

Slab Layer

Design

Slab Layer
Uma cache por tipo de objeto Kmalloc() usa uma famlia de caches de propsito geral Slabs compostas de uma ou mais paginas fisicamente contguas Cada Slab contem um nmero de objetos Slab possui 3 estados: full, partial ou empty

Slab Layer

Struct slab

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 */ };

Criao de slabs feita em


__get_free_pages()

Slab Layer

Exemplo

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; }

Liberando memria (low mem ou cache destruida)


kmem_freepages() free_pages()

Slab Layer

Criao de cache

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 SLAB_NO_REAP SLAB_HWCACHE_ALIGN SLAB_MUST_HWCACHE_ALIGN SLAB_POISON SLAB_RED_ZONE SLAB_PANIC SLAB_CACHE_DMA Descrio Slab Layer no faz reap automtico Alinhar cada objeto com uma linha de cache Fora alinhamento na cache dos objetos Prenche a slab com (a5a5a5a5) Ajuda na deteco de buffer overruns Quando a alocao no pode falhar Para usar DMA

Slab Layer

Destruindo a cache
Invocada pelo shutdown de modulos que criam suas prprias caches No pode ser chamada no contexto de interrupo (pode dormir) Todas as slabs devem estar vazias Ningum pode acessar a cache durante ou depois (sincronizao)

int kmem_cache_destroy(kmem_cache_t *cachep)

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)

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Alocao Esttica na Pilha


Pilha pequena e esttica Duas formas

2 pginas por processo 1 pgina por processo + 1 para manipuladores de interrupo

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

High Memory Mappings

Mapeamento permanente (pode dormir)


void *kmap(struct page *page) void kunmap(struct page *page)

Mapeamento temporrio
void *kmap_atomic(struct page *page, enum km_type type) void kunmap_atomic(void *kvaddr, enum km_type type)

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Alocao Per-CPU

Razes para usar


Evitar Locks Reduzir Invalidao de cache

Alocao Per-CPU
Problemas com preempo do kernel

Cdigo pode ser reescalonado em outro processador (varivel CPU no mais vlida Se outra task faz preempo pode acessar o my_percpu concorrentemente

Interface Antiga

unsigned long my_percpu[NR_CPUS]; int cpu; cpu = get_cpu(); //pega o proc e desablita preemp my_percpu[cpu]++; smp_processor_id(); //no desabilita preemp printk("my_percpu on cpu=%d is %lu\n", cpu, my_percpu[cpu]); put_cpu(); //habilita preemp

Alocao Per-CPU

Nova Interface

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

Roteiro

Pginas Zonas Operaes com Pginas kmalloc() vmalloc() Slab Layer Alocao esttica na Pilha High Memory Mappings Alocao Per-CPU Qual mtodo de alocao usar?

Qual mtodo de alocao usar?


Mtodo Kmalloc() alloc_pages() Vmalloc() Slab cache Descrio Pginas fisicamente contguas High Memory Lgicamente Contguas apenas Criao e destruio de muitas estruturas grandes

OBRIGADO!!!!!!

Das könnte Ihnen auch gefallen