Actualidad

Tecnología

Linux busca kernel stacks más pequeños por la escasez de memoria

Will Deacon propone kernel stacks más pequeños en la LPC 2026, con Android superando los 5000 hilos y 16 KB de memoria reservada por cada tarea.

Linux busca kernel stacks más pequeños por la escasez de memoria
Linux busca kernel stacks más pequeños por la escasez de memoria

Un móvil Android en reposo puede mantener más de 5000 hilos vivos y, bajo carga, rozar los 100 MiB gastados solo en pilas del kernel (memoria ocupada por el kernel). Cada hilo aparta unos 16 KB fijos, aunque casi nunca use la mitad. Por ello, Will Deacon, que mantiene arm64 junto a Catalin Marinas, llevó esa cuenta a la microconferencia de gestión de memoria de la Linux Plumbers Conference 2026, celebrada en Praga el 5 de octubre de este año.

El detonante de esta revisión no es técnico, es algo mucho más global: el precio de contrato de la DRAM convencional sube entre un 10% y un 15% en el cuarto trimestre de 2026, y TrendForce lo atribuye a los servidores de inteligencia artificial que acaparan la producción.

Con la memoria otra vez escasa, la pila de cada tarea volvió a la lista de recortes. La cuenta escala rápido: diez mil hilos con pila de 16 KB son 160 MB de memoria fija, imposible de paginar o compartir, y las flotas con millones de hilos la pagan en petabytes. Recortar ese bloque toca el código de entrada de excepciones de cada arquitectura, donde un error de cálculo termina en pánico del sistema.

Una pila por tarea, 16 KB cada una

El kernel de Linux no comparte una única pila entre todos los procesos. Cada hilo recibe un bloque privado que usa mientras ejecuta código privilegiado y que se libera cuando muere. En x86-64 ese bloque mide cuatro páginas de 4 KB, es decir 16 KB, y la documentación del kernel lo fija en THREAD_SIZE, cuatro veces el tamaño de página. En arm64 el valor es el mismo desde 2013.

Ese espacio no está solo reservado, sino que también está inmovilizado. Las pilas se asignan con alineación doble y, cuando van mapeadas en memoria virtual, una página de guarda separa una de otra, así que pasarse de largo se detecta en el acto.

Un hilo bloqueado esperando un socket conserva su pila entera. De ahí la cifra que Deacon llevó a la sala y que figura en la ficha de su ponencia en la Linux Plumbers Conference 2026: entre 2000 y 3000 hilos de sistema más miles de hilos de usuario en un Android reciente, con más de 5000 en reposo y alrededor de 100 MiB comprometidos en pilas cuando el equipo trabaja. La mayor parte de ese espacio no se toca nunca, y ahí está el desperdicio.

De 8 KB a 16 KB y el intento de volver

El arm64 que se fusionó en la versión 3.7 del kernel, en 2012, arrancó con pilas de 8 KB. En julio de 2013, camino de la 3.11, el tamaño subió a 16 KB con una justificación escueta en el registro de cambios: fallos al ejecutar la prueba SpecWeb. No hay hilo de correo que lo discuta, según la arqueología que el propio Deacon mostró en sus diapositivas. x86 subió en la 3.16, ya en 2014, y desde entonces cada hilo paga lo mismo en ambas arquitecturas.

Después llegaron dos mejoras que no cambiaron el tamaño, pero sí el daño de un desbordamiento. La 4.5, en 2016, dio a cada CPU una pila propia para interrupciones. La 4.14, en 2017, mapeó las pilas en memoria virtual, de modo que pasarse de largo provoca una falta controlada en vez de escribir sobre memoria ajena.

Mostrando evidencia

La prueba de tamaño que el ponente mostró en Praga deja el problema sin adornos. Midió cuatro escalones sobre Android y ninguno de los cuatro sale gratis, ni siquiera el que hoy se usa:

  • 4 KB termina en un fallo de arranque durante la inicialización de un controlador, antes de que el sistema llegue a nada.
  • 8 KB pasa QEMU, la compilación del kernel y las baterías de pruebas de Android, pero revienta en reclamación directa bajo presión de memoria.
  • 12 KB no está soportado con pilas mapeadas en memoria virtual, así que ese escalón intermedio no existe hoy.
  • 16 KB pasa todas las pruebas a cambio de una utilización pobre, con páginas apartadas que casi nadie toca.

Ese orden decide la discusión. El escalón problemático no es el arranque ni el trabajo normal, sino la reclamación directa, una ruta que puede acabar llamando a un sistema de ficheros y a la capa de bloque con muy poco margen y sin sitio donde crecer. La traza del pánico lo muestra: la pila se agota dentro de un fallo de página, mientras el kernel intenta liberar memoria para atender otro.

Las alternativas que Deacon puso sobre la mesa

Cuatro caminos quedaron encima de la mesa en la discusión, y ninguno es un simple cambio de constante en un fichero de cabecera. La lista que el ponente llevó a la página de la sesión incluye esto:

  • Reabrir la decisión de 2013 y bajar a 8 KB, ahora que la reclamación directa puede ejecutarse en un hilo del kernel y dejar libre la pila de quien pide memoria.
  • Fijar el tamaño en el arranque con un parámetro de línea de comandos, la vía de una serie de Mostafa Saleh que además habilita pilas de 12 KB.
  • Cambiar el tamaño por tarea, para que pague el espacio extra solo quien de verdad lo necesita en su peor ruta.
  • Exponer el ajuste a espacio de usuario, de modo que Android o una distribución lo elijan sin parchear el árbol.

La quinta vía no estaba en esa lista y sí en el historial. Pasha Tatashin propuso en febrero de 2024 pilas dinámicas que empiezan en 4 KB y crecen con un fallo de página, y el esquema se topó con dos muros que siguen en pie. El primero es el código de entrada de excepciones, que debe cambiar de pila sin dejar estados a medias justo cuando atiende la excepción. El segundo es que el kernel tendría que reservar memoria desde cualquier contexto, incluido uno sin pila disponible para pedirla.

Atacando el problema desde otro ángulo

De ahí que el trabajo reciente ataque el problema desde otro ángulo. Deacon firma una serie de 21 parches que mueve el puntero de la tarea actual a TPIDRRO_ELO, apunta SP_ELO a la pila de desbordamiento y termina intercambiando ambas, con una pila de excepción dedicada. No ahorra un solo byte por sí misma. Lo que hace es dejar el terreno listo para elegir el tamaño en tiempo de ejecución, algo imposible mientras el código de entrada asuma una pila de tamaño fijo.

Los fabricantes ya lo intentaron por su cuenta. Varias implementaciones de pilas dinámicas viven fuera del árbol en teléfonos Android, son invasivas y no caben en los ganchos de personalización del kernel genérico. Deacon lo resumió en el resumen de la charla con una idea simple: encontrar una alternativa upstream para que todos dejen de llevar el código roto en el bolsillo.

A quién le toca pagar la cuenta

El primer damnificado es el móvil, donde la memoria se ha encarecido por encima del resto de componentes. Recortar 8 KB por hilo devolvería unos 40 MB en un equipo con 5000 hilos, espacio que se nota cuando el sistema mata procesos por presión.

En la nube el ahorro se mide en otra escala, porque una flota con millones de hilos dedicados paga páginas que nunca se tocan mientras dure el contrato de memoria. La misma presión de precios llega a quien monta un servidor en casa, donde la RAM decide hoy el presupuesto de un equipo de autohospedaje mucho antes que el procesador.

El calendario tampoco favorece una respuesta rápida. La ventana de fusión de la 7.4 lleva abierta desde el lanzamiento de la 7.3 el 18 de octubre y ya ha absorbido 6753 cambios sin contar las fusiones, así que ninguna de estas series está dentro. Lo que se decida ahora aterrizará, como pronto, en el ciclo siguiente.

Ninguna de las series sobre la mesa ahorra memoria por sí sola, y el tamaño efectivo seguirá dependiendo de una compilación que se sube cada vez que alguien tropieza en su entorno. Cambiar esa lógica exige convencer a los mantenedores de que una pila configurable no será una fuente nueva de pánicos.

Un 8 KB que vuelve a la mesa

La sesión se cerró sin decisión y con preguntas abiertas, entre ellas si el interés existe también en x86 y cómo medir el uso real de las pilas en producción. El suelo del problema sigue igual, porque un tamaño elegido por una prueba de 2013 gobierna cada hilo del sistema.

Si el recorte llega, llegará con el precio de la DRAM como argumento y con una condición incómoda. Cada kilobyte que se quite de la pila es un pánico potencial en una ruta que nadie ejercitó, y el ahorro se mide en megabytes por dispositivo mientras el fallo se mide en equipos que no arrancan.

José Maldonado

Autor

José Maldonado

Activista y bloguero de tecnología, software libre y blockchain.

Lo último
La IA obliga a Bitcoin Core a cambiar su política de seguridad

Una lectura semanal imprescindible sobre inteligencia artificial y blockchain.

Te explicamos cómo transforman la economía, qué nuevas puertas te abren y cómo te afectan.