SR-IOV vs Passthrough: cuándo IOMMU ayuda (y cuándo no)

¿Te fue útil?

Unos días tu NIC “virtualizada” consume 2% de CPU y entrega 25 Gbps como un campeón. Otros días pierde paquetes bajo carga, la latencia p99 parece un sismógrafo, y alguien sugiere “simplemente activa SR-IOV” como si fuera un solvente universal.

Esta es la versión adulta de esa conversación: qué te ofrecen realmente SR-IOV y el passthrough, qué hace en realidad la IOMMU, y las formas específicas en que puedes empeorar el rendimiento mientras te felicitas por “ir más cerca del hardware”.

El modelo mental: PFs, VFs, DMA y por qué existe la IOMMU

Definamos términos como lo hace tu kernel, no como lo hacen las presentaciones comerciales.

Passthrough (VFIO) en un párrafo

El passthrough PCI asigna una función PCIe completa a una VM (o carga tipo contenedor) para que el invitado sea el propietario del dispositivo. En Linux/KVM esto suele ser VFIO: el host enlaza el dispositivo a vfio-pci, y QEMU lo mapea dentro del invitado. El dispositivo realiza DMA hacia la memoria del invitado, y la IOMMU (si está activada) aplica que el DMA se mantenga dentro de lo que el invitado puede tocar.

SR-IOV en un párrafo

SR-IOV divide una función PCIe física (PF) en múltiples funciones PCIe ligeras (VFs). Cada VF parece un dispositivo PCI distinto con su propio espacio de configuración, BARs y colas (depende de la implementación), por lo que puedes entregar VFs individuales a invitados. La PF queda gestionada por el host (o a veces por una “VM de servicio”), y la VF es “principalmente hardware”, con perillas de política expuestas a través del driver de la PF y el firmware.

Dónde encaja el DMA, y por qué debería importarte

Tanto SR-IOV como el passthrough tratan de una cosa: quién puede ejecutar DMA y cuán caro es hacerlo de forma segura. Los dispositivos no “envían paquetes”; hacen DMA de descriptores y cargas útiles hacia/desde memoria. Si un dispositivo puede hacer DMA a cualquier lugar, puede leer tus secretos, garabatear en tu kernel y convertir la fiabilidad en danza interpretativa.

Esto es el trabajo de la IOMMU: traducir y limitar las direcciones DMA del dispositivo, similar a cómo la MMU de la CPU limita la memoria de un proceso. Sin IOMMU, los dispositivos “asignados” todavía pueden hacer DMA en la memoria del host si fallas en el aislamiento. Con IOMMU, pagas un coste de traducción (a veces pequeño, a veces no), pero obtienes contención real y características como el remapeo de interrupciones.

Regla práctica: si haces passthrough en producción y no usas una IOMMU, no eres “valiente”, simplemente estás corriendo con un modelo de amenazas distinto al que crees.

Broma #1: La IOMMU es como el portero de un club nocturno para el DMA. No evita malas decisiones adentro, pero mantiene fuera a los extraños aleatorios.

Qué significa realmente “rendimiento” aquí

La gente dice “SR-IOV es más rápido que virtio.” A veces. Pero necesitas especificar en qué eje de rendimiento:

  • Rendimiento (Throughput) (Gbps o IOPS) con un presupuesto de CPU dado
  • Latencia en la cola (p99/p999), especialmente bajo contención
  • Jitter (variación), que rompe aplicaciones casi en tiempo real
  • Eficiencia de CPU (ciclos por paquete/IO)
  • Rendimiento operativo (qué tan rápido puedes depurar y restaurar servicio)

SR-IOV y passthrough pueden ser fantásticos para throughput y eficiencia de CPU. También pueden empeorar la latencia en las colas si manejas mal las interrupciones, no fijas afinidades y dejas que el planificador del host improvise.

SR-IOV vs passthrough: las verdaderas compensaciones

Aquí la versión opionada:

  • Si necesitas que una VM posea un dispositivo de forma completa (GPU, FPGA, HBA): usa passthrough. SR-IOV no siempre está disponible, y aun cuando lo esté, la paridad de características es desigual.
  • Si necesitas que muchos invitados obtengan rendimiento de NIC cercano al metal: usa SR-IOV, pero trata la gestión de VFs como parte de tu plataforma, no como un hobby por VM.
  • Si necesitas flexibilidad (migración en caliente, snapshots, hosts heterogéneos): prefiere virtio y acepta el coste de CPU, a menos que tengas una razón probada para no hacerlo.

Seguridad y aislamiento: no cuentan la misma historia

Con passthrough, el invitado obtiene el dispositivo completo. Eso es estupendo para rendimiento y acceso a funciones, y terrible para compartir. El aislamiento depende mucho de la corrección de la IOMMU y del comportamiento del dispositivo. Con SR-IOV compartes un dispositivo físico entre inquilinos, y el aislamiento depende de la implementación de VF de la NIC (separación de colas, limitación de tasa, comprobaciones anti-spoof) además del driver de la PF. Algunas VFs pueden hacer cosas que no deberían si dejas activadas banderas tipo “trust”.

Guía práctica:

  • SR-IOV multi-inquilino es viable, pero debes configurar explícitamente el chequeo anti-spoof de VF, la aplicación de VLAN y los ajustes de trust en la PF.
  • Passthrough para invitados no confiables está fuertemente ligado a IOMMU y remapeo de interrupciones. Si falta cualquiera, estás aceptando riesgo.

Operaciones: SR-IOV gana hasta que deja de ganar

SR-IOV parece operacionalmente “simple” porque puedes repartir VFs como caramelos. Luego aparecen las complejidades ocultas:

  • Provisionamiento de VFs y recolección de basura en reinicios
  • Incompatibilidades firmware/driver que solo fallan bajo ciertos conteos de colas
  • Brechas de observabilidad (las herramientas del host ven estadísticas de PF; el invitado ve estadísticas de VF; nadie ve “end-to-end”)
  • Dirección de paquetes y afinidad de IRQ que se vuelven requisito de plataforma

Passthrough es más simple en el sentido de que un invitado posee el dispositivo y depuras una sola pila. Es más difícil en el sentido de que pierdes muchas comodidades de la virtualización (migración, instantáneas, sobresuscripción) y puedes dejar inservible la red de un host si pasas la cosa equivocada.

El secreto sucio: ambos enfoques siguen necesitando higiene Linux aburrida

Fijado de CPU, alineación NUMA, afinidad de IRQ, dimensionado de anillos y decisiones sensatas de MTU siguen importando. SR-IOV no te salva de una VM que corre en el socket equivocado, y passthrough no te salva de un driver de invitado configurado como experimento científico.

Cuándo la IOMMU ayuda (y por qué)

1) Contención: el aislamiento DMA es el objetivo principal

Sin IOMMU, un dispositivo que haga DMA puede acceder a direcciones de memoria física que no pretendías. En passthrough, eso puede significar que un dispositivo controlado por el invitado (o la programación del dispositivo desde el invitado) pueda leer o corromper la memoria del host. Con IOMMU, el espacio de direcciones DMA (IOVA) se traduce mediante tablas que controla el host.

En SR-IOV, las VFs también hacen DMA. Si asignas VFs a invitados, aún quieres la IOMMU activada para confinar el DMA de la VF a la memoria del invitado. Sí, la NIC está “virtualizada”, pero sigue siendo un dispositivo que hace DMA.

2) Remapeo de interrupciones: menos formas de arruinar tu día

Las IOMMUs modernas también pueden remapear interrupciones (MSI/MSI-X) para que un dispositivo no inyecte interrupciones de formas extrañas. Eso importa cuando pasas dispositivos a invitados. Sin remapeo de interrupciones, puedes verte forzado a modos inseguros, o tendrás comportamiento inestable según el soporte de la plataforma.

3) Puedes activar funciones seguras que de otro modo serían peligrosas

Si haces asignación de dispositivos a escala, la IOMMU es la capa habilitadora para “este dispositivo solo toca lo que debe tocar”. Desbloquea hacer passthrough para cargas de trabajo reales, no solo para montajes de laboratorio.

4) Algunas rutas de rendimiento las asumen

Contrario a la intuición: a veces dejar la IOMMU desactivada dispara retrocesos del kernel, desactiva el remapeo de interrupciones o fuerza diferentes estrategias de mapeo DMA. En algunas plataformas, “IOMMU off” no es “modo rápido”, es “modo compatibilidad”. No eliges la aventura; tu placa base ya lo decidió.

Cuándo la IOMMU no ayuda (y puede perjudicar)

Ahora la parte que a la gente no le gusta oír: la IOMMU no es un interruptor mágico de rendimiento. Es una característica de seguridad con implicaciones de rendimiento. A veces esas implicaciones son despreciables. A veces son tu p99.

1) Redes de alta tasa con paquetes pequeños pueden amplificar la sobrecarga de traducción

Si tu carga son paquetes de 64 bytes a PPS muy altos, el coste de mapear/desmapear DMA, la presión de TLB en la IOMMU y los fallos de IOTLB pueden aparecer. Los buenos drivers amortizan costes de mapeo (mapeos de larga vida, hugepages, batching). Las configuraciones malas churnean mapeos y lo pagan.

2) Hugepages mal configuradas o fragmentación de memoria lo empeoran

Si la memoria que respalda al invitado está fragmentada, la IOMMU necesita más entradas de tabla de páginas, lo que aumenta la probabilidad de fallos de IOTLB. Con hugepages (y fijado correcto), reduces la huella de traducción. Por eso a veces “SR-IOV es más lento que virtio”: no es SR-IOV; es la estrategia de mapeo y la disposición de memoria.

3) Puedes perder funciones que asumías disponibles

Algunos entornos activan la IOMMU en un modo que rompe o desactiva DMA peer-to-peer (dispositivo a dispositivo), o cambia cómo funcionan ATS/PRI (cuando están presentes). Para stacks de almacenamiento que dependen de ciertos patrones DMA, puedes ver regresiones que parecen “bug de driver” pero son cambios de comportamiento de la traducción.

4) Depurar se complica porque los modos de fallo se multiplican

Cuando la IOMMU está involucrada, una falla puede ser:

  • bug del driver del invitado
  • bug de VFIO/QEMU en el host
  • bug/quirk de la IOMMU de la plataforma
  • desajuste de configuración de BIOS
  • extrañezas de agrupamiento ACS
  • comportamiento del firmware bajo carga

Broma #2: Activar IOMMU para “arreglar rendimiento” es como comprar una llave dinamométrica para arreglar una rueda pinchada. Herramienta útil, problema equivocado.

Hechos interesantes y contexto histórico

  • Las IOMMU preceden al hype de la nube. Aparecieron en varias formas para resolver límites de direccionamiento DMA y aislamiento mucho antes de que “multi-tenant” fuera un pitch comercial.
  • El direccionamiento DMA solía ser una limitación real. Los primeros sistemas tenían dispositivos que solo podían DMA en rangos de direcciones limitados; las IOMMUs ayudaron remapeando las direcciones visibles para el dispositivo.
  • Intel VT-d y AMD-Vi hicieron la asignación de dispositivos mainstream. El remapeo DMA de hardware se convirtió en una característica estándar para servidores que querían virtualización seria.
  • MSI-X cambió el juego para NICs de alto rendimiento. Múltiples vectores de interrupción permitieron diseños de cola-por-core, en los que SR-IOV confía en gran medida.
  • SR-IOV es un estándar de PCI-SIG. No es magia del proveedor, aunque las implementaciones de los proveedores varían enormemente en calidad y controles.
  • “Grupos IOMMU” tratan sobre límites de aislamiento. El agrupamiento refleja lo que el hardware puede aislar; no es una invención de Linux, es Linux exponiendo la realidad.
  • ACS fue el héroe incómodo. Access Control Services influyen cómo los dispositivos se aíslan detrás de switches PCIe; la falta de ACS puede forzar grupos IOMMU más grandes.
  • Virtio maduró porque las operaciones lo exigieron. Virtio no es solo “emulación más lenta”. Evolucionó en una interfaz paravirtual sólida y depurable que encaja con operaciones en la nube.
  • DPDK y la red en espacio de usuario elevaron expectativas. Una vez que la gente vio line rate en espacio de usuario, exigieron comportamiento similar en VMs, lo que empujó la adopción de SR-IOV.

Guía de diagnóstico rápido

El objetivo es encontrar el cuello de botella rápido, no “entender PCIe por completo”. Eso puede esperar.

Primero: confirma qué desplegaste realmente

  1. ¿La carga usa virtio, VF SR-IOV o passthrough completo?
  2. ¿La IOMMU está activada y funcionando (no solo “activada en BIOS”)?
  3. ¿Se remapean las interrupciones y está habilitado MSI-X?

Segundo: localiza el dominio de contención

  1. Alineación NUMA: ¿la VM está en el mismo socket que el dispositivo PCIe?
  2. Afinidad de IRQ: ¿las interrupciones están fijadas a CPUs apropiadas?
  3. Número de colas: ¿tienes suficientes colas, o demasiadas?

Tercero: decide si estás limitado por CPU, IRQ o DMA/IOMMU

  1. Si la CPU está al tope en softirq/ksoftirqd: es procesamiento de paquetes e interrupciones/steering.
  2. Si la CPU está bien pero la p99 es mala: revisa migración de IRQ, estados de energía y churn de IOTLB.
  3. Si el throughput está capado sospechosamente: verifica velocidad/ancho del enlace, negociación de PCIe y offloads.

Cuarto: demuéstralo con un experimento dirigido

  • Fija vCPUs y memoria al nodo NUMA del dispositivo, vuelve a probar.
  • Cambia afinidad de IRQ para colas VF, vuelve a probar.
  • Alterna hugepages (o 2M vs 1G) en un host, vuelve a probar.

No cambies cinco variables y declares victoria. Así se crea folklore.

Tareas prácticas: comandos, salidas y decisiones

Estos son los chequeos que realmente ejecuto cuando alguien dice “SR-IOV va lento” o “passthrough es inestable”. Cada tarea incluye la decisión que tomo según la salida.

Task 1: Confirmar que IOMMU está habilitada en el kernel

cr0x@server:~$ dmesg | egrep -i 'iommu|vt-d|amd-vi|dmari' | head -n 25
[    0.142311] DMAR: IOMMU enabled
[    0.142355] DMAR: Host address width 46
[    0.142360] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.381200] DMAR-IR: Enabled IRQ remapping in x2apic mode

Qué significa: Tienes remapeo DMA (DMAR: IOMMU enabled) y remapeo de interrupciones (DMAR-IR).

Decisión: Si no ves estas líneas, no finjas que existe aislamiento de passthrough. Arregla BIOS/args del kernel antes de diagnosticar rendimiento.

Task 2: Verificar cmdline del kernel para modo IOMMU y trampas comunes

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.8.0 root=/dev/mapper/vg0-root ro quiet intel_iommu=on iommu=pt mitigations=auto

Qué significa: intel_iommu=on la habilita; iommu=pt usa mapeos de passthrough para dispositivos del host (a menudo reduce sobrecarga para dispositivos no asignados).

Decisión: Para cargas mixtas, iommu=pt suele ser sensato. Si depuras aislamiento, puedes quitarlo temporalmente para ver si cambia el comportamiento—pero documenta por qué.

Task 3: Identificar si usas VFs SR-IOV o dispositivos completos

cr0x@server:~$ lspci -D | egrep -i 'ethernet|network' | head
0000:3b:00.0 Ethernet controller: Intel Corporation Ethernet Controller XXV710 for 25GbE SFP28
0000:3b:02.0 Ethernet controller: Intel Corporation Ethernet Virtual Function
0000:3b:02.1 Ethernet controller: Intel Corporation Ethernet Virtual Function

Qué significa: La PF es 3b:00.0, y las VFs existen en 3b:02.x.

Decisión: Si esperabas SR-IOV pero solo ves PFs, no estás usando SR-IOV; estás depurando la cosa equivocada.

Task 4: Confirmar el conteo de VFs creadas en la PF

cr0x@server:~$ sudo cat /sys/class/net/enp59s0f0/device/sriov_numvfs
8

Qué significa: La PF tiene 8 VFs habilitadas actualmente.

Decisión: Si es 0, no existen VFs. Si es mayor que lo planeado, puedes estar agotando recursos de la PF (colas, TCAM, interrupciones). Reduce el conteo de VFs y vuelve a probar estabilidad.

Task 5: Comprobar grupos IOMMU para límites de aislamiento

cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group $(basename $g):"; ls -1 $g/devices; done | sed -n '1,40p'
Group 12:
0000:3b:00.0
0000:3b:00.1
Group 13:
0000:3b:02.0
0000:3b:02.1

Qué significa: Dispositivos en el mismo grupo no pueden aislarse de forma segura entre sí por la plataforma.

Decisión: Si tu dispositivo objetivo comparte un grupo con algo que no puedes pasar (como un controlador de almacenamiento), no uses passthrough en ese diseño de host. Arregla la topología PCIe o acepta virtio.

Task 6: Comprobar qué driver está enlazado (lado host)

cr0x@server:~$ lspci -nnk -s 0000:3b:02.0
3b:02.0 Ethernet controller [0200]: Intel Corporation Ethernet Virtual Function [8086:154c]
	Subsystem: Intel Corporation Device [8086:0000]
	Kernel driver in use: vfio-pci
	Kernel modules: iavf

Qué significa: VF está enlazada a VFIO para passthrough; el módulo driver nativo de VF existe pero no está activo en el host.

Decisión: Si esperabas red del host vía VF, ver vfio-pci es correcto. Si esperabas que el host lo usara, esto es tu mala configuración.

Task 7: Verificar que la VM realmente tiene el dispositivo adjunto (QEMU/libvirt)

cr0x@server:~$ sudo virsh domiflist vm-netperf-01
Interface  Type     Source     Model   MAC
-------------------------------------------------------
vnet0      bridge   br0        virtio  52:54:00:aa:bb:cc

Qué significa: Esta VM sigue usando virtio en un bridge, no SR-IOV VF passthrough.

Decisión: Deja de debatir afinado de SR-IOV. Primero adjunta el dispositivo VF y confirma los cambios de driver dentro del invitado.

Task 8: Comprobar velocidad/ancho negociado PCIe (cap común silencioso)

cr0x@server:~$ sudo lspci -s 3b:00.0 -vv | egrep -i 'LnkSta:|LnkCap:' | head -n 4
LnkCap:	Port #0, Speed 8GT/s, Width x8
LnkSta:	Speed 8GT/s, Width x4

Qué significa: La tarjeta soporta x8 pero está funcionando a x4. Eso es un problema físico/topológico/BIOS, no un bug de driver.

Decisión: Si los límites de throughput alinean con x4, mueve la tarjeta, cambia el riser o arregla la bifurcación de lanes en BIOS. No afines colas para solucionar lanes faltantes.

Task 9: Comprobar localidad NUMA del dispositivo PCI

cr0x@server:~$ cat /sys/bus/pci/devices/0000:3b:00.0/numa_node
1

Qué significa: El dispositivo está atado al nodo NUMA 1.

Decisión: Coloca las vCPUs y la memoria de la VM en el nodo 1. Si no puedes, acepta latencia más alta y menor throughput, o mueve el dispositivo al otro socket.

Task 10: Encontrar IRQs de colas VF y ver dónde caen

cr0x@server:~$ grep -E 'enp59s0f0v0|iavf|vfio|msi' /proc/interrupts | head -n 8
 178:     120433          0          0          0  IR-PCI-MSI 524288-edge      vfio-msi[0]
 179:     118901          0          0          0  IR-PCI-MSI 524289-edge      vfio-msi[1]
 180:     119552          0          0          0  IR-PCI-MSI 524290-edge      vfio-msi[2]

Qué significa: Todas las interrupciones están golpeando la CPU0 (primera columna) porque la afinidad no está configurada, o irqbalance hizo una elección “creativa”.

Decisión: Fija IRQs a CPUs locales a la NIC, y idealmente reparte colas entre cores aislados. Luego vuelve a probar la latencia p99.

Task 11: Comprobar estado de irqbalance (puede ayudar o perjudicar)

cr0x@server:~$ systemctl status irqbalance --no-pager
● irqbalance.service - irqbalance daemon
     Loaded: loaded (/lib/systemd/system/irqbalance.service; enabled)
     Active: active (running) since Mon 2026-02-02 09:14:12 UTC; 1 day ago

Qué significa: irqbalance está en ejecución y puede mover IRQs dinámicamente.

Decisión: Para cargas sensibles a la latencia SR-IOV/passthrough, considera deshabilitar irqbalance y fijar afinidad explícitamente—especialmente en hosts con aislamiento de CPU.

Task 12: Comprobar configuración de hugepages (host)

cr0x@server:~$ grep -i huge /proc/meminfo | head -n 6
HugePages_Total:    2048
HugePages_Free:     1980
HugePages_Rsvd:       12
Hugepagesize:       2048 kB
Hugetlb:         4194304 kB

Qué significa: Hay hugepages de 2M disponibles y mayormente libres.

Decisión: Si persigues sobrecarga IOMMU/IOTLB, las hugepages son una palanca. Si HugePages_Free es bajo, podrías estar fragmentando o filtrando reservas; arregla antes de culpar a SR-IOV.

Task 13: Comprobar si la VM usa hugepages (libvirt)

cr0x@server:~$ sudo virsh dumpxml vm-netperf-01 | egrep -n 'memoryBacking|hugepages|locked'
112:  
113:    
114:    
115:  

Qué significa: La memoria de la VM está respaldada por hugepages y bloqueada (reduce churn de páginas y sorpresas).

Decisión: Si usas SR-IOV/passthrough y te importa la latencia en la cola, esto suele valer la pena. Si no puedes bloquear memoria, espera variabilidad bajo presión del host.

Task 14: Buscar fallos de IOMMU (te asombrarías)

cr0x@server:~$ dmesg | egrep -i 'DMAR:.*fault|IOMMU.*fault|AMD-Vi:.*Event' | tail -n 10
[12345.671234] DMAR: [DMA Read] Request device [3b:02.0] fault addr 0x7f3a1000 [fault reason 0x05] PTE Read access is not set

Qué significa: El dispositivo intentó hacer DMA fuera de los mapeos permitidos, o los mapeos se están derribando incorrectamente.

Decisión: Para. Esto no es un tema de afinado; es un tema de corrección. Revisa versiones de VFIO/QEMU, bugs de drivers y si estás hot-unplugging dispositivos de forma insegura.

Task 15: Comprobar offloads de NIC dentro del invitado (las VFs SR-IOV varían)

cr0x@server:~$ sudo ethtool -k ens5 | egrep -i 'rx-checksumming|tx-checksumming|tso|gso|gro|lro'
rx-checksumming: on
tx-checksumming: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off

Qué significa: Los offloads están activados donde se espera; LRO está desactivado (a menudo bueno para latencia/observabilidad).

Decisión: Si offloads están inesperadamente off, pagarás CPU. Si están on pero ves trazas de paquetes raras, considera deshabilitar GRO para depurar—no como solución permanente.

Task 16: Verificar anti-spoofing y settings de trust de VF en la PF (host)

cr0x@server:~$ sudo ip link show enp59s0f0
2: enp59s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
cr0x@server:~$ sudo ip link show enp59s0f0 vf 0
vf 0 MAC 52:54:00:11:22:33, vlan 100, spoof checking on, link-state auto, trust off, query_rss on

Qué significa: La VF tiene VLAN aplicada, chequeo anti-spoof activado, trust desactivado. Es un buen valor por defecto para entornos compartidos.

Decisión: Si aparece trust on “porque arregló algo”, exige una razón concreta y añade controles compensatorios. Trust tiende a propagarse como moho.

Task 17: Confirmar governor/frecuencia CPU (causa común de latencia en cola)

cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
powersave

Qué significa: La CPU puede bajar frecuencia agresivamente, dañando la p99.

Decisión: Para hosts dataplane de alto rendimiento, usa el governor performance o tuning de plataforma apropiado. Si no puedes, deja de esperar latencia determinista.

Task 18: Comprobar presión de softirq (salud del dataplane de red)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server)  02/04/2026  _x86_64_  (32 CPU)

02:11:01 PM  CPU   %usr %nice %sys %iowait %irq %soft %steal %idle
02:11:02 PM  all   12.5  0.0   9.8    0.0   2.1  18.7    0.0   56.9

Qué significa: Alto %soft sugiere procesamiento heavy de softirqs; común en cargas con muchos paquetes.

Decisión: Añade colas/cores, mejora afinidad IRQ/RPS/XPS, o mueve a SR-IOV/DPDK si virtio es el cuello de botella. Si ya estás en SR-IOV, esto apunta a steering y colocación de CPU.

Tres mini-historias corporativas desde el campo

Mini-historia 1: El incidente causado por una suposición equivocada

Estaban desplegando passthrough de NIC para un servicio sensible a latencia. El pitch era claro: “elimina el switch virtual, reduce overhead, baja la p99.” El host de prueba se veía bien. El canario se veía bien. Entonces la producción se volvió… embrujada.

Un cluster empezó a reiniciarse bajo carga. No todos los nodos. Solo los de una fila de rack concreta. Los logs mostraban fallos DMA esporádicos y a veces un bloqueo duro sin pánico limpio del kernel. La primera suposición del equipo fue la habitual: “bug del driver.” Actualizaron drivers invitados. Actualizaron QEMU. Alternaron offloads. Las apariciones continuaron.

La suposición equivocada fue creer que “IOMMU habilitada en BIOS” significaba “IOMMU realmente funciona end-to-end”. En los nodos afectados, la opción de BIOS estaba presente pero la plataforma venía con remapeo de interrupciones deshabilitado por una versión de firmware más antigua. Linux activó remapeo DMA pero no pudo activar remapeo de interrupciones limpiamente en esa revisión de hardware.

Habían pasado un dispositivo que generaba MSI-X en masa bajo carga máxima, y sin garantías de remapeo correcto, la plataforma se comportó de forma impredecible. No era que la IOMMU “estuviera apagada”; era que una parte crítica de ella no estaba fiable.

La solución fue aburrida: estandarizar perfiles de BIOS, añadir una puerta de arranque que falle el nodo si DMAR-IR no está habilitado, y rechazar programación de passthrough en esos hosts. El rendimiento mejoró después, pero el incidente terminó porque dejaron de mentirse sobre las capacidades de la plataforma.

Mini-historia 2: La optimización que salió mal

Otra compañía ejecutaba VFs SR-IOV para cargas de alto throughput. Alguien notó que la sobrecarga de traducción IOMMU podría contribuir al coste de CPU en PPS extremos. Encontraron iommu=pt y decidieron “optimizar” más: deshabilitar la IOMMU para el host, porque “los invitados sólo tienen VFs y la NIC ya los aísla”.

Al principio pareció una victoria. Microbenchmarks mejoraron ligeramente y los gráficos de CPU se veían más bonitos. Luego la carga real golpeó: corrupción de datos esporádica dentro de un servicio respaldado por almacenamiento que también usaba otro dispositivo passthrough en algunos nodos. No en todos—solo donde la programación alineó una combinación particular de asignación de dispositivos y presión de memoria.

Sin IOMMU, un dispositivo mal comportado (o una interacción bug del sistema) podía DMA en memoria que no debía. La corrupción no era ruidosa. Fue sutil: fallos de checksum raros, crashes ocasionales de procesos, transiciones de estado “imposibles”. El peor tipo de outage: el que hace dudar de las leyes de la física.

Revirtieron el cambio y la corrupción cesó. El postmortem no fue amable: la optimización perseguía una sobrecarga teórica mientras eliminaba la barandilla de seguridad. El coste de la “ganancia” fueron días de respuesta a incidentes, revisiones de riesgo y una nueva política: IOMMU se queda activada; si el rendimiento es un problema, arregla la estrategia de mapeo (hugepages, pinning) o cambia el diseño del dataplane.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Un equipo de plataforma tenía una flota mixta: algunos hosts para virtualización genérica (virtio en todas partes), y una pool más pequeña para SR-IOV de alto rendimiento y passthrough ocasional de GPU. Tenían reputación de ser terriblemente estrictos sobre perfiles de host.

Cada arranque ejecutaba una lista de verificación: validar IOMMU habilitada, validar remapeo de interrupciones, validar ancho de enlace NIC, validar versiones de firmware contra una whitelist, validar conteo de VFs, validar restricciones de localidad NUMA. Si alguna comprobación fallaba, el nodo se drenaba automáticamente. Sin heroísmos. Sin negociación.

Un día, llegó un lote de servidores con una sutil diferencia de topología PCIe. La NIC negoció x4 en lugar de x8 en una configuración de ranura. Nada “se rompió”. Ninguna alerta del driver de NIC saltó. Las aplicaciones simplemente se volvieron más lentas de una forma que parecía “pico de tráfico”.

La puerta de arranque lo detectó: LnkSta no coincidía con lo esperado. Los nodos nunca entraron en la pool SR-IOV. Las cargas se quedaron en hosts sanos, y el único “incidente” fue un ticket a ops del datacenter para mover las tarjetas a las ranuras correctas.

La práctica que los salvó no fue un tweak ingenioso del kernel. Fue la negativa a aceptar degradación silenciosa. La ingeniería de fiabilidad es, en gran parte, decidir qué no tolerarás.

Errores comunes: síntomas → causa raíz → solución

1) Síntoma: “Passthrough está habilitado, pero el rendimiento es peor que virtio”

Causa raíz: La VM está en NUMA remoto respecto al dispositivo; interrupciones caen en CPUs incorrectas; memoria no fijada; churn de IOTLB por memoria fragmentada.

Solución: Alinea vCPUs y memoria al nodo NUMA de la NIC, habilita hugepages + memoria bloqueada, fija afinidad IRQ, ajusta número de colas para empatar con cores.

2) Síntoma: “La VF SR-IOV pierde enlace aleatoriamente o se bloquea bajo carga”

Causa raíz: Bug del driver/firmware de PF desencadenado por conteo de VFs, conteo de colas o combinación de offloads; a veces exacerbado por resets.

Solución: Actualiza firmware de NIC + driver de PF; reduce VFs/colas; evita combos exóticos de offloads; añade health checks que recrean VFs en fallo.

3) Síntoma: “Adjuntar VFIO falla: el dispositivo está ocupado / no puede resetear”

Causa raíz: El dispositivo está enlazado al driver del host o forma parte de un grupo con otras funciones en uso; limitaciones de FLR/reset.

Solución: Desenlaza correctamente, asegura aislamiento por grupo IOMMU, evita pasar dispositivos sin semántica de reset fiable, o usa SR-IOV en lugar de eso.

4) Síntoma: “Los grupos IOMMU son enormes; no puedo aislar la NIC”

Causa raíz: La topología PCIe carece de ACS, o los dispositivos comparten componentes ascendentes que no pueden aplicar aislamiento.

Solución: Cambia ranura/topología, usa hosts con switches ACS-capables, o deja de intentar passthrough seguro en esa plataforma.

5) Síntoma: “Alta latencia p99 solo durante contención en el host”

Causa raíz: Escalado de frecuencia CPU, migración de IRQ, reclaim de memoria, o vecinos ruidosos en el mismo socket.

Solución: Aislamiento CPU para cores del dataplane, governor performance, deshabilitar irqbalance (o configurarlo), reservar hugepages, bloquear memoria, establecer políticas NUMA reales.

6) Síntoma: “Paquetes se pierden en el invitado, el host parece bien”

Causa raíz: Hambruna de colas VF, tamaños de ring insuficientes, moderación de interrupciones demasiado agresiva, o driver del invitado mal ajustado.

Solución: Aumenta tamaños de ring, ajusta coalescing, asegura vectores MSI-X, asegura suficientes colas, fija vCPUs y valida versión del driver del invitado.

7) Síntoma: “Seguridad dice que SR-IOV es inseguro”

Causa raíz: Políticas de trust/spoof/VLAN de VF dejadas permisivas; malentendido del riesgo de hardware compartido.

Solución: Aplica políticas de VF en la PF, restringe características por inquilino, audita asignación de dispositivos, asegura IOMMU activada y documenta el modelo de amenazas.

Listas de verificación / planes paso a paso

Lista A: Elegir SR-IOV vs passthrough (toma de decisiones, no sensaciones)

  1. ¿Necesitas compartir el dispositivo entre muchos invitados? SR-IOV. Si el dispositivo no soporta bien SR-IOV, replantea el hardware.
  2. ¿Necesitas características completas del dispositivo (GPU, modos avanzados HBA, herramientas del proveedor)? Passthrough.
  3. ¿Necesitas migración en vivo/snapshots? Prefiere virtio. SR-IOV/passthrough complican o bloquean esto.
  4. ¿Tolerancia al riesgo multi-inquilino baja? Passthrough con IOMMU y chequeos de plataforma estrictos, o evita asignación de dispositivos.
  5. Madurez operativa: Si no puedes estandarizar BIOS/firmware/versiones del kernel, no hagas asignación de dispositivos a escala.

Lista B: Plan de despliegue SR-IOV (qué hacer en orden)

  1. Estandariza ajustes de BIOS (VT-d/AMD-Vi on, SR-IOV on, configuraciones PCIe consistentes).
  2. Estandariza cmdline del kernel y valida vía puertas dmesg.
  3. Elige un conteo de VFs por PF basado en límites de hardware y necesidades de colas (no lo rellenes por defecto).
  4. Define política de VF: spoof checking on, trust off por defecto, política de VLAN explícita.
  5. Define política de colocación NUMA para hosts SR-IOV y hazla cumplir vía scheduler.
  6. Implementa estrategia de afinidad IRQ; no confíes en la suerte.
  7. Canary bajo patrones reales de tráfico (PPS + tamaños de paquete + conteo de flujos).
  8. Observa p99/p999, drops, resets y fallos IOMMU; avanza solo cuando sea aburrido.

Lista C: Plan de despliegue Passthrough (no quemes tu host)

  1. Verifica que IOMMU y remapeo de interrupciones estén habilitados y estables tras reinicios.
  2. Verifica grupos IOMMU y asegura que el dispositivo pueda aislarse.
  3. Verifica soporte de reset del dispositivo (FLR o comportamiento de reset del proveedor) funciona de forma fiable.
  4. Enlaza dispositivo a vfio-pci y confirma que servicios del host no lo necesitarán.
  5. Fija vCPUs y memoria de la VM al nodo NUMA del dispositivo; usa hugepages si te importa jitter.
  6. Instrumenta: recopila fallos IOMMU en dmesg, errores PCIe AER y métricas de distribución de interrupciones.
  7. Tener rollback: desacoplar el dispositivo, volver a enlazar al driver del host, restaurar rutas de red/almacenamiento.

Preguntas frecuentes

1) ¿SR-IOV siempre es más rápido que virtio?

No. SR-IOV suele reducir CPU por paquete y mejorar throughput, pero puede perder en latencia en cola si IRQ/NUMA/mapeo de memoria están descuidados. Virtio puede ser “suficientemente rápido” y mucho más fácil de operar.

2) ¿El passthrough siempre es la opción más rápida?

A menudo para propiedad de dispositivo single-tenant, sí. Pero “más rápido” depende de colocación y manejo de interrupciones. Un dispositivo passthrough en NUMA remoto puede ser más lento que una ruta virtio bien afinada.

3) ¿Necesito IOMMU para SR-IOV?

Si asignas VFs a invitados, quieres IOMMU para aislamiento DMA. Si mantienes todo en el host, tiene menos que ver con aislamiento—pero muchas plataformas siguen comportándose mejor con una configuración IOMMU consistente.

4) ¿Qué hace realmente iommu=pt?

Típicamente configura mapeos identidad/passthrough para dispositivos del host para que no paguen sobrecarga de traducción, mientras permite mapeos traducidos para dispositivos asignados. Es un compromiso común entre rendimiento y seguridad.

5) ¿Por qué mis grupos IOMMU son “demasiado grandes”?

Porque tu hardware no puede aislar esos dispositivos entre sí. La topología PCIe y el soporte ACS determinan el agrupamiento. Linux reporta el límite en el que confía, no el que desearías tener.

6) ¿Puedo migrar en caliente una VM que usa SR-IOV o passthrough?

No en la forma habitual de “simplemente funciona”. La asignación de dispositivo liga la VM a un estado de hardware específico. Algunos ecosistemas tienen enfoques especializados de migración, pero trátalo como un proyecto especial, no como una casilla para marcar.

7) ¿Cuál es la causa principal de reportes “SR-IOV es inestable”?

Incompatibilidad firmware/driver y sobrecommit de recursos en la NIC (demasiadas VFs, demasiadas colas, settings demasiado agresivos). La segunda causa es operacional: VFs no recreadas consistentemente tras reinicio o eventos de enlace.

8) ¿La IOMMU añade latencia medible?

Puedes verla, especialmente cuando los mapeos churnean o los fallos de IOTLB aumentan. Con memoria fijada, hugepages y mapeos estables, la sobrecarga a menudo es pequeña comparada con el resto del dataplane.

9) ¿Debería deshabilitar irqbalance en hosts SR-IOV/passthrough?

Para cargas sensibles a latencia, sí—a menos que hayas configurado irqbalance explícitamente para respetar aislamiento y localidad. La migración dinámica de IRQ y una p99 determinista no son amigas.

10) ¿Cuál es la arquitectura “segura por defecto” más simple?

Virtio para cómputo general, una pool separada SR-IOV para cargas de rendimiento, y passthrough solo para dispositivos que realmente requieran propiedad completa. Mantén perfiles de host estrictos y validados.

Siguientes pasos prácticos

Toma la decisión basada en tu realidad operativa, no en la captura de pantalla de tu benchmark.

  1. Elige una línea base: Si actualmente usas virtio, primero consigue higiene NUMA/IRQ limpia. Si no, no sabrás qué mejoró SR-IOV.
  2. Activa IOMMU correctamente: Confirma remapeo DMA y remapeo de interrupciones en dmesg. Bloquea tu flota con esa condición.
  3. Elige el modelo adecuado: SR-IOV para aceleración NIC compartida, passthrough para propiedad single-tenant de dispositivo, virtio por flexibilidad.
  4. Operativiza: Estandariza firmware, BIOS, args del kernel, conteos de VF y política de seguridad de VF. Automatiza chequeos; drena en caso de desajuste.
  5. Mide lo correcto: Rastrea latencias p99/p999 y pérdidas, no solo throughput promedio. La mayoría de outages viven en las colas.

Una cita para pegar en un post-it, porque resume todo el trabajo: “La esperanza no es una estrategia.” — General Gordon R. Sullivan

← Anterior
Clúster Proxmox: por qué Corosync parece estar bien mientras tu clúster se degrada
Siguiente →
One‑liners de PowerShell que reemplazan 10 clics de la GUI (Úsalos a diario)

Deja un comentario