Qué hace el ASPM
La gestión de energía en estado activo (ASPM) de PCIe permite que los enlaces PCIe entren en estados de bajo consumo cuando están ociosos. La especificación PCIe define varios estados de enlace:
L0 es el estado plenamente activo. El enlace está levantado, ambos extremos alimentados, los datos pueden fluir de inmediato.
L0s es un estado ocioso ligero. El enlace se apaga parcialmente. La recuperación a L0 tarda alrededor de 1–4 µs según el hardware. Ambos extremos pueden entrar en L0s de forma independiente.
L1 es un estado ocioso más profundo. Ambos extremos del enlace se apagan juntos. La recuperación a L0 tarda más — típicamente 2–32 µs, a veces más. El tiempo exacto de recuperación depende del dispositivo, la generación PCIe y la plataforma.
L1.1 y L1.2 son subestados de L1 introducidos en PCIe 3.0. Reducen el consumo aún más apagando la referencia de reloj del PLL. La recuperación desde L1.2 puede tardar 32–100 µs. Para un dispositivo de almacenamiento eso no es un error de redondeo. Es más o menos lo que tardaba la lectura que intentabas hacer en primer lugar.
La idea es sencilla. Si un enlace PCIe está ocioso unos microsegundos, pásalo a un estado de menor consumo. Cuando el tráfico se reanuda, despiértalo. Ahorra algo de energía mientras tanto.
En un portátil o un equipo de sobremesa que pasa la mayor parte del tiempo sin hacer nada, el ASPM ahorra energía de verdad. Unos vatios por enlace, que suman a lo largo de todos los dispositivos PCIe del sistema. En un servidor con cargas intensivas de E/S, los enlaces rara vez están ociosos el tiempo suficiente para que el ASPM entre en juego de forma significativa.
Por qué causa problemas bajo passthrough
En hardware nativo, el sistema operativo y el controlador del dispositivo negocian juntos la gestión de energía. El controlador NVMe sabe cuándo el enlace va a quedar ocioso y cuándo va a enviar nueva E/S. El subsistema PCIe del kernel coordina las transiciones de estado del enlace con el controlador. Todo va sincronizado.
Bajo passthrough VFIO, esa coordinación se rompe.
El kernel del host sigue controlando el enlace PCIe físico. La VM invitada es dueña del dispositivo a través de VFIO, pero no controla el enlace en sí. El subsistema PCIe del host ve que el enlace queda ocioso — porque desde la perspectiva del host ningún controlador del lado host lo está usando. Pasa el enlace a un estado de bajo consumo. Cuando el invitado envía E/S, el dispositivo necesita el enlace de vuelta en L0. El tiempo de recuperación aparece como latencia añadida en esa operación de E/S.
El resultado es una latencia inconsistente.
La mayoría de las E/S se completan a velocidad normal.
Algunas tardan mucho más porque topan con un enlace que está en L1 o L1.2 y tiene
que despertar primero.
Esto aparece como una amplia dispersión en tus percentiles de clat (latencia de
finalización).
La media puede tener buena pinta.
El p99 puede ser 5–10 veces mayor.
Esto es difícil de detectar porque los números de rendimiento medio pueden tener buena pinta. Solo ves el problema cuando miras la latencia de cola. Muchos benchmarks no lo resaltan a menos que pidas la salida por percentiles.
La particularidad específica de VFIO
Hay aquí una particularidad que va más allá del problema básico de «el host y el invitado peleándose por el estado del enlace».
Cuando un dispositivo está enlazado a vfio-pci en el host, el kernel del host
sabe que el dispositivo está en modo passthrough.
Pero la política de ASPM de PCIe se aplica a nivel de enlace, no de dispositivo.
La política de ASPM del host sigue aplicándose al enlace físico porque el host
sigue siendo dueño de la topología PCIe.
VFIO no intercepta ni anula las transiciones de ASPM. Pasa a través del espacio BAR del dispositivo y las interrupciones, pero la gestión de energía del enlace permanece bajo control del host. El invitado no tiene ningún mecanismo para decirle al host «mantén este enlace en L0».
Algún hardware y algunas versiones del kernel más nuevas gestionan esto mejor que otras. Como tal, el enfoque más seguro es quitar el ASPM del cuadro por completo.
Cómo desactivarlo
Añade pcie_aspm=off a la línea de comandos del kernel del host:
# Edit /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet pcie_aspm=off"
# Update GRUB and reboot
update-grub
reboot
Esto impide que el host ponga cualquier enlace PCIe en un estado de bajo consumo. Se aplica globalmente. A todos los dispositivos PCIe del host, no solo al que se pasa por passthrough.
Verifica tras reiniciar:
# Should show "ASPM Disabled" for all devices
lspci -vv | grep -i "ASPM"
El coste en energía
Desactivar el ASPM sí aumenta el consumo en reposo. Cada enlace PCIe que de otro modo estaría en L1 se queda en L0, consumiendo unos cientos de milivatios más. A lo largo de un sistema con diez o quince dispositivos PCIe, eso podría sumar 2–5 vatios en reposo.
Para un servidor en un centro de datos, 2–5 vatios es un error de redondeo en la factura eléctrica. Para un homelab, es una fracción de lo que consumen la CPU y la memoria. Para un portátil, importa. Pero no harías passthrough VFIO con la batería de un portátil.
El compromiso está claro. Unos vatios de consumo en reposo frente a picos de latencia impredecibles en tus dispositivos pasados por passthrough. En cualquier sistema que haga passthrough, el ASPM debería estar desactivado.
Problemas de estado de energía a nivel de dispositivo
El ASPM controla el estado de energía del enlace PCIe. Los dispositivos también tienen su propia gestión de energía — los estados D de PCIe (D0 a D3).
Cuando un dispositivo está en D3 (totalmente apagado), no es solo el enlace lo que
duerme. El propio dispositivo se ha detenido.
Bajo passthrough VFIO, el controlador vfio-pci del host puede poner el
dispositivo en D3 cuando la VM no está en marcha o cuando la política de gestión
de energía del host decide que el dispositivo está ocioso.
Algunas controladoras NVMe no gestionan limpiamente la transición de D3 a D0. No vuelven limpiamente, el invitado pierde el dispositivo, y la única salida es reiniciar la VM o a veces reiniciar el host.
La Samsung 990 EVO Plus es una infractora conocida.
El arreglo es la opción de módulo disable_idle_d3 de vfio-pci:
# /etc/modprobe.d/vfio.conf
options vfio-pci disable_idle_d3=1
Esto impide que vfio-pci ponga en D3 cualquier dispositivo enlazado cuando está
ocioso.
Como pcie_aspm=off, es un ajuste global. Todo dispositivo enlazado a vfio-pci
se queda en D0.
Eso suele ser lo que quieres para el passthrough, donde el invitado debería ser
lo único que controle el estado de energía del dispositivo.
La opción disable_idle_d3 es independiente del ASPM.
El ASPM controla el enlace.
D3 controla el dispositivo.
Ambos pueden causar problemas de forma independiente.
Para una configuración de passthrough limpia, desactiva ambos.
Control de ASPM por dispositivo
Si no quieres desactivar el ASPM globalmente — quizá tengas otros dispositivos PCIe en el host que se beneficien del ahorro de energía — puedes controlar el ASPM por enlace vía sysfs:
# Find the link's ASPM policy
cat /sys/bus/pci/devices/0000:XX:00.0/link/l1_aspm
# Disable ASPM for a specific link
echo 0 > /sys/bus/pci/devices/0000:XX:00.0/link/l1_aspm
Esto es más quirúrgico pero menos fiable a través de reinicios y actualizaciones
del kernel.
Para la mayoría de montajes de passthrough, el parámetro global pcie_aspm=off
del kernel es más simple y más predecible.
Cuándo el ASPM no es el problema
No toda fluctuación de latencia es ASPM.
Si tus percentiles de clat son consistentemente altos (no solo la cola), es más
probable que el problema sea la sobrecarga de traducción del IOMMU, una mala
alineación NUMA o un desajuste de MPS.
El ASPM causa específicamente un patrón bimodal — la mayoría de las E/S rápidas,
unas pocas lentas — porque solo afecta a las E/S que llegan cuando el enlace está
en un estado de bajo consumo.
Comprueba el ASPM primero cuando veas:
- Latencia p99 5 veces o más por encima de la media
- Resultados de
fioinconsistentes entre ejecuciones - Latencia que mejora bajo carga sostenida pero empeora con cargas a ráfagas
Si la latencia es consistentemente mala sea cual sea el patrón de carga, mira en otra parte. Merece la pena descartar el ASPM pronto porque es barato de probar. No es la respuesta a todo enlace lento, eso sí, y perseguirlo cuando los números no encajan con el patrón es una tarde que no recuperarás.
Referencias
- Linux kernel PCI documentation — ASPM parameters — código fuente del kernel que cubre
pcie_aspm=offy opciones relacionadas - Proxmox Forum — PCI Passthrough NVMe Unable to Change Power State — hilo de la comunidad que cubre
disable_idle_d3para controladoras NVMe de Samsung - Proxmox VE Wiki — PCI(e) Passthrough — documentación oficial sobre la configuración del passthrough