Beruflich Dokumente
Kultur Dokumente
Sistema de Paginado
Ingeniera en Informtica Facultad de Las Palmas de Gran Canaria Curso 2003 - 2004
I N D I C E TE MATI C O
1. Introduccin 2. Diagrama General 3. Estructuras de Datos Tabla de Pginas Directorio de Pginas Cachs 4. Gestin Asignacin y Liberacin de pginas Asignacin y Liberacin de zonas de memoria (ncleo) Bloqueo de pginas en memoria Dispositivos de swap 5. Tratamiento de Excepciones
2
INTRODUCCIN
Todo proceso tiene asociado un espacio de direccionamiento donde se encuentran las zonas de memoria que le han sido asignadas.
Este espacio se compone de varias regiones de memoria: cdigo datos inicializados no inicializados cdigo y datos de bibliotecas compartidas pila las
_end
Datos (bss)
_data
Datos (data)
_etext
Cdigo
INTRODUCCIN
pagina
PAGINACIN BAJO DEMANDA El espacio de cada regin de memoria se organiza en pginas para un mejor manejo de la informacin. Cada regin posee una serie de atributos que a su vez heredan las pginas que componen la misma
4
INTRODUCCIN
Si el proceso modifica los derechos de acceso asociados a una regin, el ncleo se encarga de modificar la proteccin asociada a las pginas que componen la regin de memoria afectada.
Existen diversas constantes que representan las diferentes protecciones posibles (<sys/mman.h>), y en caso de fallo la variable errno puede tomar distintos valores:
Proceso Memoria
DATA
pagina
CODE
Mostrar Tablas
Ncleo
SIGNIFICADO La zona se marca como inaccesible La zona se marca como accesible en lectura La zona se marca como accesible en escritura La zona se marca como accesible en ejecucin
ERROR
SIGNIFICADO
EACCES EFAULT
EINVAL ENOMEM
La proteccin especificada por prot no es aplicable La direccin especificada por addr no forma parte del espacio de direccionamiento del proceso que llama
addr, len o prot contiene un valor no vlido El ncleo no ha podido asignar memoria para sus descriptores internos
DIAGRAMA GENERAL
task_struct
mm count pgd
Memoria fsica
MAPPER vm_start
vm_flags vm_inode
DATA
pagina
vm_ops vm_next
0x8059BB8
vm_area_struct vm_end
vm_start
vm_flags vm_inode vm_ops
CODE 0x8048000
vm_next
0x0000000
DIRECCIONES VIRTUALES
(no tienen porqu ser contiguas en memoria fsica)
Pagina
Desplaz.
Tabla de pginas
Estas direcciones son utilizadas tanto por los procesos como por el ncleo.
direccin Pagina Desplaz.
Para acceder a memoria es necesario convertir la direccin virtual en una direccin fsica. La direccin virtual se divide en dos partes:
nmero de pgina desplazamiento
Direccin fsica
El nmero de pgina se utiliza como ndice de una tabla de pginas y el desplazamiento hace referencia a la posicin que ocupa el dato dentro de la pgina en cuestin. Todos los accesos a memoria se realizan a travs de la tabla de pginas y cada proceso tiene una propia. Para que 2 procesos compartan una pgina, debe aparecer el n de marco de la pgina fsica en sus respectivas tablas de pginas.
marco es a memoria fsica lo que pgina a memoria virtual
Direccin virtual
Pagina Desplaz.
Tabla de pginas
direccin
Pagina
Desplaz.
Direccin fsica
La tabla de pginas contiene la siguiente informacin: Flag de validacin n de marco (memoria fsica) informacin de control Cuando el contenido de una pgina se altera el ncleo se encarga de actualizar la pgina correspondiente TABLA DE DESCRIPTORES Descriptor Pgina de memoria
Tabla de pginas Direccin virtual
Pagina Desplaz.
direccin
Pagina
Desplaz.
Direccin fsica
10
typedef struct page { [...] void struct list_head Struct address_space Unsigned long struct page
*virtual; list; *mapping; index; *next_hash, **prev_hash; count; long flags; lru; wait;
Los valores que puede tomar el campo flags (<linux/mm.h>) de la estructura anterior se muestran en la siguiente tabla: Mostrar Tabla
*zone;
11
page
TIPO struct page * struct page * struct inode * unsigned long struct page * atomic_t unsigned unsigned:16 unsigned:8 struct wait_queue * struct page *
CAMPO next prev inode offset next_hash count flags dirty age wait prev_hash
DESCRIPCIN
Puntero a la pgina libre siguiente Puntero a la pgina libre anterior Descriptor del i-nodo correspondiente al contenido de la pgina Desplazamiento de la pgina en el i-nodo Direccin del descriptor de pgina siguiente en una lista de hash Nmero de referencias a la pgina Estado de la pgina Booleano que indica si el contenido de la pgina se ha modificado Contador utilizado para seleccionar las pginas a descartar de la memoria Cola de espera usada para esperar la disponibilidad de la pgina Direccin del descriptor de pgina anterior en una lista de hash Direccin del primer descriptor de memoria intermedia cuyo contenido se sita en la pgina 12
struct buffer_head *
buffers
flags
CONSTANTE (FLAGS) PG_locked PG_error PG_referenced PG_update PG_free_after PG_decr_after PG_DMA PG_reserved
SIGNIFICADO
La pgina est bloqueada en memoria Se ha producido un error en la carga de la pgina en memoria La pgina ha sido accedida El contenido de la pgina est actualizado La pgina debe liberarse tras el fin de la e/s en curso El nmero de referencias a la pgina debe decrementarse tras el fin de la e/s en curso La pgina es utilizable para una transferencia DMA (en la arquitectura x86, est contenida en los primeros 16 MB de memoria central) La pgina est reservada para un uso futuro, no es posible acceder a ella
13
Es necesario mantener la tabla de pginas en memoria, sin embargo, dado el espacio de direccionamiento de cada proceso sera imposible. Otro problema que surge con este tipo de tablas tiene que ver con la velocidad. Si la tabla de un proceso es muy grande, acceder a ella ralentizara la ejecucin del mismo.
Como solucin, Linux descompone la tabla de pginas original en distintos niveles. Este conjunto de tablas se denomina directorio de pginas.
CAT PAG
DESPLAZAMIENTO
addr
addr
PAG
OFFSET 14
El directorio de tablas de pginas contiene en cada entrada la direccin base de la tabla de pginas correspondiente. Se utilizan los 10 bits de mayor peso de la direccin lineal (31-22) como ndice en el directorio.
Cada tabla de pginas contiene en cada entrada la direccin base de una pgina fsica o marco. Se utilizan los siguientes 10 bits de la direccin lineal (21-12) como ndice en la tabla. Los restantes 12 bits de la direccin lineal se utilizan como desplazamiento dentro del marco de pgina.
CAT PAG
DESPLAZAMIENTO
addr
addr
PAG
OFFSET 15
Para la arquitectura x86 de Intel, se utiliza una descomposicin en dos niveles de las tablas de pginas (figura anterior).
L1
Directorio
L2
L3
offset
Sin embargo, Linux soporta otro tipo de arquitecturas basadas en 3 niveles, por lo que introduce una tabla intermedia para darles soporte. Si la arquitectura pertenece a la familia x86, Linux utiliza la tabla intermedia que contiene un nico descriptor.
Intermedio
Paginas
Memoria fisica
16
Cada proceso (task_struct) tiene un campo mm de tipo mm_struct que almacena la informacin de su espacio de direcciones virtual.
El campo pgd es del tipo pgd_t:
typedef unsigned long pgd_t;
task_struct
mm
Mantiene el directorio de pginas utilizado para resolver la direccin fsica dada una direccin virtual. Cada mm_struct tiene un conjunto de objetos pgd_t de tamao PTRS_PER_PGD (1024).
mm_struct
count pgd
17
Para localizar una direccion (addr), es necesario saber a que pgd_t pertenece:
pgd = mm->pgd[addr >> 22];
task_struct
mm
Una vez sabemos a qu entrada pmd_t corresponde la direccin, se consulta el ltimo nivel del rbol: un arreglo de PTRS_PER_PTE (1024) objetos de tipo pte_t asociado a la estructura pmd_t:
pte = pmd[(addr>>PAGE_SHIFT) & (PTRS_PER_PTE - 1)];
mm_struct
count pgd
18
Proceso Memoria
DATA
pagina
contenido de archivos proyectados en memoria La cach se gestiona dinmicamente. En caso de que el contenido de una pgina asociada a un i-nodo deba cargarse en memoria, se asigna una nueva pgina y se inserta en la cach, leyndose su contenido desde el disco.
Disco
19
De esta forma, en los siguientes accesos al contenido de la pgina, su carga ya no ser necesaria, puesto que est presente en memoria.
Proceso
Cuando Linux se encuentra falto de memoria, selecciona pginas para su descarte. Aquellas pginas de la cach que no han tenido accesos desde hace tiempo se descartan. Funciones como page_unuse y try_to_swap_out se emplean con este fin.
Linux tambin utiliza este mecanismo de cach de pginas para las lecturas sobre archivos. Las escrituras de datos y manipulaciones de directorios se efectan mediante el buffer cach.
Memoria
DATA
pagina
CODE
20
Linux utiliza el principio del Buddy system para asignar y liberar eficientemente bloques de pginas.
El ncleo mantiene una lista de grupos de pginas disponibles. El tamao de los grupos es fijo, siendo asignados un nmero de pginas igual a potencias de 2. 0 1 ... 5 Grupos de 1 pgina Grupos de 2 pginas Grupos de 32 pginas
pagina pagina pagina
BUDDY SYSTEM:
Peticin de asignacin
busca un grupo disponible dentro de la lista que contiene grupos de pginas de tamao igual o inmediatamente superior al especificado.
El grupo se divide en 2 partes: tantas pginas como tamao de memoria especificado resto de pginas que continan disponibles
22
Las pginas que no son utilizadas se insertan en las otras listas. El tamao de los grupos es predeterminado. Si sobrasen 24 pginas, se distribuiran en un grupo de 16 y otro de 8. Dentro de cada lista, se comprobara si el grupo de pginas adyacentes se encuentra disponible, en ese caso se fusionan los grupos y pasan a la lista de grupos de tamao inmediatamente superior. As sucesivamente hasta llegar al tope. Este proceso se repite si en vez de ser pginas que sobran de una asignacin, son pginas que han sido liberadas.
23
La tabla free_area (mm/page_alloc.c) contiene la direccin del primer descriptor de grupo de pginas para cada tamao de grupo:
Mostrar Figura
La tabla free_area_struct (mm/page_alloc.c) contiene la direccin del primer descriptor de grupo de pginas para cada tamao de grupo: Mostrar Tabla
struct free_area_struct { struct page *next; struct page *prev; unsigned int * map; };
Mostrar Funciones
24
free_area_struct
CAMPO next
DESCRIPCIN
Puntero a la primera pgina contenida en el primer grupo de pginas
struct page *
prev
Puntero no utilizado
unsigned int *
map
Puntero a una tabla de bits: cada bit indica si el grupo correspondiente est asignado o disponible
25
Estructura free_area
free_area mem_map
5
mem_map_t
mem_map_t
4
3 2
map
56
mem_map_t
map
26
ASIGNACIN Y LIBERACIN DE PGINAS 382 /* 383 * The old interface name will be removed in 2.5: 384 */ 409 /* 410 * Common helper functions. 411 */ 412 unsigned long __get_free_pages (unsigned int gfp_mask, unsigned int order) 413 { 414 struct page * page; 415 416 page = alloc_pages(gfp_mask, order); 417 if (!page) 418 return 0; 419 return (unsigned long) page_address(page); 420 }
422 unsigned long get_zeroed_page(unsigned int gfp_mask) 423 { 424 struct page * page; 425 426 page = alloc_pages(gfp_mask, 0); 427 if (page) { 428 void *address = page_address(page); 429 clear_page(address); 430 return (unsigned long) address; 431 } 432 return 0; 433 }
27
435 void __free_pages(struct page *page, unsigned int order) 436 { 437 if (!PageReserved(page) && put_page_testzero(page)) 438 __free_pages_ok(page, order); 439 }
28
Linux ofrece 2 tipos de funciones para asignar zonas de memoria del espacio de direccionamiento propio del ncleo:
kmalloc y kfree: pginas contiguas en memoria central
- tiles para la gestin de zonas pequeas - Ineficaces con zonas de grandes tamaos - bloques de tamao fijo
kmalloc y kfree
vmalloc y vfree
29
En la implementacin de kmalloc y kfree, Linux utiliza listas de zonas disponibles. Existe una para cada tamao de zona.
Aunque kmalloc pida un tamao especfico, Linux busca dentro de la lista de tamao inmediatamente superior. Cada una de las listas lleva asociado un descriptor con la estructura size_descriptor (mm/kmalloc.c)
firstfree
....
firstfree firstfree bh_next
...
next
Mostrar Tabla El nmero de pginas vara segn el tamao de los bloques almacenados en la lista. Como mnimo se establece tantas como sean necesarias para formar un bloque.
...
Listas de bloques de memoria disponibles
30
....
bh_next
Cada grupo de pginas se descompone en una tabla de bloques de tamao fijo. Al principio de cada bloque se encuentra un descriptor de bloque con la estructura block_header.
next
...
firstfree
Mostrar Tabla
...
Listas de bloques de memoria disponibles
31
kmalloc y kfree
1535 void * kmalloc (size_t size, int flags) 1536 { 1537 cache_sizes_t *csizep = cache_sizes;
1577 void kfree (const void *objp) 1578 { 1579 kmem_cache_t *c; 1580 unsigned long flags; 1581 1582 if (!objp)
1538
1539 for (; csizep->cs_size; csizep++) { 1540 if (size > csizep->cs_size) 1541 continue; 1542 return _kmem_cache_alloc(flags & GFP_DMA ? 1543 csizep->cs_dmacachep : csizep->cs_cachep, flags); 1544 } 1545 return NULL; 1546 }
1583 return;
1584 local_irq_save(flags); 1585 CHECK_PAGE(virt_to_page(objp)); 1586 c = GET_PAGE_CACHE(virt_to_page(objp)); 1587 __kmem_cache_free(c, (void*)objp); 1588 local_irq_restore(flags); 1589 }
32
vmalloc y vfree 38753 void vfree(void * addr) 38754 { 38755 struct vm_struct **p, *tmp; 38756 38757 if (!addr) 38758 return; 38759 if ((PAGE_SIZE-1) & (unsigned long) addr) { 38760 printk("Trying to vfree() bad address (%p)\n", addr); 38761 return; 38762 } 38763 for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { 38764 if (tmp->addr == addr) { 38765 *p = tmp->next; 38766 vmfree_area_pages(VMALLOC_VMADDR( tmp->addr), 38767 tmp->size); 38768 kfree(tmp); 38769 return; 38770 } 38771 } 38772 printk("Trying to vfree() nonexistent vm area (%p)\n", 33 38773 addr); 38774 }
38776 void * vmalloc(unsigned long size) 38777 { 38778 void * addr; 38779 struct vm_struct *area; 38780 38781 size = PAGE_ALIGN(size); 38782 if (!size || size > (max_mapnr << PAGE_SHIFT)) 38783 return NULL; 38784 area = get_vm_area(size); 38785 if (!area) 38786 return NULL; 38787 addr = area->addr; 38788 if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size)) { 38789 vfree(addr); 38790 return NULL; 38791 } 38792 return addr; 38793 }
size_descriptor
DESCRIPCIN
Puntero al descriptor del primer grupo de pginas disponibles en la lista Puntero al descriptor del porimer grupo de pginas utilizables para un acceso DMA (es decir, pginas de memoria situadas en los primeros 16 MB de memoria central) disponible en la lista
int
int int int
nblocks
nmablocks nfrees nbutesmalloced
int
unsigned long
npages
gfporder
page_descriptor
DESCRIPCIN
Puntero al descriptor del grupo de pginas siguientes de la lista Puntero al descriptor del primer bloque libre en el grupo de pginas Nmero de pginas a asignar (expresado en logaritmo de 2)
int
nfree
35
block_header
DESCRIPCIN
Estado del bloque (asignado, utilizable para un acceso DMA o libre) Tamao del bloque
36
Linux, al arrancar un proceso, evita cargar todas las pginas que forman parte del espacio de direccionamiento de ste utilizando la paginacin bajo demanda. De la misma forma, cuando el ncleo necesita memoria central puede decidir liberar aquellas pginas que no han sido utilizadas en un periodo de tiempo, escribindolas en memoria secundaria (en caso de haber sido modificadas).
Para evitar que un proceso se vea suspendido por el ncleo mientras espera por la carga de sus pginas, Linux permite a los procesos privilegiados bloquear ciertas pginas en memoria. Existen diversas llamadas al sistema que permiten a un proceso especificar que sus pginas no deben ser descartadas de la memoria.
Proceso Memoria
DATA
pagina
CODE
Disco
37
DISPOSITIVOS DE SWAP
Cuando el ncleo necesita memoria resuelve el problema eliminando pginas. Si estas pginas han sido modificadas, ser necesario guardarlas en disco: Archivo proyectado en memoria
mkswap
Activacin de dispositivo
se rescribe en el archivo.
swapon
Desactivacin de dispositivo
Datos
se guarda en un dispositivo swap.
swapoff
Descartar pginas de la memoria
Linux puede llegar a utilizar varios dispositivos swap; por este motivo, cuando se ha de guardar una pgina, se exploran los dispositivos de swap activos hasta encontrar un lugar donde escribirla.
kswapd
38
DISPOSITIVOS DE SWAP
El ncleo guarda en memoria una lista de dispositivos de swap activos. Utiliza una tabla de descriptores, donde cada posicin describe uno de ellos. La estructura de cada descriptor se llama swap_info_struct (<linux/swap.h>)
Mostrar Tabla
Los campos swap_map y swap_lockmap son utilizados para mantener actualizadas las pginas usadas.
Cuando se descarta una pgina de la memoria, se le asigna una pgina en un dispositivo swap y la direccin anterior se memoriza para poder recargarla posteriormente.
39
DISPOSITIVOS DE SWAP
swap_info_struct
TIPO
CAMPO
DESCRIPCIN
Estado del dispositivo
Identificador del dispositivo en modo bloque Puntero al descriptor del i-nodo correspondiente, en el caso de un archivo regular Puntero a una tabla de bytes que representan el estado de cada pgina (nmero de referencias a la pgina) Puntero a una tabla de bits que indican por cada pgina si est bloqueada o es utilizable (1 => bloqueada / 0 => libre) Nmero de la menor pgina utilizable Nmero de la mayor pgina utilizable Prioridad asociada al dispositivo Nmero de pginas disponibles (asignadas o no) Nmero de pginas en el dispositivo Puntero al descriptor siguiente en la lista
41
unsigned int
kdev_t struct inode * unsigned char * unsigned char * int int int int unsigned long int
flags
swap_device swap_file swap_map swap_lockmap lowest_bit highest_bit prio pages max next
Macroinstrucciones
MACROINSTRUCCIN SWP_ENTRY
SIGNIFICADO
Combina un nmero de dispositivo y un ndice de pgina para formar una direccin de entrada de swap Devuelve el nmero del dispositivo correspondiente a una direccin de entrada de swap Devuelve el ndice de la pgina correspondiente a una direccin de entrada de swap
SWP_TYPE
SWP_OFFSET
42
TRATAMIENTO DE EXCEPCIONES
Es el procesador (a travs del MMU) quien provoca las excepciones en ciertos accesos a memoria:
Acceso incompatible con la proteccin asociada a una pgina en memoria. Acceso a una pagina no presente en memoria.
do_wp_page
do_swap_page
do_no_page handle_pte_fault
handle_mm_fault do_page_fault
43
TRATAMIENTO DE EXCEPCIONES
La funcin que se encarga de gestionar las excepciones en la arquitectura x86 es do_page_fault, declarada en el archivo /arch/i386/mm/fault.c Primero obtiene el descriptor de la regin de memoria afectada mediante la funcin find_vma, y luego comprueba el tipo de error: - Si el error lo ha causado una pagina no presente en el segmento de la pila, se llama a la funcin expand_stack, para aumentar el tamao de sta.
- Si el error se debe a un acceso en escritura en una region protegida en lectura, el error se seala enviandole al proceso actual la seal SIGSEV.
- Si el error es igual al anterior, pero debido a una copia en escritura, se llama a la funcion do_wp_page. - Si el error se debe a una pgina no presente en memoria, se llama a la funcin do_no_page, para cargarla.
44
TRATAMIENTO DE EXCEPCIONES
45
TRATAMIENTO DE EXCEPCIONES
942 static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, 943 unsigned long address, pte_t *page_table, pte_t pte) 944 { 945 struct page *old_page, *new_page; 946 947 old_page = pte_page(pte); 948 if (!VALID_PAGE(old_page)) 949 goto bad_wp_page; 950 951 if (!TryLockPage(old_page)) { 952 int reuse = can_share_swap_page(old_page); 953 unlock_page(old_page); 954 if (reuse) { 955 flush_cache_page(vma, address); 956 establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte)))); 957 spin_unlock(&mm->page_table_lock); 958 return 1; /* Minor fault */ 959 } 960 }
46
TRATAMIENTO DE EXCEPCIONES
do_swap_page: Carga en memoria el contenido de una pagina situada en el espacio de swap. Si una operacin swapin est asociada a la regin de memoria que contiene la pgina, se llama a esta funcin, en caso contrario se llama a la funcin swap_in. En ambos casos, la pgina asignada se inserta en el espacio de direccionamiento del proceso actual.
47
TRATAMIENTO DE EXCEPCIONES
1111 static int do_swap_page(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, 1113 pte_t * page_table, pte_t orig_pte, int write_access) 1114 { 1115 struct page *page; 1116 swp_entry_t entry = pte_to_swp_entry(orig_pte); 1117 pte_t pte; 1118 int ret = 1; 1119 1120 spin_unlock(&mm->page_table_lock); 1121 page = lookup_swap_cache(entry); 1122 if (!page) { 1123 swapin_readahead(entry); 1124 page = read_swap_cache_async(entry); 1125 if (!page) { 1126 /* 1127 * Back out if somebody else faulted in this pte while 1128 * we released the page table lock. 1129 */ 1130 int retval; 1131 spin_lock(&mm->page_table_lock); 1132 retval = pte_same(*page_table, orig_pte) ? -1 : 1; 1133 spin_unlock(&mm->page_table_lock); 1134 return retval; 1135 } 1136 ret = 2; 1137 }
48
TRATAMIENTO DE EXCEPCIONES
asociada a la
En caso afirmativo se usa esta operacin para cargar enl contenido en memoria, insertando la paigna en la tabla de pginas correspondiente. En caso negativo se asigna una nueva pagina rellenada con 0s, mediante la funcin ___get_free_page.
49
TRATAMIENTO DE EXCEPCIONES
239 static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma, 1240 unsigned long address, int write_access, pte_t *page_table) { 1242 struct page * new_page; 1243 pte_t entry; 1245 if (!vma->vm_ops || !vma->vm_ops->nopage) 1246 return do_anonymous_page(mm, vma, page_table, write_access, address); 1247 spin_unlock(&mm->page_table_lock); 1249 new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0); 1251 if (new_page == NULL) return 0; 1253 if (new_page == NOPAGE_OOM) return -1; 1259 if (write_access && !(vma->vm_flags & VM_SHARED)) { 1260 struct page * page = alloc_page(GFP_HIGHUSER); 1261 if (!page) { 1262 page_cache_release(new_page); 1263 return -1; } 1265 copy_user_highpage(page, new_page, address); 1266 page_cache_release(new_page); 1267 lru_cache_add(page); 1268 new_page = page; } 1271 spin_lock(&mm->page_table_lock); 1299 update_mmu_cache(vma, address, entry); 1300 spin_unlock(&mm->page_table_lock); 1301 return 2; /* Major fault */ 1302 }
50
Si
No
Pertenece a la Pila del modo usuario
Si No
Si
Acceso de escritura
No
Pagina presente
Si Si No
No
Regin legible o ejecutable
En Modo usuario No
No
Si
Copy on Write
Enviar SIGSEGV
Fixup Code 51
REFERENCIAS
52