Diseo de Sistemas Operativos Sistema de Paginado Ingeniera




















































- Slides: 52
Diseño de Sistemas Operativos Sistema de Paginado Ingeniería en Informática Facultad de Las Palmas de Gran Canaria Curso 2003 - 2004 Nayarit Santana Pacheco Iván Martín Mesa 1
INDICE TEMATICO 1. Introducción 2. Diagrama General 3. Estructuras de Datos • Tabla de Páginas • Directorio de Páginas • Cachés 4. Gestión • Asignación y Liberación de páginas • Asignación y Liberación de zonas de memoria (núcleo) • Bloqueo de páginas en memoria • Dispositivos de swap 5. Tratamiento de Excepciones 2
INTRODUCCIÓN 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: Memoria del núcleo 0 x. C 0000000 Entorno Argumentos Pila • código • datos • inicializados • no inicializados • código y datos de las bibliotecas compartidas _end Datos (bss) _data Datos (data) _etext Código • pila 0 Espacio de direccionamiento de un proceso 3
INTRODUCCIÓN Al arrancar un proceso no siempre es necesaria toda la información del mismo Memoria pagina PAGINACIÓN BAJO DEMANDA El espacio de cada región de memoria se organiza en páginas para un mejor manejo de la información. Cada región posee una serie de atributos que a su vez heredan las páginas que componen la misma 4
INTRODUCCIÓN Los derechos de acceso a la memoria son gestionados directamente por el procesador. Si el proceso modifica los derechos de acceso asociados a una región, el núcleo se encarga de modificar la protección asociada a las páginas que componen la región 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: Mostrar Tablas Proceso Memoria DATA pagina CODE Núcleo 5
Cte. de protecciones y errno CONSTANTE SIGNIFICADO PROT_NONE La zona se marca como inaccesible PROT_READ La zona se marca como accesible en lectura PROT_WRITE La zona se marca como accesible en escritura PROT_EXEC La zona se marca como accesible en ejecución ERROR SIGNIFICADO EACCES La protección especificada por prot no es aplicable EFAULT La dirección especificada por addr no forma parte del espacio de direccionamiento del proceso que llama EINVAL addr, len o prot contiene un valor no válido ENOMEM El núcleo no ha podido asignar memoria para sus descriptores internos 6
DIAGRAMA GENERAL Pagina logica task_struct mm count pgd Memoria física vm_area_struct vm_end MAPPER vm_start vm_flags DATA pagina vm_inode mmap_avl mmap_sem vm_ops 0 x 8059 BB 8 vm_next vm_area_struct vm_end vm_start vm_flags CODE vm_inode vm_ops 0 x 8048000 vm_next 0 x 0000000 7
ESTRUCTURAS DE DATOS - TABLAS DE PAGINAS Los procesos contiguas necesitan direcciones Dirección virtual Pagina DIRECCIONES VIRTUALES (no tienen porqué ser contiguas en memoria física) Estas direcciones son utilizadas tanto por los procesos como por el núcleo. Desplaz. Tabla de páginas dirección Pagina Desplaz. Dirección física Para acceder a memoria es necesario convertir la dirección virtual en una dirección física. La dirección virtual se divide en dos partes: • número de página • desplazamiento 8
ESTRUCTURAS DE DATOS - TABLAS DE PAGINAS El número de página se utiliza como índice de una tabla de páginas y el desplazamiento hace referencia a la posición que ocupa el dato dentro de la página en cuestión. Todos los accesos a memoria se realizan a través de la tabla de páginas y cada proceso tiene una propia. Dirección virtual Pagina Desplaz. Tabla de páginas dirección Pagina Desplaz. Dirección física Para que 2 procesos compartan una página, debe aparecer el nº de marco de la página física en sus respectivas tablas de páginas. marco es a memoria física lo que página a memoria virtual 9
ESTRUCTURAS DE DATOS - TABLAS DE PAGINAS La tabla de páginas contiene la siguiente información: • Flag de validación Dirección virtual Pagina Desplaz. • nº de marco (memoria física) • información de control Cuando el contenido de una página se altera el núcleo se encarga de actualizar la página correspondiente Tabla de páginas dirección Pagina Desplaz. Dirección física TABLA DE DESCRIPTORES Descriptor Página de memoria 10
ESTRUCTURAS DE DATOS - TABLAS DE PAGINAS La variable mem_map (mm/memory. c) apunta a esta tabla de descriptores La estructura page (<linux/mm. h>) define el formato de cada descriptor. Contiene los siguientes campos: Mostrar Tabla typedef struct page { [. . . ] void *virtual; struct list_head list; Struct address_space *mapping; Unsigned long index; struct page Los valores que puede tomar el campo flags (<linux/mm. h>) de la estructura anterior se muestran en la siguiente tabla: Mostrar Tabla *next_hash, **prev_hash; atomic_t count; unsigned long flags; struct list_head lru; wait_queue_head_t wait; struct zone_struct } mem_map_t; *zone; 11
page TIPO CAMPO DESCRIPCIÓN struct page * next Puntero a la página libre siguiente struct page * prev Puntero a la página libre anterior struct inode * inode Descriptor del i-nodo correspondiente al contenido de la página unsigned long offset Desplazamiento de la página en el i-nodo struct page * next_hash atomic_t count Número de referencias a la página unsigned flags Estado de la página unsigned: 16 dirty Booleano que indica si el contenido de la página se ha modificado unsigned: 8 age Contador utilizado para seleccionar las páginas a descartar de la memoria struct wait_queue * wait Cola de espera usada para esperar la disponibilidad de la página struct page * prev_hash Dirección del descriptor de página anterior en una lista de hash struct buffer_head * buffers Dirección del primer descriptor de memoria intermedia cuyo contenido se sitúa en la página 12 Dirección del descriptor de página siguiente en una lista de hash
flags CONSTANTE (FLAGS) PG_locked PG_error PG_referenced PG_update SIGNIFICADO La página está bloqueada en memoria Se ha producido un error en la carga de la página en memoria La página ha sido accedida El contenido de la página está actualizado PG_free_after La página debe liberarse tras el fin de la e/s en curso PG_decr_after El número de referencias a la página debe decrementarse tras el fin de la e/s en curso PG_DMA La página es utilizable para una transferencia DMA (en la arquitectura x 86, está contenida en los primeros 16 MB de memoria central) PG_reserved La página está reservada para un uso futuro, no es posible acceder a ella 13
ESTRUCTURAS DE DATOS - TABLAS DE PAGINAS Es necesario mantener la tabla de páginas en memoria, sin embargo, dado el espacio de direccionamiento de cada proceso sería 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 ralentizaría la ejecución del mismo. CAT PAG DESPLAZAMIENTO addr Como solución, Linux descompone la tabla de páginas original en distintos niveles. Este conjunto de tablas se denomina directorio de páginas. PAG OFFSET 14
ESTRUCTURAS DE DATOS - DIRECTORIO DE PAGINAS GLOBAL El directorio de tablas de páginas contiene en cada entrada la dirección base de la tabla de páginas correspondiente. Se utilizan los 10 bits de mayor peso de la dirección lineal (3122) como índice en el directorio. CAT PAG DESPLAZAMIENTO addr Cada tabla de páginas contiene en cada entrada la dirección base de una página física o marco. Se utilizan los siguientes 10 bits de la dirección lineal (21 -12) como índice en la tabla. addr Los restantes 12 bits de la dirección lineal se utilizan como desplazamiento dentro del marco de página. PAG OFFSET 15
ESTRUCTURAS DE DATOS - DIRECTORIO DE PAGINAS GLOBAL Para la arquitectura x 86 de Intel, se utiliza una descomposición en dos niveles de las tablas de páginas (figura anterior). 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 x 86, Linux utiliza la tabla intermedia que contiene un único descriptor. L 1 L 2 L 3 offset Directorio Intermedio Paginas Memoria fisica 16
ESTRUCTURAS DE DATOS - DIRECTORIO DE PAGINAS GLOBAL Cada proceso (task_struct) tiene un campo mm de tipo mm_struct que almacena la información de su espacio de direcciones virtual. task_struct mm El campo pgd es del tipo pgd_t: typedef unsigned long pgd_t; Mantiene el directorio de páginas utilizado para resolver la dirección física dada una dirección virtual. mm_struct count pgd Cada mm_struct tiene un conjunto de objetos pgd_t de tamaño PTRS_PER_PGD (1024). mmap_avl mmap_sem 17
ESTRUCTURAS DE DATOS - DIRECTORIO DE PAGINAS GLOBAL Para localizar una direccion (addr), es necesario saber a que pgd_t pertenece: pgd = mm->pgd[addr >> 22]; task_struct mm y determinar la entrada correspondiente en la table de descriptores intermedia: pmd = (pmd_t *) pgd; Una vez sabemos a qué entrada pmd_t corresponde la dirección, 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: count pgd pte = pmd[(addr>>PAGE_SHIFT) & (PTRS_PER_PTE - 1)]; mmap_avl mmap_sem mm_struct 18
ESTRUCTURAS DE DATOS – CACHÉ DE PÁGINAS Linux mantiene en memoria una caché de páginas. Todas las páginas en memoria asociadas a un i-nodo se registran en una lista de hash. Las páginas pueden corresponder a: Proceso Memoria DATA pagina • código ejecutado por los procesos CODE • contenido de archivos proyectados en memoria La caché se gestiona dinámicamente. En caso de que el contenido de una página asociada a un i-nodo deba cargarse en memoria, se asigna una nueva página y se inserta en la caché, leyéndose su contenido desde el disco. Disco 19
ESTRUCTURAS DE DATOS – CACHÉ DE PÁGINAS De esta forma, en los siguientes accesos al contenido de la página, su carga ya no será necesaria, puesto que está presente en memoria. Proceso Cuando Linux se encuentra falto de memoria, selecciona páginas para su descarte. Aquellas páginas 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. Memoria DATA pagina CODE Linux también utiliza este mecanismo de caché de páginas para las lecturas sobre archivos. Las escrituras de datos y manipulaciones de directorios se efectúan mediante el buffer caché. 20
ASIGNACIÓN Y LIBERACIÓN DE PÁGINAS Linux utiliza el principio del Buddy system para asignar y liberar eficientemente bloques de páginas. El núcleo mantiene una lista de grupos de páginas disponibles. El tamaño de los grupos es fijo, siendo asignados un número de páginas igual a potencias de 2. • 0 • 1. . . • 5 pagina Grupos de 1 página Grupos de 2 páginas Grupos de 32 páginas Cada grupo hace referencia a páginas contiguas en memoria. 21
ASIGNACIÓN Y LIBERACIÓN DE PÁGINAS BUDDY SYSTEM: Petición de asignación busca un grupo disponible dentro de la lista que contiene grupos de páginas de tamaño igual o inmediatamente superior al especificado. El grupo se divide en 2 partes: • tantas páginas como tamaño de memoria especificado • resto de páginas que continúan disponibles 22
ASIGNACIÓN Y LIBERACIÓN DE PÁGINAS Las páginas que no son utilizadas se insertan en las otras listas. El tamaño de los grupos es predeterminado. Si sobrasen 24 páginas, se distribuirían en un grupo de 16 y otro de 8. Dentro de cada lista, se comprobaría si el grupo de páginas adyacentes se encuentra disponible, en ese caso se fusionan los grupos y pasan a la lista de grupos de tamaño inmediatamente superior. Así sucesivamente hasta llegar al tope. Este proceso se repite si en vez de ser páginas que sobran de una asignación, son páginas que han sido liberadas. 23
ASIGNACIÓN Y LIBERACIÓN DE PÁGINAS La tabla free_area (mm/page_alloc. c) contiene la dirección del primer descriptor de grupo de páginas para cada tamaño de grupo: static struct free_area_struct free_area[NR_MEM_LISTS]; Mostrar Figura La tabla free_area_struct (mm/page_alloc. c) contiene la dirección del primer descriptor de grupo de páginas para cada tamaño de grupo: 34536 34537 34538 34539 34540 struct free_area_struct { struct page *next; struct page *prev; unsigned int * map; }; Mostrar Tabla Mostrar Funciones 24
free_area_struct TIPO CAMPO DESCRIPCIÓN struct page * next Puntero a la primera página contenida en el primer grupo de páginas 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 mem_map_t 56 5 mem_map_t 4 4 map 3 2 mem_map_t 0 1 map 0 26
ASIGNACIÓN Y LIBERACIÓN DE PÁGINAS 382 /* 383 * The old interface name will be removed in 2. 5: 384 */ 409 /* 385 #define get_free_page get_zeroed_page 410 * Common helper functions. 411 */ 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); 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; 429 clear_page(address); 419 return (unsigned long) page_address(page); 430 return (unsigned long) address; 420 } 431 } 432 return 0; 433 } 27
ASIGNACIÓN Y LIBERACIÓN DE PÁGINAS 435 void __free_pages(struct page *page, unsigned int order) 436 { 437 if (!Page. Reserved(page) && put_page_testzero(page)) 438 __free_pages_ok(page, order); 439 } 441 void free_pages(unsigned long addr, unsigned int order) 442 { 443 if (addr != 0) 444 __free_pages(virt_to_page(addr), order); 445 } 28
ASIGNACIÓN Y LIBERACION DE ZONAS DE MEMORIA (NÚCLEO) Linux ofrece 2 tipos de funciones para asignar zonas de memoria del espacio de direccionamiento propio del núcleo: • kmalloc y kfree: páginas contiguas en memoria central kmalloc y kfree - Útiles para la gestión de zonas pequeñas - Ineficaces con zonas de grandes tamaños - bloques de tamaño fijo vmalloc y vfree • vmalloc y vfree: páginas no contiguas en memoria central - El tamaño de “desperdiciada” es menos importante la memoria 29
ASIGNACIÓN Y LIBERACION DE ZONAS DE MEMORIA (NÚCLEO) En la implementación de kmalloc y kfree, Linux utiliza listas de zonas disponibles. Existe una para cada tamaño de zona. Aunque kmalloc pida un tamaño específico, Linux busca dentro de la lista de tamaño inmediatamente superior. . . firstfree Cada una de las listas lleva asociado un descriptor con la estructura size_descriptor (mm/kmalloc. c) bh_next . . . firstfree Mostrar Tabla El número de páginas varía según el tamaño de los bloques almacenados en la lista. Como mínimo se establece tantas como sean necesarias para formar un bloque. next . . . Listas de bloques de memoria disponibles 30
ASIGNACIÓN Y LIBERACION DE ZONAS DE MEMORIA (NÚCLEO) El inicio de cada grupo de páginas contiene un descriptor con la estructura page_descriptor. . . Mostrar Tabla firstfree Cada grupo de páginas se descompone en una tabla de bloques de tamaño fijo. Al principio de cada bloque se encuentra un descriptor de bloque con la estructura block_header. Mostrar Tabla firstfree bh_next . . . firstfree next . . . Listas de bloques de memoria disponibles 31
kmalloc y kfree 1535 void * kmalloc (size_t size, int flags) 1577 void kfree (const void *objp) 1536 { 1578 { 1537 cache_sizes_t *csizep = cache_sizes; 1579 kmem_cache_t *c; 1538 1580 unsigned long flags; 1539 for (; csizep->cs_size; csizep++) { 1581 1540 if (size > csizep->cs_size) 1582 if (!objp) 1541 continue; 1583 return; 1542 return _kmem_cache_alloc(flags & GFP_DMA ? 1584 local_irq_save(flags); 1543 csizep->cs_dmacachep : csizep->cs_cachep, flags); 1585 CHECK_PAGE(virt_to_page(objp)); 1544 } 1586 c = GET_PAGE_CACHE(virt_to_page(objp)); 1545 return NULL; 1587 __kmem_cache_free(c, (void*)objp); 1546 } 1588 local_irq_restore(flags); 1589 } 32
vmalloc y vfree 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 } 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 }
size_descriptor TIPO CAMPO DESCRIPCIÓN struct page_descriptor * firstfree Puntero al descriptor del primer grupo de páginas disponibles en la lista struct page_descriptor * dmafree Puntero al descriptor del porimer grupo de páginas utilizables para un acceso DMA (es decir, páginas de memoria situadas en los primeros 16 MB de memoria central) disponible en la lista int nblocks Número de bloques de memoria en una página int nmablocks int nfrees int Número de bloques asignados de esa lista Número de bloques libres en esta lista nbutesmalloced Número de bytes asignados en la lista int npages Número de grupos de páginas asignadas a la lista unsigned long gfporder Número de páginas a asignar (expresado en logaritmo de 2 => 2 gfporder) 34
page_descriptor TIPO CAMPO DESCRIPCIÓN struct page_descriptor * next Puntero al descriptor del grupo de páginas siguientes de la lista struct block_header * firstfree Puntero al descriptor del primer bloque libre en el grupo de páginas int order Número de páginas a asignar (expresado en logaritmo de 2) int nfree Número de bloques libres en el grupo de páginas 35
block_header TIPO CAMPO DESCRIPCIÓN unsigned long bh_flags Estado del bloque (asignado, utilizable para un acceso DMA o libre) unsigned long bh_length struct block_header * bh_next Tamaño del bloque Puntero al descriptor de bloque siguiente en el grupo de páginas 36
BLOQUEO DE PÁGINAS EN MEMORIA Linux, al arrancar un proceso, evita cargar todas las páginas que forman parte del espacio de direccionamiento de éste utilizando la paginación bajo demanda. De la misma forma, cuando el núcleo necesita memoria central puede decidir liberar aquellas páginas que no han sido utilizadas en un periodo de tiempo, escribiéndolas en memoria secundaria (en caso de haber sido modificadas). Para evitar que un proceso se vea suspendido por el núcleo mientras espera por la carga de sus páginas, Linux permite a los procesos privilegiados bloquear ciertas páginas en memoria. Existen diversas llamadas al sistema que permiten a un proceso especificar que sus páginas no deben ser descartadas de la memoria. Proceso Memoria DATA pagina CODE Disco 37
DISPOSITIVOS DE SWAP Cuando el núcleo necesita memoria resuelve el problema eliminando páginas. Si estas páginas han sido modificadas, será necesario guardarlas en disco: Funciones utilizadas: • Inicialización de dispositivo mkswap • Archivo proyectado en memoria • Activación de dispositivo se rescribe en el archivo. swapon • Datos • Desactivación de dispositivo se guarda en un dispositivo swap. Linux puede llegar a utilizar varios dispositivos swap; por este motivo, cuando se ha de guardar una página, se exploran los dispositivos de swap activos hasta encontrar un lugar donde escribirla. swapoff • Descartar páginas de la memoria kswapd 38
DISPOSITIVOS DE SWAP El núcleo guarda en memoria una lista de dispositivos de swap activos. Utiliza una tabla de descriptores, donde cada posición 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 páginas usadas. Cuando se descarta una página de la memoria, se le asigna una página en un dispositivo swap y la dirección anterior se memoriza para poder recargarla posteriormente. 39
DISPOSITIVOS DE SWAP Existen varias macroinstrucciones que manipulan estas direcciones (<asm/pgtable. h>) Mostrar Tabla El proceso encargado de descartar páginas de la memoria, kswapd, se lanza al arrancar el sistema y su misión consiste en descartar las páginas inútiles de la memoria. Sólo podrá quitar aquellas que tengan el campo age del descriptor de página a 0. Cuando un dispositivo se desactiva todas las páginas guardadas en él vuelven a cargarse en memoria. 40
swap_info_struct TIPO CAMPO DESCRIPCIÓN unsigned int flags kdev_t swap_device struct inode * swap_file Puntero al descriptor del i-nodo correspondiente, en el caso de un archivo regular unsigned char * swap_map Puntero a una tabla de bytes que representan el estado de cada página (número de referencias a la página) unsigned char * swap_lockmap Puntero a una tabla de bits que indican por cada página si está bloqueada o es utilizable (1 => bloqueada / 0 => libre) int lowest_bit Número de la menor página utilizable int highest_bit Número de la mayor página utilizable int prio int pages unsigned long max Número de páginas en el dispositivo int next Puntero al descriptor siguiente en la lista Estado del dispositivo Identificador del dispositivo en modo bloque Prioridad asociada al dispositivo Número de páginas disponibles (asignadas o no) 41
Macroinstrucciones MACROINSTRUCCIÓN SIGNIFICADO SWP_ENTRY Combina un número de dispositivo y un índice de página para formar una dirección de entrada de swap SWP_TYPE Devuelve el número del dispositivo correspondiente a una dirección de entrada de swap SWP_OFFSET Devuelve el índice de la página correspondiente a una dirección de entrada de swap 42
TRATAMIENTO DE EXCEPCIONES Es el procesador (a través del MMU) quien provoca las excepciones en ciertos accesos a memoria: • do_wp_page • Acceso incompatible con la protección asociada a una página en memoria. • do_swap_page • Acceso a una pagina no presente en memoria. • do_no_page • handle_pte_fault Las funciones usadas en el tratamiento de una excepción se definen en mm/memory. c: • handle_mm_fault • do_page_fault 43
TRATAMIENTO DE EXCEPCIONES La función que se encarga de gestionar las excepciones en la arquitectura x 86 es do_page_fault, declarada en el archivo /arch/i 386/mm/fault. c Primero obtiene el descriptor de la región de memoria afectada mediante la función 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 función expand_stack, para aumentar el tamaño de ésta. - Si el error se debe a un acceso en escritura en una region protegida en lectura, el error se señala enviandole al proceso actual la señal 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 página no presente en memoria, se llama a la función do_no_page, para cargarla. 44
TRATAMIENTO DE EXCEPCIONES do_wp_page: Gestiona la copia en escritura. Cuando un proceso accede en escritura a una página compartida y protegida en lectura exclusiva, se asigna una nueva página mediante la funcion ___get_free_page, y se comprueba si la página afectada es compartida por varios procesos. En caso afirmativo se copia su contenido en la nueva página, y se inserta en la tabla de páginas del proceso actual a través de set_pte. El número de referencias a la anterior página se decrementa por una llamada a free_page. En el caso de que la página afectada no sea compartida, su protección simplemente se modifica para hacer posible la escritura. 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 (!Try. Lock. Page(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 operación swapin está asociada a la región de memoria que contiene la página, se llama a esta función, en caso contrario se llama a la función swap_in. En ambos casos, la página 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 do_no_page: Acceso a una página no presente en memoria. Se comprueba si la pagina ha sido descartada de la memoria y esta en el espacio swap: - do_swap_page En caso negativo se comprueba si existe una operación de memoria nopage asociada a la región que contiene la página. En caso afirmativo se usa esta operación para cargar enl contenido en memoria, insertando la paigna en la tabla de páginas correspondiente. En caso negativo se asigna una nueva pagina rellenada con 0’s, mediante la función ___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
TRATAMIENTO DE EXCEPCIONES En interrupción o Kernel thread No Pertenece a Una región Si Si No Región con permiso de escritura No Pertenece a la Pila del modo usuario Si Acceso de escritura Si No Pagina presente No Si Si No En Modo usuario No Si Copy on Write Región legible o ejecutable No No Dirección incorrecta En una llamada al sistema Si Paginacion Por demanda Enviar SIGSEGV Matar el proceso Y kernel “Ops” Fixup Code 51
REFERENCIAS • Real Time System Group, http: //bernia. disca. upv. es/ • Manejo de Memoria Virtual y Gestión de Procesos en Linux, http: //bernia. disca. upv. es/~sol/08 -gestion-de-memoria/gen-08 -gestion-de-memoria. html • Paginación en Linux, http: //labsopa. dis. ulpgc. es/ii-dso/leclinux/ • The Open Group, http: //www. opengroup. org/ • Programación en Linux 2. 0 52




















































