Por qué los controladores serán aún más parte del juego

¿Te fue útil?

El incidente no comenzó con un obvio “disco falló” o “enlace abajo”. Empezó con un gráfico que se veía… somnoliento.
La latencia subió un poco. Luego un poco más. Entonces la capa API empezó a reintentar. Y a las 03:17, alguien dijo la frase que todo SRE odia: “Pero no cambió nada.”

Algo cambió. Es solo que el cambio vivía en la capa que nos gusta fingir que es aburrida: los controladores.
Controladores de almacenamiento. Controladores de red. Controladores de GPU. Controladores de virtualización. Controladores CSI. “Controladores” de firmware. Incluso el desorden adyacente a microcódigo.
La pila de producción moderna es una negociación entre capacidad de hardware, comportamiento del kernel y lo que el equipo de drivers supuso que querrías.

Los controladores son ahora una característica de producto, no la fontanería

En centros de datos antiguos, la “capa de drivers” era mayormente un traductor estable: el SO pide bytes, el controlador entrega bytes.
Sí, el rendimiento variaba, pero los controles eran pocos y los dominios de fallo eran nítidos: un disco, un cable, un controlador.
¿Hoy? El driver es política. Decide profundidades de cola, moderación de interrupciones, estados de energía, comportamiento de offload, semántica de reintentos,
timeouts, coalescencia, agrupamiento y qué telemetría existe siquiera.

Eso convierte a los drivers en “parte del juego” de la misma manera que los compiladores se volvieron parte del juego en ingeniería de rendimiento.
Ya no solo eliges hardware. Eliges un paquete hardware+firmware+driver+kernel+configuración.
Y o gestionas ese paquete de extremo a extremo, o él gestiona tu horario de sueño.

Esto no es teórico. Si ejecutas:

  • NVMe a escala (local o sobre fabrics),
  • Almacenamiento de bloque en la nube con multipath,
  • Kubernetes con plugins CSI,
  • Redes de alta velocidad (25/50/100/200G),
  • RDMA / RoCE,
  • DPDK, XDP, eBPF o offloads agresivos,
  • GPUs u otros aceleradores,
  • Virtualización con virtio o SR-IOV,

…entonces tus elecciones de drivers no son “detalles de implementación.” Son palancas operativas y riesgos operativos.

Una cita que sigue siendo molesta y cierta en operaciones, atribuida a John Allspaw, es la idea (parafraseada) de que
“los sistemas fallan de formas no previstas, porque el éxito requiere adaptación continua.”
Los drivers son donde mucha de esa adaptación se incorpora—a veces por ti, a veces por un proveedor, a veces por el kernel.

Chiste corto #1: Los drivers son como las sillas de oficina—nadie se preocupa hasta el día en que chirrían fuerte durante la demo ejecutiva.

Por qué esto está ocurriendo (las fuerzas aburridas que gobiernan tu vida)

1) El hardware se volvió rápido; el software se volvió sutil

Cuando un único dispositivo NVMe puede hacer cientos de miles de IOPS con latencias en microsegundos, el camino del SO se vuelve visible.
Interrupciones, afinidad de CPU, localidad NUMA, mapeo de colas y decisiones del scheduler se convierten en efectos de primer orden.
Los drivers son los guardianes de esos mecanismos.

2) Los dispositivos “inteligentes” movieron lógica al firmware y los drivers se convirtieron en el contrato

NICs y controladores de almacenamiento modernos son ordenadores. Ejecutan firmware que puede implementar offloads, políticas de caché,
control de congestión, cifrado, telemetría y lógica de reintentos. El driver es la API a ese mundo.
Y los desajustes firmware+driver son la versión adulta de “funciona en mi máquina.”

3) Virtualización y contenedorización multiplicaron las capas de traducción

Un único write puede atravesar: aplicación → libc → kernel → sistema de ficheros → capa de bloque → dm-crypt → dm-multipath →
virtio-blk → hypervisor → vhost → capa de bloque del host → driver HBA → objetivo del array de almacenamiento.
Cada salto tiene timeouts, colas y semánticas de fallo. Los drivers se sientan en múltiples puntos, y sus valores por defecto a menudo asumen
mundos más simples.

4) Las actualizaciones de kernel son ahora rutinarias, así que las regresiones de drivers también lo son

La seguridad y la velocidad de la plataforma han normalizado actualizaciones frecuentes del kernel. Eso es bueno. También significa que estás
cambiando constantemente rutas de código de drivers, a veces de maneras que solo se muestran bajo tu carga de trabajo.
Tu “plataforma estable” es estable solo si la pruebas debidamente.

5) La observabilidad se movió hacia capas más bajas

En sistemas de gran escala, las métricas a nivel de aplicación a menudo dicen “la latencia subió” pero no “por qué.”
La única forma de responder “por qué” rápido es ver por debajo de la app: capa de bloque, colas de dispositivo, comportamiento de interrupciones, problemas DMA,
retransmisiones TCP, marcas ECN en RDMA, y demás. Los drivers son tanto la fuente de esos datos como lo que estás diagnosticando.

6) Presión de costes: exprimir más del mismo hardware

La victoria presupuestaria más fácil es “usar lo que ya tenemos.” La segunda más fácil es “aumentar la utilización.”
Ambas se convierten en: ajustar drivers y parámetros del kernel, y aceptar márgenes de seguridad más estrechos.
Así es como la “optimización de rendimiento” se convierte en un proyecto de fiabilidad.

Chiste corto #2: La forma más rápida de encontrar un bug de driver es llamar a tu rotación on-call “bajo estrés.”

Hechos e historia: los controladores siempre importaron, solo que lo olvidamos

Algunos puntos de contexto que explican por qué hoy se siente diferente:

  1. Las pilas SCSI tempranas hicieron visible el encolamiento. Tagged Command Queuing introdujo concurrencia en la capa del dispositivo,
    y la profundidad de cola del driver se convirtió en un control de rendimiento mucho antes de que existiera NVMe.
  2. Linux 2.6 introdujo una gran evolución en los planificadores de I/O. CFQ y compañía respondieron a cargas mixtas,
    y los drivers tuvieron que cooperar con nuevas semánticas de scheduling.
  3. blk-mq cambió fundamentalmente la capa de bloque. El bloqueo multi-cola redujo la contención de locks y expuso
    decisiones de mapeo CPU/cola—los drivers se volvieron centrales para escalar.
  4. NVMe estandarizó un conjunto de comandos más simple, pero añadió paralelismo. Múltiples colas y profundas submissiones de comandos
    hicieron que la “localidad entre driver y CPU” importara más que la “sobrecarga del controlador.”
  5. SR-IOV convirtió los “límites de driver” en una decisión de arquitectura. Las funciones virtuales movieron partes de la NIC al
    invitado; un “problema de driver” podía ahora estar en el host, en el guest o en el firmware.
  6. RDMA revivió las suposiciones del transporte. Cuando evitas la pila de red del kernel, la corrección y configuración del driver
    se vuelven críticas para la fiabilidad, no solo para el rendimiento.
  7. CSI hizo que los drivers de almacenamiento formen parte de tu plano de control. El aprovisionamiento de volúmenes en Kubernetes pasó de “scripts ops”
    a “un driver ejecutándose en-cluster,” trayendo nuevos modos de fallo: elecciones de líder, limitación de API y RBAC.
  8. NVMe-oF convirtió a los drivers de red y almacenamiento en un solo problema. La latencia ahora es función tanto del target
    como del fabric, con drivers en ambos extremos.

Modos de fallo que verás con más frecuencia

Valores por defecto del driver optimizados para benchmarks, no para tu carga

Los proveedores envían valores por defecto que lucen bien en patrones de prueba comunes: I/O secuencial grande, flujo único, cache caliente, sin vecinos ruidosos.
Tu carga de trabajo suele ser I/O más pequeño, lecturas/escrituras mixtas, ráfagas y sensibilidad a la latencia en cola.
Las decisiones de batching o coalescencia del driver pueden mejorar el rendimiento medio mientras empeoran el p99.

Desajustes de timeouts entre capas

Una capa reintenta durante 30 segundos, otra abandona a los 10, y tu aplicación reintenta para siempre.
El resultado: escrituras duplicadas, I/O atascado, split brain en failover, o un estado “degradado pero vivo” que destruye SLAs lentamente.
Los drivers a menudo definen el primer timeout en la cadena.

Offloads que ayudan hasta que dejan de hacerlo

TCP segmentation offload, generic receive offload, checksum offload, LRO, cifrado por hardware y funciones de smart NIC:
pueden reducir CPU y aumentar throughput. También pueden romper capturas de paquetes, confundir mediciones de latencia
y desencadenar bugs de firmware bajo patrones de tráfico específicos.
Si operas redes de alta velocidad, eventualmente aprenderás qué offloads confías y cuáles deshabilitas por principio.

Problemas NUMA y de afinidad disfrazados de “el almacenamiento es lento”

Una cola ejecutándose en el socket equivocado puede añadir latencia medible, especialmente cuando persigues microsegundos.
Los drivers exponen el mapeo de colas, la afinidad de interrupciones y el uso de vectores MSI-X.
Si no controlas la afinidad, el scheduler te “ayudará” de formas que parecen aleatorias.

Huecos en telemetría

Algunos drivers exportan estadísticas detalladas; otros no exportan nada útil. Algunos contadores se reinician en un flap de enlace. Algunos mienten.
Necesitas saber qué puede decirte tu driver bajo presión, no solo un martes tranquilo.

Guía de diagnóstico rápido: encuentra el cuello de botella antes que la sala de guerra

Cuando la latencia se dispara o el throughput colapsa, no tienes tiempo para debatir arquitectura. Necesitas una ruta de triage determinista.
El objetivo es responder tres preguntas rápido:

  1. ¿Es el cuello de botella CPU, memoria, red o almacenamiento?
  2. ¿Es saturación, errores/reintentos o scheduling/afinidad?
  3. ¿Es local a un nodo, a una clase de dispositivo o sistémico?

Primero: establece si el kernel ve dolor de I/O

  • Comprueba la utilización por dispositivo y await.
  • Revisa la profundidad de cola y merges de peticiones.
  • Busca errores I/O, resets, timeouts en dmesg/journal.

Segundo: separa “el dispositivo es lento” de “el camino al dispositivo es lento”

  • NVMe: logs del controlador, SMART, eventos de reset.
  • Multipath/iSCSI/FC: fallos de ruta, failovers, estado ALUA, timeouts.
  • Virtualización: contención host vs guest, estadísticas de colas virtio, steal time.

Tercero: revisa la historia de desajuste driver/firmware/kernel

  • ¿Cambios recientes en kernel o firmware?
  • ¿Versiones de driver conocidas y buenas fijadas?
  • ¿Cambios en offloads o nuevas afinaciones?

Cuarto: confirma con una micro-prueba controlada

  • Usa una prueba fio mínima con un solo job y tamaño de bloque conocido.
  • Compárala con la línea base (incluso la de la semana pasada). Si no existe línea base, encontraste un fallo de proceso.

Tareas prácticas: comandos, salidas y la decisión que tomas

A continuación hay tareas reales que puedes ejecutar durante un incidente o una investigación de rendimiento. Cada una incluye:
el comando, un ejemplo de lo que podrías ver, qué significa y qué decisión tomar a continuación.
Son centradas en Linux porque allí viven la mayoría de las sorpresas de producción.

1) Identificar el driver exacto ligado a una NIC

cr0x@server:~$ ethtool -i ens5
driver: ixgbe
version: 5.15.0-91-generic
firmware-version: 0x800003e5
expansion-rom-version:
bus-info: 0000:3b:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

Qué significa: Ahora sabes el driver, build del kernel y versión de firmware. Esta es tu huella del incidente.
Decisión: Si los síntomas correlacionan con un despliegue reciente del kernel, tienes un sospechoso principal. También revisa la deriva de firmware
entre hosts; el firmware mezclado es un generador de outages subestimado.

2) Comprobar contadores de errores y drops de la NIC

cr0x@server:~$ ip -s link show dev ens5
2: ens5: <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
    RX:  bytes  packets  errors  dropped  missed  mcast
    9876543210  12345678  0       421      0       9012
    TX:  bytes  packets  errors  dropped  carrier collsns
    8765432109  11223344  0       0        0       0

Qué significa: Drops en RX sin errores suelen indicar presión en el buffer de anillo, saturación de CPU o problemas de offload/interrupciones.
Decisión: Si los drops suben con la carga, inspecciona la afinidad de interrupciones y el tamaño de colas RX; considera deshabilitar temporalmente offloads riesgosos.

3) Inspeccionar ajustes de offload (fuente común de “es raro”)

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

Qué significa: GRO/GSO/TSO activados es normal, pero al depurar latencia o anomalías de paquetes puede que necesites alternarlos.
Decisión: Si sospechas bugs de offload, desactiva uno a la vez y mide. No “desactives todo” a menos que te guste el denegamiento accidental de servicio por CPU.

4) Confirmar mapeo de dispositivo de almacenamiento y driver

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,MODEL,ROTA,TRAN,MOUNTPOINT
NAME        TYPE   SIZE MODEL               ROTA TRAN MOUNTPOINT
nvme0n1     disk 931.5G Samsung SSD 980     0    nvme
├─nvme0n1p1 part     1G                     0    nvme /boot
└─nvme0n1p2 part 930.5G                     0    nvme /

Qué significa: ROTA=0 confirma supuestos de comportamiento SSD/NVMe. TRAN=nvme aclara el transporte.
Decisión: Si esperabas NVMe empresarial y ves modelos de consumidor, para. Tus cálculos de rendimiento y resistencia acaban de cambiar.

5) Comprobar salud del controlador NVMe y log de errores

cr0x@server:~$ sudo nvme smart-log /dev/nvme0
Smart Log for NVME device:nvme0 namespace-id:ffffffff
critical_warning                    : 0x00
temperature                         : 42 C
available_spare                     : 100%
available_spare_threshold           : 10%
percentage_used                     : 3%
data_units_read                     : 1,234,567
data_units_written                  : 987,654
media_errors                        : 0
num_err_log_entries                 : 12

Qué significa: num_err_log_entries > 0 puede correlacionar con timeouts transitorios, resets o problemas de enlace.
Decisión: Extrae el log de errores a continuación; si los errores se agrupan durante incidentes, escala a investigación de compatibilidad firmware/driver.

6) Revisar logs del kernel por resets/timeouts

cr0x@server:~$ sudo dmesg -T | egrep -i 'nvme|timeout|reset|blk_update_request|I/O error' | tail -n 8
[Mon Jan 21 03:12:09 2026] nvme nvme0: I/O 123 QID 4 timeout, aborting
[Mon Jan 21 03:12:10 2026] nvme nvme0: Abort status: 0x371
[Mon Jan 21 03:12:11 2026] nvme nvme0: resetting controller
[Mon Jan 21 03:12:15 2026] blk_update_request: I/O error, dev nvme0n1, sector 123456 op 0x1:(WRITE) flags 0x0 phys_seg 1 prio class 0

Qué significa: Timeouts y resets de controlador no son “problemas de rendimiento.” Son problemas de fiabilidad con síntomas de rendimiento.
Decisión: Si aparecen resets, deja de ajustar flags de fio y comienza a validar firmware, cableado/backplane, errores PCIe y versiones de drivers del kernel.

7) Detectar errores de enlace PCIe (a menudo confundidos con “discos malos”)

cr0x@server:~$ sudo lspci -s 0000:3b:00.0 -vv | egrep -i 'LnkSta:|AER|UESta|CESta' -n
45:		LnkSta:	Speed 8GT/s, Width x8
97:		CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ FatalErr-

Qué significa: Errores corregibles (NonFatalErr+) aún pueden causar reintentos y jitter.
Decisión: Si los errores se acumulan, trátalo como inestabilidad en el camino hardware. Cambia slot/cable/backplane o ajusta la configuración ASPM de PCIe si aplica.

8) Medir latencia y utilización por dispositivo rápidamente

cr0x@server:~$ iostat -x 1 3
Linux 5.15.0-91-generic (server) 	01/21/2026 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           9.12    0.00    2.95    7.88    0.00   80.05

Device            r/s     w/s   rKB/s   wKB/s  avgrq-sz avgqu-sz   await  r_await  w_await  %util
nvme0n1         120.0   980.0  3840.0 15680.0     32.0     8.10   8.20     2.10     9.00   96.50

Qué significa: %util cercano a 100% con await alto sugiere saturación en el dispositivo o en la cola del driver.
Decisión: Si await sube mientras el throughput se mantiene plano, estás haciendo cola. Decide si reducir concurrencia (lado aplicación) o escalar dispositivos.

9) Buscar ajustes de cola en la capa de bloque (scheduler, nr_requests)

cr0x@server:~$ cat /sys/block/nvme0n1/queue/scheduler
[none] mq-deadline kyber

Qué significa: NVMe suele usar “none”, pero mq-deadline puede ayudar la latencia tail en cargas mixtas en algunos entornos.
Decisión: Si ves p99 extremo bajo contención, prueba mq-deadline en staging con tu carga. No adivines.

10) Comprobar profundidad de cola y I/O pendientes

cr0x@server:~$ cat /sys/block/nvme0n1/queue/nr_requests
1023

Qué significa: Esto no es “la” profundidad de cola, pero influye en cuánto puede encolar el kernel.
Decisión: Si tu sistema colapsa bajo ráfagas, considera si el encolamiento está ocultando backpressure y amplificando la latencia tail.

11) Observar tiempo de servicio de disco en tiempo real por proceso

cr0x@server:~$ sudo iotop -oPa
Total DISK READ:         0.00 B/s | Total DISK WRITE:       12.34 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN      IO    COMMAND
12345 be/4  postgres    0.00 B/s   8.90 M/s  0.00 %  12.00 %  postgres: writer process
23456 be/4  root        0.00 B/s   3.44 M/s  0.00 %   4.50 %  java -jar service.jar

Qué significa: Si un único proceso domina las escrituras, tu “problema de almacenamiento” podría ser un patrón de flush de la aplicación.
Decisión: Decide si limitar la tasa, agrupar operaciones, cambiar comportamiento de fsync o aislar inquilinos ruidosos en diferentes dispositivos.

12) Validar opciones de montaje del sistema de ficheros (los drivers cumplen política aquí)

cr0x@server:~$ findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /
/dev/nvme0n1p2 / ext4 rw,relatime,errors=remount-ro

Qué significa: Opciones como noatime, comportamiento de barreras (dependiente del sistema de ficheros) y modos de journaling influyen en patrones de I/O.
Decisión: Si estás depurando picos de latencia, confirma que las opciones de montaje concuerdan con tu intención y no son “valores por defecto heredados.”

13) Detectar estado multipath y flaps de ruta

cr0x@server:~$ sudo multipath -ll
mpatha (3600508b400105e210000900000490000) dm-2 IBM,2145
size=200G features='1 queue_if_no_path' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| `- 3:0:0:1 sdb 8:16 active ready running
`-+- policy='service-time 0' prio=10 status=enabled
  `- 4:0:0:1 sdc 8:32 active ready running

Qué significa: Si el estado salta entre active/enabled frecuentemente, puedes estar fallando por rutas y añadiendo latencia.
Decisión: Si existen flaps de ruta, deja de culpar a la base de datos. Arregla zonificación SAN, cableado, timeouts FC/iSCSI o problemas de driver/firmware.

14) Confirmar versiones de módulos del kernel y qué está cargado

cr0x@server:~$ lsmod | egrep 'nvme|dm_multipath|ixgbe|mlx5' | head
nvme                  69632  2
nvme_core            167936  3 nvme
dm_multipath          40960  0
ixgbe                286720  0

Qué significa: Confirma qué código está en juego. Si esperabas mlx5 (Mellanox) y ves otra cosa, encontraste deriva de configuración.
Decisión: Alinea versiones de módulos en la flota; fija builds conocidos y buenos donde la fiabilidad importe más que la novedad.

15) Ver si estás limitado por CPU en softirq (presión del driver de red)

cr0x@server:~$ mpstat -P ALL 1 2 | tail -n 8
Average:     CPU   %usr   %nice  %sys  %iowait  %irq  %soft  %steal  %idle
Average:      0    5.10    0.00  12.40    0.20  0.30   18.70    0.00  63.30
Average:      1    3.90    0.00   9.80    0.10  0.20   25.10    0.00  60.90

Qué significa: %soft alto sugiere presión de procesamiento de paquetes (NAPI/softirq), a menudo por ráfagas RX o afinidad de IRQ desbalanceada.
Decisión: Ajusta la afinidad de IRQ / RSS, aumenta colas RX o reduce ajustes de offload que desplacen trabajo inesperadamente a la CPU.

16) Validar distribución de interrupciones para una NIC (la afinidad importa)

cr0x@server:~$ grep -E 'ens5|ixgbe' /proc/interrupts | head -n 6
  64:   1234567          0          0          0  IR-PCI-MSI 524288-edge      ens5-TxRx-0
  65:         0    1133445          0          0  IR-PCI-MSI 524289-edge      ens5-TxRx-1
  66:         0          0     998877          0  IR-PCI-MSI 524290-edge      ens5-TxRx-2
  67:         0          0          0     887766  IR-PCI-MSI 524291-edge      ens5-TxRx-3

Qué significa: Idealmente, las interrupciones se reparten entre CPUs; “todas las interrupciones en CPU0” es una herida auto-infligida clásica.
Decisión: Si la distribución está sesgada, ajusta la política irqbalance o fija IRQs para cargas críticas. Mide antes/después.

17) Micro-benchmark de almacenamiento rápido y controlado (no te pases)

cr0x@server:~$ sudo fio --name=randread --filename=/var/tmp/fio.test --rw=randread --bs=4k --iodepth=32 --numjobs=1 --size=1G --runtime=30 --time_based --direct=1
randread: (groupid=0, jobs=1): err= 0: pid=27182: Tue Jan 21 03:22:01 2026
  read: IOPS=85.2k, BW=333MiB/s (349MB/s)(9990MiB/30001msec)
    slat (usec): min=3, max=89, avg=7.2, stdev=1.1
    clat (usec): min=45, max=4120, avg=365.1, stdev=55.4
    lat  (usec): min=55, max=4130, avg=372.5, stdev=55.6

Qué significa: Obtienes una comprobación de cordura: IOPS, ancho de banda y distribución de latencias. picos en clat max pueden indicar encolamiento o resets.
Decisión: Si fio se ve sano pero tu app es lenta, el cuello de botella probablemente esté más arriba: comportamiento del sistema de ficheros, patrones de sync, locks o red.
Si fio está mal, investiga inmediatamente la ruta de driver y dispositivo.

Tres mini-historias corporativas (anonimizadas, dolorosamente plausibles)

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

Una empresa SaaS de tamaño medio desplegó nuevos nodos de cómputo para un clúster Kubernetes con mucho tráfico. Mismo modelo de CPU, misma RAM, “misma” capacidad NVMe.
Compras cumplió: compraron lo que cumplía la ficha técnica. El equipo de plataforma los imprinted y los añadió al pool de nodos.
Todo se veía bien durante una semana.

Luego la latencia p99 de un servicio central empezó a oscilar todas las tardes. El autoscaling se disparó, lo que incrementó costes pero no arregló el p99.
El on-call notó algo extraño: solo los pods programados en los nodos nuevos mostraban las peores latencias de cola. Sin embargo, fio en esos nodos parecía “ok”
si se ejecutaba en horas tranquilas. Durante el pico, era un caos: picos ocasionales de clat de varios milisegundos.

La suposición equivocada fue simple: “NVMe es NVMe.” Los nodos nuevos tenían dispositivos NVMe de grado consumidor con gestión de energía agresiva
y una combinación firmware/driver que favorecía ráfagas de throughput sobre latencia consistente. Bajo carga mixta sostenida, el controlador
entraba en comportamientos que se manifestaban como paradas periódicas. Nadie había revisado nvme smart-log o entradas del log de errores porque no
hubo fallos duros. Solo mucha “performance”.

La solución no fue exótica. Estandarizaron en modelos NVMe empresariales, fijaron firmware y añadieron un paso de validación previa al despliegue:
fio con un umbral de latencia tail, no solo IOPS promedio. También aprendieron a registrar huellas de driver y firmware en el inventario.
La victoria real fue cultural: dejaron de tratar a los drivers como ruido de fondo y empezaron a tratarlos como parte del diseño de la plataforma.

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

Una compañía de pagos perseguía reducir costes de CPU. El procesamiento de red era un gran trozo, y alguien tuvo una idea brillante:
habilitar todas las funciones “útiles” de offload de NIC en toda la flota. Se desplegó gradualmente y en pruebas sintéticas el throughput mejoró.
La CPU bajó. Los gráficos parecían heroicos.

Dos semanas después, los tickets de soporte empezaron a mencionar “timeouts aleatorios”. No constantes. No regionales. Simplemente… aleatorios.
Los logs de la aplicación mostraron retransmisiones elevadas y fallos ocasionales en el handshake TLS. Los balanceadores no veían errores de enlace.
El equipo de incidentes hizo la danza habitual: culpar DNS, culpar certificados, culpar “internet”.

La realidad fue prosaicamente mundana. La combinación específica de offloads interactuó mal con un patrón de tráfico de muchas respuestas pequeñas
y una versión particular del kernel. Los paquetes no estaban “corruptos” en la forma que los contadores señalaban; estaban retrasados y coalescidos de maneras que
inflaban la latencia tail. Las capturas de paquetes eran engañosas porque los offloads distorsionaban lo que tcpdump veía frente a lo que había en el cable.
El sistema se volvió difícil de depurar justo cuando necesitaba ser depurable.

El rollback lo arregló. Luego el equipo reintrodujo offloads selectivamente con criterios claros de aceptación: p99, retransmisiones
y fidelidad de observabilidad. La lección no fue “los offloads son malos.” La lección fue que drivers y offloads son características de producción,
así que las despliegas como características: con canarios, medición y una vía de aborto rápida.

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

Una plataforma de analítica sanitaria tenía una costumbre que parecía aburrida en las revisiones de cambios: fijaban versiones de kernel por entorno,
mantenían una línea base de drivers “conocida buena” y requerían una breve prueba de regresión de rendimiento antes de promover un kernel a producción.
Esto molestaba a quienes querían parches de seguridad ayer y nuevas funciones mañana.

Un trimestre, tuvieron que parchear rápidamente por un advisory de seguridad del kernel. Promovieron un nuevo kernel a staging y vieron inmediatamente
latencia de almacenamiento elevada en sus jobs batch nocturnos. Nada se cayó. Simplemente se puso más lento, de una forma que habría hecho que el job
sobrepasara la ventana de mantenimiento en producción.

Su prueba de regresión señaló el cambio. El equipo bisecó la diferencia en staging: misma carga, mismo hardware, kernel distinto.
Confirmaron que correlacionaba con un cambio en el manejo del encolamiento del driver NVMe bajo mezcla de lectura/escritura. No era “un bug” espectacular.
Era un cambio de comportamiento que perjudicaba su carga específica.

Porque tenían una baseline fijada y un proceso, pudieron tomar una decisión en calma: aplicar el parche de seguridad usando el backport del proveedor
en la línea de kernel anterior, mantener estable el comportamiento del driver y programar una migración controlada más adelante con mitigaciones.
La práctica aburrida—fijar, baselinar, probar regresiones—no solo previno un outage. Previno una falla operativa en cámara lenta que habría parecido “la app empeora.”

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

1) Síntoma: picos de latencia p99, las medias se ven bien

Causa raíz: Encolamiento del driver oculta backpressure; colas profundas + carga en ráfagas crean inflación de latencia tail.

Solución: Reduce la concurrencia en la app, prueba mq-deadline/kyber donde corresponda, y confirma que el firmware del dispositivo no esté causando paradas. Mide p95/p99, no solo la media.

2) Síntoma: “El almacenamiento es lento” solo en ciertos nodos

Causa raíz: Versiones mixtas de firmware/driver, comportamiento distinto de slot PCIe o diferencias de afinidad NUMA.

Solución: Compara huellas (driver/firmware/lspci), revisa contadores AER de PCIe y normaliza IRQ/afinidad de colas en el pool de nodos.

3) Síntoma: timeouts de red aleatorios, sin errores de enlace

Causa raíz: Interacción de offloads (GRO/TSO/checksum) o moderación de interrupciones que causa latencia tail en micro-rafagas.

Solución: Alterna offloads uno a la vez; inspecciona CPU en softirq; valida tamaños de ring y distribución RSS.

4) Síntoma: almacenamiento multipath muestra paradas periódicas

Causa raíz: Flaps de ruta + comportamiento queue_if_no_path causando que I/O se acumule durante cortos outages.

Solución: Arregla la ruta inestable, ajusta timeouts coherentemente entre multipath y transporte, y prueba failover bajo carga (no durante ventana de mantenimiento con cero tráfico).

5) Síntoma: Tras una actualización de kernel, el throughput cae 15–30%

Causa raíz: Regresión de driver o cambios de valores por defecto (scheduler, mapeo de colas, valores por defecto de offload).

Solución: Re-ejecuta fio y pruebas de red base, compara ajustes en sysfs, y fija o revierte mientras validas el nuevo comportamiento en staging.

6) Síntoma: %iowait alto, pero discos no están ocupados

Causa raíz: I/O esperando algo distinto al throughput del dispositivo: locks de sistema de ficheros, contención de journal o una ruta estancada en virtualización.

Solución: Usa iotop + perf/eBPF si está disponible, verifica steal time en virtualización, y revisa resets/timeouts de drivers que bloqueen la capa de bloque.

7) Síntoma: la captura de paquetes no coincide con la realidad

Causa raíz: Offloads (especialmente GRO/GSO/TSO) cambian lo que observas en tcpdump respecto al comportamiento en el cable.

Solución: Desactiva offloads temporalmente para depurar o captura en un punto mirror/span; no construyas una teoría sobre paquetes engañosos.

8) Síntoma: “Funciona bien” hasta el tráfico pico, luego colapso

Causa raíz: Desbalance de interrupciones/colas: una cola caliente, una CPU manejando la mayoría de interrupciones, o problemas con el presupuesto NAPI.

Solución: Inspecciona /proc/interrupts, configura RSS/afinidad de forma sensata, valida la configuración de irqbalance y re-test bajo carga similar al pico.

Listas de comprobación / plan paso a paso

Paso a paso: construir una línea base de producción consciente de drivers

  1. Inventario de huellas.
    Registra driver+firmware de NIC, driver+firmware NVMe, versión del kernel y ajustes clave de sysfs por clase de host.
  2. Define pruebas de rendimiento relevantes para la carga.
    Un perfil fio de almacenamiento y un perfil de red que coincidan con tus tamaños de I/O reales y concurrencia.
  3. Rastrea métricas tail.
    Requiere umbrales de latencia p95/p99, no solo throughput.
  4. Despliegues en staging con canarios.
    Primero una AZ/rack/nodepool, con criterios de aborto escritos.
  5. Fija combinaciones conocidas buenas.
    Hardware + firmware + driver + kernel como una unidad, por plataforma.
  6. Haz que revertir sea aburrido.
    Ten una vía automatizada para revertir cambios de kernel/driver de forma segura.
  7. Prueba failover bajo carga.
    Multipath, NICs en bond o failover NVMe-oF deberían probarse con concurrencia real.
  8. Documenta tu postura sobre offloads.
    Qué offloads están permitidos, cuáles están prohibidos y cuáles requieren justificación explícita.

Paso a paso: respuesta a incidentes cuando “almacenamiento/red está lento”

  1. Acótalo. ¿Qué nodos, qué dispositivos, qué ventana temporal? Si es una clase de nodo, sospecha deriva de drivers/firmware.
  2. Recolecta huellas inmediatamente. ethtool -i, lsmod, uname -a, nvme smart-log.
  3. Revisa errores/resets. dmesg y contadores AER de PCIe. Los resets cambian la historia de “afinación” a “estabilidad.”
  4. Busca señales de saturación. iostat -x, profundidad de colas, %util, CPU en softirq.
  5. Ejecuta una micro-prueba controlada. fio o una pequeña prueba de red, con mínima disrupción.
  6. Toma una decisión. Revierte un cambio, aisla un pool de nodos, desactiva un offload específico o falla lejos de una clase de dispositivo sospechosa.
  7. Escribe la delta de drivers post-incidente. Qué cambió en driver/firmware/kernel, y cómo evitar deriva silenciosa.

Qué evitar (porque estarás tentado)

  • No cambies cinco tunables a la vez durante un incidente. “Arreglarás” sin saber cómo, y volverá.
  • No confíes en un perfil de benchmark que no diseñaste. Los valores por defecto del proveedor no son tu carga.
  • No actualices kernel/firmware de forma independiente entre hosts a menos que también rastrees las combinaciones y las pruebes.
  • No asumas que un problema de driver es “raro.” Es raro hasta que escalas, luego es martes.

Preguntas frecuentes

1) ¿Por qué los controladores son más importantes ahora que hace cinco años?

Porque el hardware es más rápido, las pilas son más profundas (virtualización, CSI, offloads) y las actualizaciones de kernel son más frecuentes. Los drivers ahora codifican política:
encolamiento, reintentos, agrupamiento y exposición de telemetría.

2) Si el driver del proveedor “soporta Linux”, ¿no es eso suficiente?

“Soporta Linux” a menudo significa “se carga y pasa una prueba funcional.” Producción significa latencia tail, semánticas de fallo y comportamiento bajo contención.
Necesitas validación específica de carga y una baseline fijada.

3) ¿Siempre debo usar el kernel más reciente para tener los mejores drivers?

No siempre. Los kernels nuevos traen arreglos y características, pero también cambios de comportamiento. Usa un despliegue en staging, mantiene una línea de kernel conocida buena
y actualiza con criterios de aceptación medibles.

4) ¿Valen la pena los offloads?

A menudo sí, especialmente para throughput y eficiencia de CPU. Pero trátalos como características de producción: habilítalos selectivamente, valida la observabilidad
y mantén un plan de rollback rápido. Algunos entornos priorizan la depurabilidad sobre el pico de throughput.

5) ¿Cómo sé si mi cuello de botella es “el driver” versus “el dispositivo”?

Busca resets/timeouts en logs, errores PCIe y cambios de comportamiento tras actualizaciones de kernel. Un problema de dispositivo suele mostrar indicadores de salud/errores,
mientras que un problema de driver suele correlacionar con cambios de versión y manifestarse en una clase de hosts.

6) ¿Cuál es la métrica más útil para problemas de almacenamiento?

La latencia tail (p95/p99) correlacionada con la profundidad de cola y %util. Las medias mienten. Si las colas crecen y p99 salta, estás acumulando dolor en algún lugar.

7) En Kubernetes, ¿por qué importan tanto los drivers CSI?

No son solo “ruta de datos.” Son actores del plano de control: aprovisionamiento, attach, resize, snapshot. Bugs o throttling pueden bloquear el scheduling,
crear volúmenes atascados o causar reintentos en cascada que parecen inestabilidad del clúster.

8) ¿Cuál es la forma más segura de cambiar afinaciones relacionadas con drivers en producción?

Cambia una variable a la vez, canarízala, mide latencia tail y contadores de error, y documenta el antes/después.
Si no puedes explicar por qué ayudó, no has terminado el trabajo.

9) ¿Necesito preocuparme por NUMA en almacenamiento y redes?

Si ejecutas altas IOPS o alto ancho de banda, sí. La localidad NUMA y la afinidad de IRQ pueden ser la diferencia entre p99 estable y jitter periódico.
Trátalo como parte de la planificación de capacidad.

10) ¿Qué debo estandarizar primero: hardware, firmware o drivers?

Estandariza el paquete. En la práctica: elige SKU(s) de hardware, fija firmware, fija una baseline de kernel/driver y aplica detección de deriva.
La estandarización parcial es cómo obtienes “el mismo servidor” comportándose distinto a las 2 a.m.

Conclusión: pasos siguientes que realmente puedes hacer

Los controladores serán “parte del juego” aún más porque allí es donde los sistemas modernos esconden su complejidad: en colas, offloads
y timeouts. Fingir que los drivers son una fontanería aburrida es como acabar diagnosticando “latencia aleatoria” durante tres días.

Pasos prácticos siguientes:

  • Crea un inventario de huellas de driver/firmware por clase de nodo y haz visible la deriva.
  • Construye dos líneas base: un perfil fio de almacenamiento y un perfil de red que coincidan con tu carga (incluyendo métricas tail).
  • Fija paquetes conocidos buenos (hardware + firmware + kernel + driver) y promueve cambios vía canarios.
  • Escribe tu política de offloads y trata los cambios de offload como despliegues de características.
  • Practica la guía de diagnóstico rápido una vez cuando nadie esté en llamas, para que funcione cuando todo lo esté.

No necesitas convertirte en desarrollador de drivers. Debes volverte lector de drivers: saber qué está cargado, qué cambió, qué afecta
y cómo probarlo con datos. Esa es la diferencia entre “creemos que es almacenamiento” y “sabemos exactamente qué capa está mintiendo hoy.”

← Anterior
Cadenas CNAME en DNS: cuando son un problema de rendimiento y fiabilidad
Siguiente →
WordPress no envía correos: configuración SMTP que realmente entrega

Deja un comentario