← Gestión de Memoria Bloque 7 · Memoria virtual · Tema 29 de 52

Tema 29

Paginación por demanda y fallo de página

El fallo de página es el mecanismo central de la memoria virtual: cuando un proceso accede a una página no presente, la MMU lanza una excepción y el sistema operativo carga la página en la RAM. En este tema verás los pasos exactos, desde el hardware hasta la reanudación de la instrucción, los tipos de fallo y cómo se observa en Linux.

1. Qué es un fallo de página

Un fallo de página (page fault) ocurre cuando un proceso accede a una página cuya entrada en la tabla de páginas tiene el bit presente a 0. La MMU no puede traducir la dirección y lanza una excepción al procesador, que transfiere el control al sistema operativo.

El fallo de página es el mecanismo que hace posible la memoria virtual: permite que las páginas se carguen solo cuando se necesitan.

Fallo de página es la excepción que lanza la MMU cuando un acceso a memoria se refiere a una página no presente en la RAM, transfiriendo el control al sistema operativo para que la cargue.

2. Los pasos del fallo de página

El proceso completo tiene estos pasos:

  1. El programa accede a una dirección virtual cuya página no está presente.
  2. La MMU detecta P=0 y lanza una excepción de fallo de página (trap).
  3. El procesador guarda el estado (registros, PC) y transfiere el control al manejador de fallos del SO.
  4. El SO identifica la página que falta (usando la dirección virtual que causó el fallo).
  5. El SO busca un marco libre (o reemplaza uno si no hay).
  6. El SO carga la página desde el disco (swap o archivo) al marco.
  7. El SO actualiza la tabla de páginas: P=1, marco=f, y actualiza los bits.
  8. El SO reanuda la instrucción que causó el fallo.
Pasos de un fallo de página: hardware → SO → reanudación Programa acceso a pág no presente MMU P=0 → trap SO carga página, actualiza tabla RAM reanudar instrucción
El hardware detecta la página ausente, el SO la carga en la RAM, actualiza la tabla y reanuda la instrucción.

3. Lo que hace el hardware

El hardware (MMU + procesador) es responsable de:

Todo esto ocurre en hardware, en unos pocos ciclos. El SO no interviene hasta que la excepción se lanza.

4. Lo que hace el sistema operativo

El manejador de fallos de página del SO realiza:

  1. Identificar la página: lee el registro que contiene la dirección virtual que causó el fallo (CR2 en x86).
  2. Verificar que el acceso sea válido: comprueba que la dirección esté dentro del espacio del proceso y que los permisos sean correctos. Si no, envía SIGSEGV.
  3. Buscar un marco libre: si hay marcos libres, se usa uno. Si no, se elige una víctima (reemplazo, tema 34).
  4. Cargar la página: si la página está en el swap, se lee del disco. Si es la primera vez, se inicializa a cero (páginas anónimas) o se lee del archivo (páginas de archivo).
  5. Actualizar la tabla: se establece P=1, se pone el marco, y se actualizan los bits (accessed, dirty, etc.).
  6. Reanudar: se devuelve el control al proceso.

El SO también puede prefetchear páginas adyacentes (leer varias a la vez) para mejorar el rendimiento.

5. Reanudar la instrucción

Tras cargar la página, el SO reanuda la instrucción que causó el fallo. Esto es posible porque:

Esto es transparente para el programa: no se entera de que hubo un fallo de página.

6. Tipos de fallo de página

TipoCausaAcción del SO
Menor (minor)La página está en la RAM pero no mapeada (ej. página ya cargada por otro proceso, o página COW).Mapear la página sin leer del disco. Rápido.
Mayor (major)La página no está en la RAM; hay que leerla del disco.Leer del disco y cargar en la RAM. Lento.
InválidoLa dirección no es válida (fuera del espacio del proceso).Enviar SIGSEGV al proceso.

Los fallos menores son rápidos (microsegundos); los mayores son lentos (milisegundos). La distinción es importante para el rendimiento.

7. Ejemplo numérico

Un programa accede a una dirección virtual 0x1234 cuya página (p=2) no está presente. La tabla de páginas tiene:

PáginaMarcoPresente
05Sí
12Sí
2—No
38Sí

El acceso a 0x1234 (p=2) genera un fallo de página. El SO carga la página 2 en un marco libre (ej. marco 3), actualiza la tabla (página 2 → marco 3, P=1) y reanuda la instrucción. El acceso se repite y ahora tiene éxito.

8. Experimento en C

El programa siguiente provoca un fallo de página manejable usando mmap con PROT_NONE y luego cambiando los permisos:

pagefault.c
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

int main(void)
{
    size_t tam = 4096;
    char *p = mmap(NULL, tam, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (p == MAP_FAILED) { perror("mmap"); return 1; }

    printf("Región mapeada en %p (sin permisos)\\n", (void *)p);
    printf("Voy a cambiar permisos a PROT_READ|PROT_WRITE...\\n");
    if (mprotect(p, tam, PROT_READ | PROT_WRITE) == -1) { perror("mprotect"); return 1; }

    printf("Ahora escribo en la página...\\n");
    p[0] = 42;   /* esto puede provocar un fallo de página menor */
    printf("Leí: %d\\n", p[0]);

    munmap(p, tam);
    return 0;
}
terminal · fallo de página
$ gcc -std=c17 -Wall -Wextra -o pagefault pagefault.c
$ ./pagefault
Región mapeada en 0x7f8b4c000000 (sin permisos)
Voy a cambiar permisos a PROT_READ|PROT_WRITE...
Ahora escribo en la página...
Leí: 42Leí: 42

El programa mapea una región sin permisos, cambia los permisos con mprotect y escribe. El sistema puede generar un fallo de página menor al cargar la página en la RAM.

9. Probar con un simulador

Este simulador muestra los pasos de un fallo de página para una dirección virtual cuya página no está presente.

Simulador · fallo de página

PasoDescripción
1
2
3
4
5
6
7
8

10. En Linux

Linux maneja los fallos de página en el manejador do_page_fault. Las herramientas para observarlos:

terminal · fallos de página en Linux
$ grep pgfault /proc/vmstat
pgfault 1234567
pgmajfault 890
$ perf stat -e page-faults,major-faults ./pagefault

11. Resumen

12. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué es un fallo de página?

La excepción que lanza la MMU cuando se accede a una página no presente en la RAM.

2. ¿Qué hace el hardware en un fallo de página?

Detecta P=0, lanza un trap y guarda la dirección virtual que causó el fallo.

3. ¿Qué hace el SO en un fallo de página?

Identifica la página, busca un marco, carga la página, actualiza la tabla y reanuda la instrucción.

4. ¿Cómo se reanuda la instrucción?

El procesador restaura el PC guardado y re-ejecuta la instrucción (ahora la página está presente).

5. ¿Qué es un fallo menor (minor)?

Un fallo en el que la página está en la RAM pero no mapeada (no requiere leer del disco).

6. ¿Qué es un fallo mayor (major)?

Un fallo que requiere leer la página desde el disco (swap o archivo).

7. ¿Qué ocurre si el acceso es inválido?

El SO envía SIGSEGV al proceso.

8. ¿Qué registro guarda la dirección que causó el fallo en x86?

CR2.

Para practicar

  1. Modifica el simulador para que una página esté presente desde el principio (sin fallo).
  2. Explica por qué la instrucción se re-ejecuta y no se "salta".
  3. Investiga cómo Linux distingue entre un fallo menor y uno mayor.
  4. Usa perf stat para contar los fallos de página de un programa que toca 1 MiB.
  5. Explica qué ocurre si el SO no puede encontrar un marco libre.
  6. Dibuja el flujo completo de un fallo de página, desde el hardware hasta la reanudación.
  7. Compara el tiempo de un fallo menor y uno mayor.