paginacion - Servidor de Información de Sistemas Operativos

Download Report

Transcript paginacion - Servidor de Información de Sistemas Operativos

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
I N D I C E TE MATI C O
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
0xC0000000
Entorno
Argumentos
Pila
• código
_end
• datos
Datos (bss)
_data
• inicializados
Datos (data)
• no inicializados
• código y datos de
bibliotecas compartidas
_etext
las
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.
Proceso
Memoria
DATA
pagina
CODE
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
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_struct
mm
count
pgd
Memoria física
vm_area_struct
vm_end
MAPPER
vm_start
vm_flags
DATA
pagina
vm_inode
mmap
mmap_avl
mmap_sem
vm_ops
0x8059BB8
vm_next
vm_area_struct
vm_end
vm_start
vm_flags
CODE
vm_inode
vm_ops
0x8048000
vm_next
0x0000000
7
ESTRUCTURAS DE DATOS - TABLAS DE PAGINAS
Los procesos necesitan direcciones contiguas
Dirección virtual
DIRECCIONES VIRTUALES
(no tienen porqué ser contiguas en memoria física)
Pagina
Desplaz.
Tabla de páginas
Estas direcciones son utilizadas tanto por los
procesos como por el núcleo.
dirección
Para acceder a memoria es necesario
convertir la dirección virtual en una
dirección física.
Pagina
Desplaz.
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
Los valores que puede tomar el campo flags
(<linux/mm.h>) de la estructura anterior se
muestran en la siguiente tabla:
Mostrar Tabla
typedef struct page {
[...]
void
*virtual;
struct list_head
list;
Struct address_space
*mapping;
Unsigned long
index;
struct page
*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 descriptor de página siguiente en una lista de hash
Dirección del primer descriptor de memoria intermedia cuyo
contenido se sitúa en la página
12
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 x86, 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
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 (31-22)
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 x86 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 x86,
Linux utiliza la tabla intermedia que contiene
un único descriptor.
L1
L2
L3
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
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:
task_struct
pgd = mm->pgd[addr >> 22];
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
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
pagina
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
free_area
mem_map
mem_map_t
56
5
mem_map_t
4
4
map
3
2
mem_map_t
1
0
0
map
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 (!PageReserved(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: páginas no contiguas en
memoria central
vmalloc y vfree
- El tamaño de la memoria “desperdiciada”
es menos importante
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
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.
firstfree
bh_next
...
firstfree
next
Mostrar Tabla
...
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
Número de bloques libres en esta lista
int
nbutesmalloced
Número de bytes asignados en la lista
int
npages
unsigned long
gfporder
Número de bloques asignados de esa lista
Número de grupos de páginas asignadas a la lista
Número de páginas a asignar (expresado en
logaritmo de 2 => 2gfporder)
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
Número de páginas disponibles (asignadas o no)
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
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 x86 es
do_page_fault, declarada en el archivo /arch/i386/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 (!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 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
región que contiene la página.
nopage
asociada a la
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
No
Pagina
presente
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