Ingeniería

Arreglar la suspensión/reanudación en Meteor Lake: un parámetro del kernel, un año tarde

12 min lectura
Angel Sulev

Corrección, 22-09-2026. Cuando publiqué esto señalé i915.enable_psr2_sel_fetch=0 como la solución. No lo era. Mi panel anuncia solo PSR1, así que el selective fetch nunca llegó a actuar — el parámetro cambiaba el momento del cuelgue, que es exactamente por qué me lo creí durante meses. El parámetro que acabó con los cuelgues es i915.enable_psr=0. La URL conserva el nombre antiguo para no romper los enlaces existentes; todo lo de abajo es la versión corregida, y he dejado el camino equivocado al final porque es la parte instructiva.

Mantuve pulsado el botón de encendido más de 300 veces en esta máquina.

ThinkPad P1 Gen7, Intel Core Ultra 9 185H (Meteor Lake), del kernel 6.x al 7.x. Dos síntomas, no uno. Cada suspensión acababa en cuelgue: LED de encendido fijo, máquina muerta, apagado forzado. Y aparte: dejar la pantalla quieta unos cinco minutos y la máquina entera se bloqueaba sin que hubiera ninguna suspensión de por medio. Más de un año de trabajo real en un portátil que no sabía ni dormir ni estarse quieto.

El segundo síntoma es el que resuelve el caso, y lo ignoré durante meses porque ya había decidido que esto era un fallo de suspensión.


Síntomas — para que sepas si estás en el sitio correcto

  • Cuelgue al reanudar desde suspensión — LED encendido, sin respuesta, apagado forzado obligatorio.
  • Cuelgue en inactividad, sin suspensión — pantalla quieta unos 5 minutos y la máquina se bloquea. Esta es la pista. Un fallo puramente de suspensión no te cuelga la máquina mientras estás sentado trabajando.
  • Parece un teclado muerto — la entrada deja de responder mientras el resto parece vivo. No es un fallo del teclado, y perseguirlo como tal es una trampa a la que vuelvo más abajo.
  • Sin logs del intento fallido — journalctl -b -1 sale vacío o truncado; el cuelgue llega antes de que el journal se vuelque a disco.
  • Persiste entre versiones del kernel — 6.x y 7.x, igual.
  • Funciona bien en Fedora, Ubuntu y Kali de serie. Esa es la pista entera.

Hardware que encaja: cualquier portátil Meteor Lake (Intel Core Ultra 100 o 200) con el driver i915, especialmente con panel eDP OLED. El P1 Gen7 está confirmado.


Causa raíz: el PSR forzado atasca el PHY eDP al salir

Panel Self Refresh permite que el panel mantenga su propia imagen para que el motor de display deje de escanear. Es un ahorro real de energía cuando funciona. En esta máquina no funciona.

El panel interno (Samsung SDC OLED) anuncia solo PSR1 — ni PSR2 ni Panel Replay. Mi cmdline forzaba i915.enable_psr=2, pero el nivel lo dicta el panel: el kernel negocia a la baja y ejecuta PSR1 de todas formas. Así que yo tenía configurada una cosa y estaba ejecutando otra, que es como un año entero tocando la perilla equivocada se mantuvo plausible.

El PSR entra solo con un frontbuffer estático — ese es el cuelgue en inactividad — y con s2idle, que es el cuelgue al reanudar. El fallo está en la salida del PSR: el driver tiene que volver a enganchar el PHY C10 de Meteor Lake, y se atasca. Ocho ciclos instrumentados fallaron todos en el mismo punto exacto:

Failed to bring PHY A to idle
[CONNECTOR:eDP-1] commit wait timed out
vblank wait timed out   (in i915_drm_resume)
pixel_rate expected 572010 found 65082

Por qué parece un fallo del teclado. El worker de DRM atascado retiene el modeset lock de DRM mientras espera un vblank que no llega nunca. Todas las tareas de GPU y del compositor se encolan detrás de ese lock, y la entrega de eventos de entrada es una de ellas. Las interrupciones de serio siguen llegando por hardware; simplemente userspace nunca llega a procesarlas. Un mecanismo, dos disparadores, bloqueo total.


La solución

Mínimo — añade esto a tu cmdline del kernel

i915.enable_psr=0 i915.enable_dc=1 i915.enable_fbc=1 mem_sleep_default=s2idle
  • i915.enable_psr=0 — la solución. El panel es solo PSR1, así que no hay nada que ajustar: encendido es precisamente lo que atasca el PHY.
  • i915.enable_dc=1 — estados de ahorro DC5/DC6. enable_dc=0 rompe el display en este stack; déjalo fijado a 1.
  • i915.enable_fbc=1 — fijado por determinismo entre actualizaciones de kernel, no porque arregle nada.
  • mem_sleep_default=s2idle — Meteor Lake no tiene S3. Nunca pongas deep.

Con dGPU NVIDIA (serie RTX)

i915.enable_psr=0
i915.enable_dc=1 i915.enable_fbc=1 i915.enable_guc=3
i915.force_probe=7d55 xe.force_probe=!7d55
nvidia_drm.modeset=1 nvidia_drm.fbdev=1
nvidia.NVreg_DynamicPowerManagement=0x02
nvidia.NVreg_PreserveVideoMemoryAllocations=0
mem_sleep_default=s2idle

i915.force_probe=7d55 y xe.force_probe=!7d55 asignan la iGPU Meteor Lake a i915 y bloquean que el driver xe se la dispute. En un sistema de GPU dual esto es obligatorio. 0x7d55 es el ID del P1 Gen7 — comprueba el tuyo con lspci -nn | grep VGA.

NVreg_DynamicPowerManagement=0x02 activa D3 de grano fino para que la RTX se apague por completo en reposo. NVreg_PreserveVideoMemoryAllocations depende del driver que uses. Con los módulos abiertos (nvidia-open), guardar y restaurar la VRAM al suspender ya es automático, así que déjalo en 0. El 1 es para el módulo propietario, y la documentación de gestión de energía de NVIDIA dice que entonces necesita el mecanismo /proc/driver/nvidia/suspend y los servicios nvidia-suspend/nvidia-resume. Para saber cuál tienes: modinfo -F license nvidia. Si dice Dual MIT/GPL, es el abierto.

Con paso de GPU en QEMU/KVM

i915.enable_psr=0 i915.enable_dc=1
intel_iommu=on iommu=pt
mem_sleep_default=s2idle

iommu=pt mantiene bajo el coste del IOMMU para los dispositivos del host. Déjalo solo si usas VMs con paso de GPU; CUDA en bare metal no lo necesita.

Cómo aplicarlo

GRUB — añade a GRUB_CMDLINE_LINUX_DEFAULT en /etc/default/grub y después:

sudo grub-mkconfig -o /boot/grub/grub.cfg

systemd-boot — añade a la línea options en /boot/loader/entries/*.conf. Sin regenerar nada.


Compruébalo en 30 segundos, sin reiniciar

No hace falta que me creas ni que toques el gestor de arranque para salir de dudas. El PSR se conmuta en caliente vía debugfs. El índice de tarjeta DRI suele ser 1 para la iGPU — mira /sys/kernel/debug/dri/*/:

echo 1 | sudo tee /sys/kernel/debug/dri/1/i915_edp_psr_debug      # desactiva PSR en caliente
sudo cat /sys/kernel/debug/dri/1/i915_edp_psr_status              # -> PSR mode: disabled

Después trabaja con normalidad, deja la pantalla quieta más de cinco minutos y haz un sudo systemctl suspend. Si los dos cuelgues desaparecen, tu causa era el PSR — hazlo permanente con i915.enable_psr=0. Se deshace con echo 0, o reiniciando.

Conmútalo con la pantalla activa, no en reposo: así fuerzas una salida limpia del PSR en lugar de provocarla desde justo el estado que intentas evitar.


Verificación después de reiniciar

# Comprobar que s2idle está seleccionado
cat /sys/power/mem_sleep          # s2idle entre corchetes = seleccionado

# Comprobar que el parámetro entró
grep -o 'i915.enable_psr=[0-9]' /proc/cmdline

# Suspender
sudo systemctl suspend
# Espera 10 segundos. Pulsa el botón de encendido una vez para despertar.

# Comprobación rápida
journalctl -b | grep -E 'PM: suspend|resume'

PM: suspend entry seguido de PM: suspend exit con unos segundos de diferencia significa que la suspensión funcionó. Si la máquina no responde tras pulsar el botón, se colgó. Antes de mantener pulsado el botón de encendido, prueba la salida del propio kernel: Alt+PetSis, y luego s, u, o — sincroniza, remonta en solo lectura y apaga. En un ThinkPad sin tecla PetSis, mantén Alt primero, pulsa Fn+ImprPant, suelta esas dos y pulsa cada letra sin soltar Alt. Después lee el arranque anterior:

journalctl -b -1 | grep -E 'PM: suspend|i915.*fail|PHY|flip_done|panic'

La firma del fallo de PSR es Failed to bring PHY A to idle y flip_done timed out. Si no ves ningún error de i915, tienes otro problema — mira la nota del final.


Es la configuración, no el chip ni el kernel

El mismo hardware suspende bien en Fedora, Ubuntu y Kali con los ajustes de serie. El linux de Arch se compila del mismo árbol mainline que el de Fedora, así que la versión del kernel nunca fue la variable — lo era la capa de configuración. Ninguna de esas distros fuerza el PSR. Yo sí.

Y un T480s (Whiskey Lake) se colgó igual en cuanto heredó la misma cmdline. Otra GPU, otro PHY, el mismo fallo. Copia una configuración que funcione antes de ponerte a ajustar a ciegas.


Ajuste de energía — qué hacer una vez suspende

Autosuspend de USB — evita el interruptor global

Yo tenía usbcore.autosuspend=-1 en la cmdline, que desactiva el autosuspend de USB para todos los dispositivos de la máquina. Funciona, y te cuesta batería sin motivo. Activa el autosuspend globalmente en TLP y exime solo a los dispositivos que no deben dormirse:

# /etc/tlp.conf
USB_AUTOSUSPEND=1
USB_DENYLIST="1050:0407 27c6:6594 04f2:b805"

Esos IDs son una YubiKey (1050:0407), un lector de huella Goodix (27c6:6594) y una cámara integrada Chicony (04f2:b805). Busca los tuyos con lsusb, y añade mochilas Bluetooth, lectores de tarjeta y cualquier cosa que deba responder al instante.

Quita usbcore.autosuspend=-1 una vez confirmes que la suspensión funciona, regenera la configuración de GRUB, reinicia y vuelve a probar.

TLP en Meteor Lake

CPU_DRIVER_OPMODE_ON_AC=active
CPU_DRIVER_OPMODE_ON_BAT=active
CPU_SCALING_GOVERNOR_ON_AC=powersave
CPU_SCALING_GOVERNOR_ON_BAT=powersave
CPU_BOOST_ON_AC=1
CPU_BOOST_ON_BAT=0
PLATFORM_PROFILE_ON_AC=balanced
PLATFORM_PROFILE_ON_BAT=low-power

active es el modo correcto para intel_pstate en MTL — no lo pases a passive. El gobernador powersave con intel_pstate no es lo que su nombre sugiere: sigue subiendo la frecuencia cuando hace falta, solo que decide mejor cuándo.

Qué cuesta realmente desactivar el PSR

Medido en esta máquina con i915.enable_psr=0:

  • Consumo en reposo: ~6 W de sistema completo (upower, energy-rate)
  • Residencia RC6 de la GPU Intel: ~99% (intel_gpu_top) — la iGPU está aparcada casi toda la ventana de reposo
  • Batería: más de 14 h en reposo hasta descarga completa con una batería de 90 Wh

O sea: renuncias a un ahorro pequeño de self-refresh y a cambio la máquina reanuda, y no se bloquea mientras la estás mirando. Si quieres recuperar ese vatio, sácalo de la ruta de reposo con un framebuffer en negro — en OLED, negro significa píxeles apagados — y no reactivando el PSR que atasca el PHY. Y deja el apagado de panel por DPMS fuera de esto: mueve el mismo PHY.


Problemas conocidos no críticos

NVIDIA “PRH failed to update thermal limit”

NVRM: GPU0 nvAssertFailedNoLog: Assertion failed: PRH failed to update thermal limit!

Aparece dos veces por arranque en mi sistema. Es un bug de nvidia-open — el Platform Request Handler no consigue sincronizar con el firmware GSP. No es fatal, no provoca cuelgues, no afecta a la suspensión. Cambia al paquete propietario nvidia si te molesta; si no, ignóralo.

“Correcting number of heads (0x00)” — esperado cuando no hay ninguna pantalla externa conectada. No es tu configuración.

Deprecación de vm.laptop_mode en TLP — cosmético. Quita la línea de tu config de TLP.


Lo que hice mal (y vale la pena leerlo)

Durante meses estuve convencido de que el culpable era el selective fetch de PSR2. Puse i915.enable_psr2_sel_fetch=0, dejé enable_psr=2 y cité linux-surface #2158 como respaldo. Cambiaba el momento del fallo, así que me lo creí. Era irrelevante: el panel va en PSR1, así que sel_fetch nunca estuvo en la ruta. Los cuelgues siguieron. Lo que los acabó fue apagar el PSR entero.

Un parámetro que desplaza los síntomas no es un parámetro que arregle la causa. Verifica contra un sistema que sabes que funciona, en vez de razonar hacia adelante desde un mecanismo plausible, que es lo que hice durante un año.

Dos más, en la misma línea:

  • No añadas nunca ningún parámetro de arranque i8042.*. Con la teoría del teclado probé i8042.reset i8042.nopnp. Se ejecutan dentro de la ruta de reanudación de s2idle y cuelgan la máquina entera — estrictamente peor que el fallo original. Nunca fue el teclado; el teclado estaba aguas abajo del modeset lock.
  • No pongas mei / mei_me en la lista negra. Se enlaza a i915 como mei_gsc_proxy, lo que lo sitúa aguas abajo de la GPU, no como causa. Ponerlo en la lista negra movió el fallo de sitio y no arregló nada.

Un año y más de 300 apagados forzados para una sola línea, y la línea ni siquiera fue la que publiqué primero. Así son las cosas a veces.


Si esto no lo arregla

enable_psr=0 acaba con la clase de cuelgue del PSR. No acaba con todos los fallos de reanudación de esta plataforma, y yo todavía persigo uno.

Compara tus logs antes que tus síntomas. Si el cuelgue al reanudar viene con los errores de PHY A y flip_done de arriba, estás en el fallo del que trata este artículo. Si lo que se te muere es el escritorio y todos los dispositivos de entrada a la vez mientras el kernel sigue funcionando con normalidad — SSH responde, el disco sincroniza — y dmesg no muestra ni un solo *ERROR* de ningún driver, eso es otra cosa completamente distinta. El mío resultó estar en la capa de sesión. En todos los ciclos fallidos que capturé, logind no pausó el dispositivo DRM de la iGPU al suspender, y al reanudar le mandó igualmente la orden de reanudar. Xorg no reaccionó a esa orden y siguió haciendo modeset sin ser DRM master, cosa que falla. El kernel no es la variable: el kernel LTS 6.18 falla exactamente igual que el 7.2. Está abierto arriba en systemd#43352, y no está arreglado.

Para este tampoco hace falta el botón de encendido. Alt+PetSis+k (SAK) mata todo lo que cuelga de la consola activa, es decir, la sesión de X congelada y nada más. Con mi autologin, la sesión nueva estaba lista en un segundo; con un gestor de pantalla deberías volver a su pantalla de login. Los servicios del sistema siguen funcionando. logind también muere, porque tiene la consola abierta, pero se reinicia solo en un segundo. Las ventanas abiertas se pierden, porque mueren con X. Si quieres, prueba antes v unos segundos; no cuesta nada, pero a mí no me devolvió la sesión.

Un dmesg limpio es evidencia, no silencio. Tardé una cantidad vergonzosa de tiempo en tratarlo como tal.


Referencias

Compartir artículo

AS

Angel Sulev

Cybersecurity + Agentic AI Expert

Especialista senior en ciberseguridad e IA Agéntica con 30+ años transformando la seguridad en ventaja competitiva para empresas visionarias.

Más sobre mí

Artículos Relacionados