Los bloqueos duros son el peor tipo de “se congeló” porque son lo suficientemente groseros como para arrastrar al kernel con ellos. Tu sesión SSH se queda parada, la consola deja de actualizarse y lo único que sigue respondiendo es el botón de encendido. Luego reinicias y dmesg te recibe con: “watchdog: BUG: hard LOCKUP”. Genial. ¿Y ahora qué?
Esto es un enfoque de grado producción, orientado a la evidencia, para Ubuntu 24.04: recopila los artefactos correctos en la próxima congelación, reduce el espacio de búsqueda rápidamente y evita cambios aleatorios que hacen el problema no demostrable.
Qué significa realmente un “hard lockup” (y qué no significa)
Un “hard lockup” en Linux es el kernel admitiendo que uno de los núcleos CPU dejó de responder a las interrupciones durante demasiado tiempo. El temporizador watchdog espera actividad periódica (típicamente de un timer de alta prioridad o del contexto NMI según la configuración). Si una CPU queda atascada con interrupciones deshabilitadas, girando en un bucle malo, bloqueada en microcódigo/firmware, o atrapada en una ruta de driver rota, el watchdog avisa.
Qué no es: un mensaje vago de que “el sistema estaba lento”. Puedes tener latencias atroces, iowait desbocado o una máquina sobrecargada sin hard lockups. Los hard lockups son más cercanos a “una CPU se fue de paseo y no avisó a nadie”.
En dmesg normalmente verás algo como:
watchdog: BUG: hard LOCKUP on cpu X- A veces precedido por reinicios de GPU, timeouts de NVMe, stalls de RCU o mensajes de “NMI watchdog”
- A veces seguido por nada, porque el sistema está demasiado congelado para registrar
Los hard lockups pueden ser causados por:
- Casos límite de gestión de energía de la CPU (C-states, P-states, controladores cpufreq)
- Errores de firmware/BIOS (tormentas SMI, tablas ACPI rotas, interacciones de microcódigo)
- Controladores de dispositivos (GPU, HBA, NIC, módulos fuera del árbol)
- Problemas de IOMMU/enrutamiento de interrupciones
- Time-outs de firmware de almacenamiento que desencadenan rutas de código kernel patológicas
- Inestabilidad térmica/eléctrica (sí, “es hardware” a veces es la respuesta)
Hay un hermano: el “soft lockup”. Eso ocurre cuando una CPU ejecuta código kernel demasiado tiempo sin ceder, pero las interrupciones siguen funcionando. Los soft lockups son malos; los hard lockups son “llama al backup de guardia” malos.
Hechos y pequeñas lecciones históricas que puedes usar a las 3 a.m.
- Hecho 1: El detector de hard-lockup del “watchdog” en Linux históricamente dependía del NMI watchdog en x86, porque las NMI pueden dispararse incluso cuando las interrupciones normales están deshabilitadas.
- Hecho 2: Las advertencias de “RCU stall” a menudo aparecen cerca de los cuelgues, pero no son lo mismo que hard lockups. RCU stalls significan que una CPU no alcanza estados quiescentes; un hard lockup es más como que la CPU dejó de responder por completo.
- Hecho 3: ACPI y SMI han sido una fuente clásica de comportamiento “todo se pausa” durante décadas—especialmente en firmware de proveedor optimizado para telemetría de Windows, no para la determinación de Linux.
- Hecho 4: El manejo de errores NVMe se ha sofisticado mucho con los años, pero las “tormentas de reset” aún pueden cascadas en bloqueos del sistema si interrupciones y timeouts se acumulan de forma adversa.
- Hecho 5: Los detectores de lockup del kernel son deliberadamente conservadores. Prefieren molestarte con una advertencia a perder un escenario real de CPU muerta.
- Hecho 6: El detector “hung task” del kernel es distinto otra vez: detecta tareas bloqueadas (a menudo esperas I/O), no CPUs muertas. La gente los confunde constantemente.
- Hecho 7: El trabajo temprano del kernel para “tickless” (NO_HZ) mejoró el consumo, pero también cambió el comportamiento temporal; algunos bugs solo aparecen con combinaciones específicas de timers/idle.
- Hecho 8: Las actualizaciones de microcódigo pueden arreglar lockups, pero también pueden sacar a la luz problemas latentes de drivers o firmware al cambiar el timing. “Empeoró tras las actualizaciones” no es automáticamente “la actualización lo rompió”.
Una idea de confiabilidad que sigue vigente: si no lo puedes medir, no lo puedes gestionar.
— W. Edwards Deming (idea parafraseada)
Playbook de diagnóstico rápido (primero/segundo/tercero)
Esta es la sección “deja de desplazarte, haz esto ahora”. El objetivo es decidir rápidamente si tratas con: (a) un problema conocido de driver/firmware, (b) un caso límite de gestión de energía, (c) patología en la ruta de almacenamiento/interrupciones, o (d) hardware fallando.
Primero: confirma que es un lockup y captura las últimas palabras buenas
- Extrae los logs del arranque anterior (journal persistente) y busca los mensajes precursores más tempranos: reinicios NVMe, Xid de GPU, asserts de firmware iwlwifi, “irq X: nobody cared”, “RCU stall”, errores MCE.
- Decide si necesitas un crash dump. Si puedes reproducir semanalmente o con mayor frecuencia, necesitas kdump. De lo contrario discutirás con sensaciones.
- Registra las versiones del kernel y firmware antes de tocar nada. Las actualizaciones cambian el timing y pueden “arreglar” por accidente.
Segundo: aisla a los culpables comunes con cambios controlados
- Módulos fuera del árbol y GPUs: arranca temporalmente sin drivers propietarios de GPU o módulos DKMS si es factible.
- Gestión de energía: prueba un cambio a la vez: deshabilita C-states profundos (
processor.max_cstate=1) o deshabilita intel_pstate (o cambia el governor). No lancen diez parámetros de kernel a la vez. - IOMMU: alterna la configuración de IOMMU si ves fallos DMA/IOMMU o comportamiento extraño de interrupciones.
Tercero: estresa el subsistema sospechoso y vigila los contadores
- Almacenamiento: ejecuta carga I/O controlada y vigila contadores de error NVMe, latencias y reinicios.
- CPU/ térmicos: revisa logs MCE, temperaturas y comportamiento de frecuencias.
- Interrupciones: identifica tormentas de interrupciones o IRQs atascados; localiza qué dispositivo posee la línea ruidosa.
Chiste #1: Un hard lockup es la forma en que tu servidor pide un “ejercicio de team-building” entre el kernel y tu BIOS.
Preparación orientada a la evidencia antes de cambiar nada
Cuando la gente “debuggea” lockups cambiando toggles aleatorios del BIOS, actualizando tres paquetes y modificando parámetros de kernel a la vez, crean lo único peor que un lockup: un lockup sin reproducibilidad y sin superficie de culpa.
Tu trabajo es producir artefactos que sobrevivan al reinicio. Para Ubuntu 24.04, la lista corta es:
- Logs persistentes del journal entre arranques
- Buffer del ring del kernel del arranque anterior (o salida netconsole)
- Captura kdump (vmcore + dmesg) si la máquina puede panic/reboot
- Logs de errores de hardware: MCE, EDAC, IPMI SEL (si es servidor), SMART/NVMe
- Versiones de firmware y microcódigo
- Un registro mínimo de cambios de lo que probaste y lo que cambió
Haz que los logs sobrevivan reinicios (persistencia de journald)
Ubuntu a menudo viene por defecto con logs persistentes en servidores, pero no siempre, y contenedores/VMs pueden comportarse raro. Hazlo explícito:
cr0x@server:~$ sudo grep -R "^\s*Storage=" /etc/systemd/journald.conf /etc/systemd/journald.conf.d/* 2>/dev/null || true
...output...
Si no ves nada, fíjalo a persistent y reinicia journald:
cr0x@server:~$ sudo install -d -m 2755 /etc/systemd/journald.conf.d
cr0x@server:~$ printf "[Journal]\nStorage=persistent\nSystemMaxUse=2G\n" | sudo tee /etc/systemd/journald.conf.d/persistent.conf
[Journal]
Storage=persistent
SystemMaxUse=2G
cr0x@server:~$ sudo systemctl restart systemd-journald
Decisión: Si tus lockups son infrecuentes, los logs persistentes son obligatorios. Si el disco es pequeño, limita el tamaño; no desactives la persistencia.
Habilita kdump (cuando necesitas respuestas, no suposiciones)
Kdump es tu grabadora de caja negra. No siempre disparará en un hard lockup (porque el sistema puede estar demasiado muerto para panic limpiamente), pero cuando lo hace, es oro. En Ubuntu:
cr0x@server:~$ sudo apt-get update
cr0x@server:~$ sudo apt-get install -y linux-crashdump crash kexec-tools
...output...
Luego asigna memoria crashkernel y habilita:
cr0x@server:~$ sudo sed -n '1,200p' /etc/default/grub
...output...
Edita para incluir algo como crashkernel=512M en un servidor típico (más para máquinas con mucha RAM), luego:
cr0x@server:~$ sudo update-grub
...output...
cr0x@server:~$ sudo systemctl enable --now kdump-tools
...output...
Decisión: Si puedes tolerar la memoria reservada, deja kdump activado hasta que la causa raíz esté probada y arreglada. Desactívalo después, no ahora.
Configura Magic SysRq (a veces puedes “descongelar” lo suficiente para volcar estado)
Los hard lockups a menudo ignoran SysRq porque las interrupciones están muertas en la CPU afectada. Pero en sistemas SMP, otra CPU puede seguir ejecutando lo suficiente como para que SysRq produzca backtraces.
cr0x@server:~$ cat /proc/sys/kernel/sysrq
176
Los valores varían; 176 típicamente permite sync/remount/reboot y algo de debug. Para habilitar completo:
cr0x@server:~$ echo 'kernel.sysrq = 1' | sudo tee /etc/sysctl.d/99-sysrq.conf
kernel.sysrq = 1
cr0x@server:~$ sudo sysctl -p /etc/sysctl.d/99-sysrq.conf
kernel.sysrq = 1
Decisión: Habilita SysRq temporalmente en hosts de depuración. En entornos de alta seguridad, sopesa la política; pero para incidentes, la evidencia vence a la pureza.
Considera netconsole para “la línea de log justo antes de morir”
Cuando los discos están atascados y la consola local está congelada, enviar mensajes del kernel por UDP a otra máquina puede capturar el último suspiro. Esto es especialmente útil para bloqueos relacionados con almacenamiento y drivers.
Tareas prácticas: comandos, salidas, decisiones (12+)
Estas son tareas de campo. Ejecútalas, lee la salida y luego toma una decisión. Cada tarea está aquí porque cambia lo que haces a continuación.
Tarea 1: Confirma el kernel exacto, build y parámetros de arranque
cr0x@server:~$ uname -a
Linux server 6.8.0-52-generic #53-Ubuntu SMP PREEMPT_DYNAMIC Fri Nov 15 12:34:56 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0-52-generic root=UUID=... ro quiet splash
Qué significa: Necesitas la versión exacta del kernel para correlacionar con regresiones conocidas y verificar que los cambios realmente surtieron efecto.
Decisión: Si ejecutas kernels HWE/edge o builds personalizados, regístralo. No mezcles “quizá es el kernel” con procedencia desconocida.
Tarea 2: Extrae logs del kernel del arranque anterior (journal) y filtra señales de lockup
cr0x@server:~$ sudo journalctl -k -b -1 | egrep -i "hard LOCKUP|soft lockup|watchdog|RCU stall|NMI|hung task|MCE|IOMMU|nvme|AER|Xid|amdgpu|i915|EDAC" | tail -n 120
...output...
Qué significa: Buscas precursores: reinicios NVMe, spam AER de PCIe, fallos de GPU, excepciones de máquina, fallos de IOMMU.
Decisión: Si ves errores de hardware (MCE/EDAC/AER), prioriza las vías de hardware/firmware antes de tunear software.
Tarea 3: Comprueba si los logs son persistentes y están bien dimensionados
cr0x@server:~$ journalctl --disk-usage
Archived and active journals take up 1.2G in the file system.
Qué significa: Si el uso de disco es pequeño y reinicias a menudo, puedes estar perdiendo historial relevante.
Decisión: Aumenta SystemMaxUse si estás truncando arranques anteriores; disminúyelo si tu raíz es diminuta.
Tarea 4: Ve cómo fue el apagado anterior (limpio vs crash)
cr0x@server:~$ last -x | head -n 12
reboot system boot 6.8.0-52-generic Mon Dec 29 09:18 still running
crash system crash 6.8.0-52-generic Mon Dec 29 09:02 - 09:18 (00:16)
...output...
Qué significa: Entradas “crash” suelen indicar reinicios abruptos o reboots por watchdog.
Decisión: Si tienes entradas de crash sin logs, configura netconsole y kdump para capturar más.
Tarea 5: Revisa logs de errores de hardware (MCE en x86)
cr0x@server:~$ sudo journalctl -k | egrep -i "mce:|machine check|hardware error" | tail -n 80
...output...
Qué significa: Las Machine Check Exceptions indican problemas a nivel de CPU/cache/memoria/PCIe.
Decisión: Si existen MCEs, deja de culpar drivers aleatorios. Investiga microcódigo, BIOS, DIMMs, térmicos y tarjetas PCIe.
Tarea 6: Revisa EDAC (reportes del controlador de memoria) si está presente
cr0x@server:~$ sudo journalctl -k | egrep -i "EDAC|CE|UE|ecc" | tail -n 80
...output...
Qué significa: Errores corregidos (CE) son advertencias tempranas; errores no corregidos (UE) pueden crashearte.
Decisión: Cualquier UE es un incidente. Re-sienta/reemplaza DIMMs, verifica configuración de memoria y valida settings BIOS.
Tarea 7: Revisa errores AER de PCIe (a menudo señalan un dispositivo enfermo o enlace marginal)
cr0x@server:~$ sudo journalctl -k | egrep -i "AER:|pcieport|Corrected error|Uncorrected" | tail -n 120
...output...
Qué significa: El spam de AER corregido aún puede causar tormentas de latencia y comportamientos extraños de drivers. Lo no corregido es peor.
Decisión: Identifica el dispositivo (BDF) e inspecciona ese slot PCIe/cable/riser/firmware.
Tarea 8: Salud NVMe y log de errores (común en incidentes cercanos a lockups)
cr0x@server:~$ sudo apt-get install -y nvme-cli
...output...
cr0x@server:~$ sudo nvme list
Node SN Model Namespace Usage Format FW Rev
/dev/nvme0n1 S6XXXXXXXXXXXX ACME NVMe 1TB 1 120.0 GB / 1.0 TB 512 B + 0 B 3B2QEXM7
cr0x@server:~$ sudo nvme smart-log /dev/nvme0
...output...
cr0x@server:~$ sudo nvme error-log /dev/nvme0 | head -n 40
...output...
Qué significa: Busca errores de media, entradas crecientes en el log de errores, advertencias de temperatura o un número sospechoso de reinicios.
Decisión: Si los contadores de error suben, trátalo como problema de hardware/firmware primero: actualiza firmware del SSD, cambia slots, revisa alimentación PCIe y refrigeración.
Tarea 9: Identifica timeouts/reinicios repetidos de almacenamiento en el log del kernel
cr0x@server:~$ sudo journalctl -k -b -1 | egrep -i "nvme.*timeout|resetting controller|I/O error|blk_update_request|Buffer I/O error|task abort" | tail -n 120
...output...
Qué significa: Los timeouts de almacenamiento pueden causar bloqueos sistémicos, especialmente si el filesystem raíz o swap están implicados.
Decisión: Si los timeouts están presentes, deja de “tunear”. Estabiliza la ruta de almacenamiento: firmware, alimentación, enlace PCIe, cables/backplanes, configuración multipath, settings de colas.
Tarea 10: Revisa distribución de interrupciones y detecta una tormenta
cr0x@server:~$ head -n 30 /proc/interrupts
CPU0 CPU1 CPU2 CPU3
0: 22 0 0 0 IO-APIC 2-edge timer
1: 0 0 0 0 IO-APIC 1-edge i8042
...output...
cr0x@server:~$ egrep -i "nvme|mlx|ixgbe|i40e|ena|nvidia|amdgpu|ahci|xhci" /proc/interrupts | head -n 20
...output...
Qué significa: Si un conteo de IRQ se dispara en una CPU, puedes tener una tormenta de IRQ o un desbalance de afinidad.
Decisión: Si las interrupciones se fijan a una CPU, considera el estado de irqbalance, afinidad manual o investigar un dispositivo/driver que falla.
Tarea 11: Confirma el comportamiento de irqbalance (no adivines)
cr0x@server:~$ systemctl status irqbalance --no-pager
...output...
Qué significa: irqbalance puede ayudar en servidores de propósito general; en cajas de baja latencia puede estar deliberadamente deshabilitado.
Decisión: Si está deshabilitado, vuelve a habilitarlo temporalmente para probar si los lockups se correlacionan con hotspots de interrupciones. Si está habilitado, considera fijar IRQs críticos para reproducibilidad.
Tarea 12: Revisa driver de frecuencia CPU y governors (sospechosos de gestión de energía)
cr0x@server:~$ sudo apt-get install -y linux-tools-common linux-tools-generic
...output...
cr0x@server:~$ cpupower frequency-info
...output...
cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
intel_pstate
Qué significa: Diferentes drivers cpufreq y governors pueden cambiar el timing y las transiciones de estados de energía que desencadenan lockups.
Decisión: Si los lockups se correlacionan con periodos de inactividad, los estados de sueño profundo son un sospechoso principal.
Tarea 13: Revisa uso de estados idle (C-states) si están disponibles
cr0x@server:~$ sudo apt-get install -y linux-tools-$(uname -r)
...output...
cr0x@server:~$ sudo turbostat --quiet --Summary --interval 5 --num_iterations 3
...output...
Qué significa: Si ves la CPU pasando mucho tiempo en C-states profundos justo antes de lockups (difícil de captar en vivo, pero útil en pruebas), tienes una pista.
Decisión: Prueba limitando C-states vía parámetros del kernel, uno a la vez, y documenta.
Tarea 14: Busca reinicios de driver GPU o Xid (workstations y nodos de cómputo)
cr0x@server:~$ sudo journalctl -k -b -1 | egrep -i "NVRM|Xid|amdgpu|ring timeout|GPU reset|i915.*reset" | tail -n 120
...output...
Qué significa: Los cuelgues de GPU pueden congelar la máquina, especialmente si el driver GPU corre en contexto kernel y se queda atascado.
Decisión: Si errores de GPU preceden a los lockups, reproduce sin el driver GPU o cambiando a la pila abierta para probar causalidad.
Tarea 15: Confirma que kdump está armado y dónde caerían los volcados
cr0x@server:~$ sudo systemctl status kdump-tools --no-pager
...output...
cr0x@server:~$ sudo kdump-config show
...output...
Qué significa: Si kdump no está cargado o crashkernel no está reservado, no obtendrás vmcores.
Decisión: Arregla kdump ahora, no después del próximo incidente.
Tarea 16: Fuerza un crash controlado (solo en un equipo de pruebas o en mantenimiento acordado)
cr0x@server:~$ echo 1 | sudo tee /proc/sys/kernel/sysrq
1
cr0x@server:~$ echo c | sudo tee /proc/sysrq-trigger
...output...
Qué significa: El sistema debería crashear y reiniciar, produciendo un vmcore si kdump está configurado.
Decisión: Si no aparece ningún volcado, todo tu plan “debuggear luego” es ficción.
Acotar por subsistema
1) Gestión de energía: C-states, P-states y el patrón de lockup relacionado con idle
Muchos hard lockups parecen “aleatorios” hasta que los correlacionas con el estado de inactividad. El sistema se congela durante la noche, o justo después de que cae la carga, o durante periodos de poco tráfico. Eso es territorio de gestión de energía: C-states profundos, package C-states y transiciones de escalado de frecuencia.
Qué buscar:
- Los lockups ocurren cuando el sistema está mayormente inactivo
- No hay errores I/O obvios antes
- A veces se arregla deshabilitando sueño profundo en la BIOS, o limitando C-states vía parámetros del kernel
Pruebas controladas (un cambio a la vez):
- Limitar C-states:
processor.max_cstate=1y/ointel_idle.max_cstate=1(Intel) - Deshabilitar driver idle específico:
idle=poll(medida drástica; útil como diagnóstico) - Ajustar modo intel_pstate (active/passive), o poner governor en performance durante una ventana de prueba
Sé estricto: aplica un parámetro por reinicio y mantiene un registro de cambios. La tentación de volcar un comentario de Reddit entero en GRUB es fuerte. Resiste.
2) Firmware y BIOS: donde el tiempo va a morir
Los bugs de firmware pueden manifestarse como lockups porque la CPU desaparece en SMM (System Management Mode) durante demasiado tiempo, o porque las tablas ACPI describen comportamiento de energía/interrupciones roto. Linux no puede arreglar firmware de proveedor. Solo puede rodearlo.
Qué verificar:
- Versión BIOS/UEFI, notas de la release (especialmente cambios de “estabilidad” y “compatibilidad PCIe”)
- Paquete de microcódigo instalado y activo
- Características de energía como ASPM, C-states globales, “package C-state limit” y “Energy Efficient Turbo” (los nombres varían mucho)
Buena práctica: actualiza BIOS y firmware de dispositivos al inicio de la investigación, pero hazlo deliberadamente: cambia una capa, luego observa por una ventana completa de reproducción.
3) Almacenamiento y PCIe: NVMe, AER y la trampa “no es I/O, es el bus”
Los lockups relacionados con almacenamiento a menudo comienzan como problemas de PCIe: enlaces marginales, NVMe sobrecalentadas, problemas de entrega de energía, firmware SSD defectuoso o un backplane haciendo cosas. El log del kernel a menudo mostrará timeouts y reinicios—si tienes la suerte de capturarlos.
Señales clave:
nvme nvme0: I/O X QID Y timeoutresetting controlleren bucle- Spam PCIe AER corregido/no corregido apuntando al BDF del NVMe
- Filesystems que se quejan (abortos de journal EXT4, errores I/O de XFS) tras errores de dispositivo
Decisiones que importan:
- Si el disco raíz está en el NVMe problemático y ves reinicios, no pierdas tiempo “tuneando schedulers I/O”. Estabiliza primero la ruta del dispositivo.
- Si existen errores AER, trátalos como evidencia de capa física: slot, riser, backplane, firmware del dispositivo, settings BIOS PCIe.
4) GPU y stacks de display: cuando el kernel es daño colateral
En escritorios Ubuntu, estaciones de trabajo y nodos de cómputo, los cuelgues de GPU son vecinos comunes de los hard lockups. Un colgado de GPU puede disparar una cadena: reinicios de driver, hilos kernel bloqueados y a veces mensajes de watchdog que parecen relacionados con CPU pero comenzaron en la ruta GPU.
Enfoque:
- Revisa mensajes de reinicio de GPU justo antes del lockup
- Prueba la pila de drivers opuesta (open vs propietario) por un periodo de prueba
- Reduce la complejidad: deshabilita overclocks, reduce estados de energía avanzados, prueba con un compositor/TTY más simple si es posible
5) IOMMU y virtualización: gran potencia, gran rareza
Los problemas de IOMMU pueden aparecer como fallos DMA, reinicios de dispositivo o lockups. Las pilas de virtualización (KVM, VFIO passthrough) aumentan la exposición: más dispositivos, más enrutamiento de interrupciones, más casos límite.
Señales:
DMAR: [DMA Read] faulto logs de fallos AMD-Vi IOMMU- Lockups bajo carga de passthrough
- Comportamiento extraño de dispositivos tras suspend/resume (en estaciones)
Pruebas controladas:
- Alterna IOMMU: deshabilita para una ventana de prueba (
intel_iommu=offoamd_iommu=off) si la política lo permite - O habilita modo passthrough si necesitas IOMMU pero quieres menos traducciones:
iommu=pt
6) Módulos del kernel: DKMS, drivers de terceros y “funciona en mi laptop” en producción
Los módulos fuera del árbol son sospechosos frecuentes porque no reciben las mismas pruebas de regresión con cada actualización de kernel. Ubuntu 24.04 ejecuta un kernel moderno; eso es bueno para soporte de hardware, pero también significa que las APIs se mueven y el timing cambia.
Regla: Si tienes módulos de terceros, tu primer objetivo diagnóstico es reproducir sin ellos. Si no puedes, no tienes un bug; tienes una negociación de dependencias.
Chiste #2: La forma más rápida de reproducir un hard lockup es programar una demo para dirección—los sistemas adoran una audiencia.
Tres mini-historias corporativas (cómo los equipos suelen equivocarse)
Mini-historia 1: El incidente causado por una suposición equivocada
El equipo gestionaba una flota de servidores Ubuntu que procesaban video en segundo plano. Empezaron a ver hard lockups semanales en un subconjunto de hardware nuevo. La narrativa inicial fue segura: “Es el kernel nuevo. Restaure.” Bloquearon la versión del kernel en la flota y… los lockups continuaron. La confianza permaneció; la evidencia no.
Alguien finalmente extrajo los logs del arranque anterior de una caja que tenía journald persistente configurado (héroe silencioso). Justo antes de cada congelación había errores PCIe AER corregidos vinculados a un controlador NVMe específico. Nadie lo había visto porque el almacenamiento “parecía bien” tras el reinicio.
La suposición equivocada fue sutil: asumieron que los errores PCIe corregidos son inofensivos. No lo son cuando son constantes. Los errores corregidos aún cuestan tiempo; además se correlacionan fuertemente con enlaces marginales y fallos no corregidos inminentes.
La solución no fue un rollback de kernel. Fue una actualización de firmware para el SSD y una actualización de BIOS que cambió defaults de entrenamiento de enlace PCIe. También movieron los discos fuera de un lote de backplanes problemático. Los lockups pararon. De todos modos el kernel fue culpado, porque el kernel siempre es un villano conveniente.
Mini-historia 2: La optimización que salió mal
Un servicio interno sensible a latencia quiso reducir consumo en idle. Alguien habilitó C-states de paquete más profundos en BIOS y cambió el governor CPU a un perfil más agresivo de ahorro de energía. El servicio se veía genial en gráficas: menos vatios, p95 similar bajo carga sostenida. Todos se felicitaron por ser adultos eficientes.
Luego vinieron los lockups. No bajo carga. Durante periodos tranquilos. Las máquinas se congelaban por la madrugada cuando el tráfico bajaba. Watchdog hard lockups aparecían en dmesg tras reboots forzados, pero no había nada obvio que los precediera.
Intentaron lo habitual: actualizaciones de drivers, kernels, incluso firmware de NIC. El punto de inflexión fue un experimento deliberadamente aburrido: limitar C-states mediante parámetros del kernel durante dos semanas en un subconjunto de hosts, dejando todo lo demás igual. Los lockups desaparecieron en el conjunto de prueba y continuaron en el control.
La “optimización” era real, pero empujó la plataforma a un caso límite de firmware/idle. Revertieron el cambio de BIOS sobre C-states, lo documentaron y siguieron adelante. El ahorro de energía era menor que el coste de un outage de todos modos.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Un equipo que ejecutaba un clúster de cargas mixtas (bases de datos, caches y batch) tenía una regla: cada host debía tener journald persistente y kdump configurado, incluso si “desperdiciaba memoria”. Era impopular. La gente se quejaba de RAM reservada y espacio en disco. El SRE que lo exigía era descrito como “intensamente poco divertido en las fiestas”, que, siendo justos, era preciso.
Tuvieron una serie de hard lockups tras una ventana de mantenimiento. Algunas cajas se congelaron completamente; otras se reiniciaron. En vez de discutir sobre posibles causas, sacaron vmcores de las cajas que crashearon limpiamente y compararon trazas de stack. Varias mostraban un camino común en código relacionado con la rutina de recuperación del driver de almacenamiento disparada por timeouts repetidos.
No necesitaron reproducir a ciegas en producción. Tenían volcados, marcas temporales y precursores consistentes en logs. El driver del proveedor se actualizó, y el problema se mitigó con un parámetro de módulo específico mientras esperaban la solución definitiva.
Sin heroísmos. Sin folklore. Solo la práctica aburrida de recopilar evidencia antes del incidente. Esa regla se pagó sola en una semana.
Errores comunes: síntoma → causa raíz → solución
Esta sección es intencionalmente específica. Estos son los modos de fallo que veo con frecuencia porque la gente trata “hard lockup” como una maldición genérica de Linux.
1) Síntoma: Hard lockups mayormente por la noche o en baja carga
Probable causa raíz: Estado idle profundo / bug de C-state / firmware idle, a veces desencadenado por tickless timing y baja actividad de interrupciones.
Solución: Prueba limitar C-states con processor.max_cstate=1 y/o intel_idle.max_cstate=1. Si se confirma, ajusta settings en BIOS/microcódigo y luego elimina el workaround de kernel si es posible.
2) Síntoma: Hard lockup precedido por timeouts NVMe o reinicios de controlador
Probable causa raíz: Problema de firmware NVMe, sobrecalentamiento, enlace PCIe marginal o problemas de alimentación/backplane causando tormentas de reset.
Solución: Actualiza firmware del SSD y BIOS. Revisa la refrigeración. Mueve la unidad a otro slot. Investiga logs PCIe AER. Reemplaza el dispositivo si los contadores de error aumentan.
3) Síntoma: Spam “RCU stall” y luego lockup
Probable causa raíz: Hambriento de CPU (tormenta de interrupciones, IRQ atascado) o una ruta de driver que deshabilita interrupciones demasiado tiempo; a veces un host VM bajo presión de interrupciones.
Solución: Revisa /proc/interrupts por tormentas, verifica irqbalance e identifica el dispositivo. Considera aislar CPUs o cambiar afinidad IRQ. Arregla el dispositivo/driver que falla.
4) Síntoma: Hard lockups tras instalar driver propietario de GPU
Probable causa raíz: Colgado o bucle de reset del driver GPU; kernel atascado en ruta de driver.
Solución: Reproduce con driver abierto o sin aceleración GPU. Actualiza driver y kernel en una matriz controlada. Si es una estación, reduce características de gestión de energía de GPU temporalmente.
5) Síntoma: Lockups empezaron tras habilitar passthrough de virtualización
Probable causa raíz: Problemas de traducción IOMMU/remapeo de interrupciones, bugs de firmware del dispositivo bajo VFIO, o routing ACS/interrupt flawed.
Solución: Revisa logs de fallos IOMMU. Prueba iommu=pt o deshabilita temporalmente IOMMU. Actualiza BIOS y firmware del dispositivo. Evita apilar múltiples parámetros de kernel experimentales a la vez.
6) Síntoma: “Siempre es la CPU X” en mensajes watchdog
Probable causa raíz: Hotspot de afinidad IRQ, settings de aislamiento de CPU, o un problema hardware específico de núcleo (raro pero real).
Solución: Inspecciona distribución de IRQs y pinning de CPU. Si realmente sigue al core a través de configuraciones, considera diagnósticos hardware y cambiar CPUs/placas si es posible.
7) Síntoma: No hay logs en absoluto justo antes del freeze
Probable causa raíz: Los logs no son persistentes, el ring buffer fue sobreescrito, o el lockup es tan duro que detiene el logging inmediatamente.
Solución: Habilita journald persistente, habilita kdump y considera netconsole. También aumenta el buffer de logs del kernel si necesitas más detalle en boots ruidosos.
Listas de verificación / plan paso a paso
Checklist A: Captura de evidencia (haz esto una vez y déjalo)
- Habilita almacenamiento persistente de journald con un tope sensato.
- Instala y configura kdump; verifica con una prueba de crash controlada (en mantenimiento).
- Registra: versión del kernel, cmdline, versión BIOS, versión de microcódigo, versiones principales de drivers (GPU, NIC, HBA de almacenamiento).
- Asegura que la sincronización de tiempo funcione (chrony/systemd-timesyncd). Los relojes malos arruinan correlaciones.
- Si los logs siguen desapareciendo, configura netconsole hacia un host colector.
Checklist B: Plan de acotación rápida (una variable por reinicio)
- Quita módulos de terceros (o arranca un kernel conocido y limpio) y abre ventana de reproducción.
- Prueba de gestión de energía: limita C-states durante una ventana. Si mejora, investiga BIOS/microcódigo.
- Prueba de ruta de almacenamiento: revisa SMART/logs NVMe y PCIe AER; estresa I/O mientras observas logs.
- Prueba IOMMU si hay fallos o se usa passthrough:
iommu=pto deshabilita para prueba (si la política lo permite). - Prueba de interrupciones: revisa /proc/interrupts antes y después de la carga; busca tormentas y problemas de afinidad.
Checklist C: Si debes mitigar ahora (triage en producción)
- Aplica la mitigación menos invasiva que apunte plausiblemente al subsistema implicado por los logs.
- Prefiere mitigaciones reversibles y medibles (parámetros de kernel, fijado de versión de driver) sobre expediciones de pesca en BIOS.
- Si existen errores de almacenamiento: migra la carga fuera del host; no “esperes y veas”.
- Si existen errores MCE/EDAC: saca el host de servicio y haz diagnósticos hardware; no intentes optimizar un DIMM inestable.
Preguntas frecuentes
1) ¿Cuál es la diferencia entre un soft lockup y un hard lockup?
Soft lockup: una CPU está atascada ejecutando código kernel demasiado tiempo sin scheduling; las interrupciones aún ocurren. Hard lockup: una CPU deja de responder a interrupciones el tiempo suficiente para que dispare el watchdog. Hard suele ser más grave y más probable que indique rutas con interrupciones deshabilitadas, problemas de firmware o hardware.
2) Si veo “hard LOCKUP” una vez, ¿la máquina es poco fiable para siempre?
No. Algunos lockups son regresiones o bugs de firmware que se corrigen. Pero trátalo como una señal seria hasta que tengas una reproducción limpia y una solución verificada. “Se fue solo” no es una solución; es una pausa.
3) ¿kdump siempre funciona para hard lockups?
No. Si el sistema está totalmente bloqueado y no puede provocar un panic, puede que no obtengas un volcado. Por eso importan los logs persistentes y a veces netconsole. Kdump sigue valiendo la pena porque cuando funciona, acorta dramáticamente las investigaciones.
4) ¿Debo deshabilitar el watchdog para dejar de ver los mensajes?
No lo deshabilites como “fix”. Como mínimo ocultas el síntoma; como peor caso conviertes una falla detectable en un hang silencioso que parece “la red murió”. Deja los watchdogs activos mientras depuras.
5) ¿Pueden los problemas de almacenamiento realmente causar hard lockups de CPU?
Indirectamente, sí. Timeouts, tormentas de reset y manejo de errores patológico pueden llevar a condiciones donde las CPUs pasan demasiado tiempo en secciones críticas o dejan de atender interrupciones correctamente. Además, fallos a nivel PCIe pueden afectar al sistema más allá de “solo I/O”.
6) ¿Cuál es el cambio más rápido para probar lockups relacionados con estado idle?
Limita C-states para una ventana de prueba: añade processor.max_cstate=1 (y en Intel también intel_idle.max_cstate=1) a la línea de comando del kernel. Es brusco, pero es un toggle diagnóstico claro.
7) Solo veo el mensaje de lockup después del reinicio. ¿Cómo capturo la causa antes de que se congele?
Los logs persistentes del journal ayudan. Netconsole puede capturar los últimos mensajes del kernel en otra máquina. Si el sistema aún corre en algunas CPUs durante el hang, los backtraces de SysRq pueden volcarse a logs. Y si puedes provocar un panic sobre el hang (con cuidado), kdump puede capturar el estado.
8) ¿Es más probable en bare metal que en VMs?
Los hard lockups son más comunes en bare metal porque estás expuesto directamente a firmware, gestión de energía y drivers de dispositivos. Las VMs aún pueden ver soft lockups y stalls, pero el hipervisor a menudo absorbe algunas clases de rarezas hardware.
9) ¿Qué pasa si los lockups empezaron justo después de actualizar a Ubuntu 24.04?
Entonces tu prioridad es correlacionar con: cambios de versión de kernel, cambios en la pila de drivers (especialmente GPU/NIC/almacenamiento) y defaults de gestión de energía. Captura evidencia primero, luego prueba: kernel antiguo en 24.04, o kernel 24.04 en userspace anterior si tienes laboratorio. Evita cambiar settings BIOS al mismo tiempo que actualizas el SO a menos que puedas aislar variables.
10) ¿Cuándo dejo de depurar y reemplazo hardware?
Cuando tienes MCE/EDAC, contadores NVMe en ascenso, spam PCIe AER persistente vinculado a un dispositivo, o el problema sigue al componente a través de cambios de OS. El hardware puede ser culpable.
Conclusión: pasos prácticos siguientes
Los hard lockups parecen caos porque roban tu observabilidad en el peor momento. Tu contra-movida es una captura disciplinada de evidencia y experimentos controlados.
- Activa journald persistente y verifica que puedes leer los logs del arranque anterior.
- Configura kdump y realiza una prueba de crash controlada en mantenimiento. Si no puedes obtener un vmcore, no finjas que puedes.
- En el próximo incidente, extrae precursores con
journalctl -k -b -1y clasifica el problema: gestión de energía, almacenamiento/PCIe, GPU/driver, IOMMU/interrupciones o errores de hardware. - Realiza un cambio por reinicio. Lleva un pequeño registro de cambios. Sí, incluso si odias la papeleta.
- Si ves MCE/EDAC/AER/NVMe: deja de tunear y empieza a arreglar la ruta física—firmware, refrigeración, slots y piezas.
Si haces esto bien, la investigación se vuelve aburrida. Aburrido es bueno. Aburrido significa que conviertes un sistema encantado en uno medible.