Pilotes qui dégradent les performances : le rituel post‑mise à jour

Cet article vous a aidé ?

Vous appliquez un patch de noyau, mettez à jour un pilote NIC, ou installez le paquet « recommandé » du fournisseur pour le stockage. La fenêtre de changement se referme. Les graphiques semblent corrects pendant une heure. Puis la latence monte comme un ascenseur capricieux : lente, régulière, et dans une direction que vous ne souhaitez pas.

C’est à ce moment que certains disent « ce n’est pas le pilote » parce que la mise à jour « n’a touché que le réseau ». Pendant ce temps, votre base de données expire des requêtes parce que les files de complétion du stockage sont affamées derrière une tempête d’interruptions. La production se fiche de l’équipe qui porte le blâme. Elle veut juste que ça aille vite.

Ce qui change quand les pilotes changent

Les pilotes ne sont pas « seulement des pilotes ». Ils déterminent comment votre matériel est ordonnancé, comment les interruptions sont livrées, comment les files sont dimensionnées, et comment le noyau perçoit le temps sous charge. Une mise à jour de pilote peut modifier les performances sans toucher une seule ligne de votre code applicatif. Ce n’est pas un risque théorique ; c’est mardi.

Schémas de régression de performance qui apparaissent après des mises à jour de pilotes

  • Pics de latence sans perte de débit : modifications du chemin de complétion, réglage de la modération d’interruptions, ou changement des valeurs par défaut de profondeur de file. Vos tableaux de bord montrent des MB/s stables, tandis que la latence p99 devient incontrôlable.
  • Baisse du débit avec faible CPU : offloads désactivés, lien négocié à une vitesse inférieure, PCIe négociant moins de lanes, ou une politique de firmware conservatrice qui s’enclenche.
  • CPU élevé alors que « rien d’autre n’a changé » : le nombre de vecteurs MSI‑X a changé, l’affinité IRQ a été réinitialisée, les bascules RPS/RFS ont été modifiées, ou un nouveau pilote verrouille le travail sur un seul cœur.
  • Seules certaines machines régressent : différentes révisions/firmwares, valeurs BIOS par défaut, différences de microcode, ou pilote correspondant à un device ID légèrement différent.
  • Régression seulement sous concurrence : le comportement de mise en file a changé ; les tests mono‑thread semblent corrects, mais les charges réelles ne sont pas mono‑thread.

Où se produit le vrai dommage

En production, « performance pilote » signifie généralement l’un des trois pipelines :

  1. Pipeline I/O de stockage : couche bloc → ordonnanceur → multipath (peut‑être) → pilote HBA/NVMe → firmware → média. Les mises à jour peuvent affecter la mise en file, le comportement de merge, les timeouts, et la récupération d’erreurs.
  2. Pipeline réseau : files netdev → GRO/LRO/offloads → modération d’interruptions → NAPI polling → topologie CPU/NUMA. Une mise à jour de pilote peut modifier silencieusement les tailles de ring et la coalescence par défaut, ce qui change la latence en queue.
  3. Pipeline accélérateur (GPU/DPDK/RDMA) : mémoire pinée, mappings IOMMU, hugepages, DMA peer‑to‑peer. Une mise à jour « mineure » peut basculer un paramètre par défaut qui transforme le DMA en mélasse.

Voici la vérité inconfortable : votre mise à jour de pilote n’a pas seulement mis à jour un pilote. Elle a mis à jour les hypothèses du système sur la façon de déplacer des octets.

Une citation à garder en tête, car c’est la version opérations de la gravité :

Werner Vogels (idée paraphrasée) : « Tout échoue tout le temps ; concevez et exploitez avec cette attente. »

Et une petite blague avant de devenir sérieux : Une mise à jour de pilote, c’est comme réorganiser votre garage — inoffensif jusqu’au moment où vous avez besoin de la clé à 2 h du matin.

Faits et contexte historique qui nous mordent encore

Certaines régressions « modernes » sont d’anciens problèmes sous un matériel plus récent. Un peu d’histoire aide à prédire où les performances tombent en piqué.

  1. La couche bloc Linux a changé de direction plusieurs fois : des ordonnanceurs legacy au multi‑queue (blk‑mq), déplaçant les goulots d’étranglement du merge de requêtes vers l’ordonnancement CPU et la gestion des files.
  2. NCQ et le tagged command queuing ont changé la signification de « profondeur de file » : des files plus profondes ont amélioré le débit mais exposé la latence de queue et des problèmes d’équité sous charges mixtes.
  3. MSI/MSI‑X ont remplacé les interruptions partagées pour de bonnes raisons : mais le nombre de vecteurs et leur mapping vers les CPUs peuvent faire ou défaire des systèmes I/O intensifs. Les pilotes changent souvent ces valeurs par défaut.
  4. La modération d’interruptions a été inventée pour sauver le CPU : la coalescence améliore le débit mais peut ruiner la latence p99. Les mises à jour de pilotes parfois « augmentent utilement » cette valeur.
  5. Les offloads (TSO/GSO/GRO/LRO) sont une arme à double tranchant : ils peuvent améliorer le débit et réduire l’utilisation CPU, mais aussi masquer des problèmes et ajouter de la latence à des endroits étranges. Les mises à jour peuvent les réinitialiser.
  6. La négociation de lien a été une source récurrente de facepalm depuis les débuts d’Ethernet : un seul mismatch d’auto‑négociation peut vous rétrograder silencieusement de 25/40/100G à quelque chose d’embarrassant.
  7. Les valeurs par défaut multipath ont évolué avec les SAN : politiques de vérification de chemin, comportements queue_if_no_path, et timing de basculement peuvent changer. « Fonctionne » ne veut pas dire « rapide ».
  8. NVMe a standardisé beaucoup de choses, mais le firmware varie toujours énormément : différentes politiques APST et de récupération d’erreurs peuvent changer la latence d’ordres de grandeur.

Rien de tout cela n’est académique. Ça revient sous la forme de « ça allait la semaine dernière ».

Feuille de route pour un diagnostic rapide

Vous êtes chronométré. Les utilisateurs crient. La fenêtre de changement est fermée depuis longtemps. Il vous faut une séquence qui vous amène rapidement à un goulot d’étranglement crédible.

Premier : confirmez que c’est réel, et définissez « lent » en une phrase

  • Choisissez un observable : p99 read latency, commit latency, network RTT, IOPS, ou CPU softirq.
  • Choisissez une comparaison : la baseline d’hier ou un autre hôte du même cluster qui n’a pas été mis à jour.
  • N’« enquêtez pas sur les performances » de manière trop vaste. Vous allez vous enliser.

Deuxième : décidez quel pipeline est coupable

Utilisez ces indices rapides :

  • iowait élevé, disk await en hausse, CPU stable → chemin de stockage ou politique device/firmware.
  • softirq élevé, activité ksoftirqd, paquets perdus → chemin réseau / interruptions.
  • Un seul cœur CPU saturé, les autres inactifs → régression d’affinité IRQ / mapping des queues.
  • Seulement sous charge, pas en idle → mise en file, coalescence, ordonnanceur, ou états d’économie d’énergie.

Troisième : trouvez le « retour aux valeurs par défaut »

Après les mises à jour, les régressions de performance viennent souvent d’un paramètre par défaut qui revient :

  • Tailles de rings NIC revenues à des valeurs faibles
  • Affinité IRQ perdue ou réordonnée
  • APST NVMe réactivé
  • Ordonnanceur I/O changé
  • Politique multipath modifiée
  • Mode IOMMU basculé

Quatrième : prouvez‑le avec un test contrôlé

Lancez un micro‑benchmark court et reproductible sur l’hôte affecté et sur un hôte connu bon. Vous n’essayez pas de gagner un concours de benchmark ; vous cherchez à isoler la dimension de la régression (latence vs débit vs CPU).

Cinquième : choisissez l’atténuation la plus sûre

Par ordre de priorité :

  1. Rollback du paquet pilote/firmware (restauration la plus rapide vers un état connu).
  2. Réappliquer des tunables connus bons (si rollback impossible).
  3. Pinner la charge de travail loin des hôtes affectés (gagner du temps).
  4. Rollback complet du noyau si le changement est couplé au kernel.

Le rituel post‑mise à jour (la partie ennuyeuse qui gagne)

Rituel fait sonner mystique. Ce n’est pas le cas. C’est une vérification répétable qui évite la spirale « on a mis à jour et maintenant c’est plus lent ». Les meilleures équipes traitent les mises à jour de pilotes comme des migrations de base de données : réversibles, mesurées, et testées dans les mêmes conditions.

1) Notez les deltas attendus avant d’appliquer

Pas « ça devrait aller ». Des attentes précises :

  • Quels appareils sont affectés (PCI IDs, modèle NIC, modèle NVMe, firmware HBA) ?
  • Quelles métriques peuvent bouger (latence, débit, CPU softirq, taux d’erreurs) ?
  • Quel est votre plan de rollback (procédure de downgrade du paquet, entrée noyau précédente, retour de firmware si possible) ?

2) Capturez une baseline reproductible

Votre « baseline » n’est pas une capture d’écran du dashboard d’il y a un mois. C’est un bundle de sorties de commandes qui raconte une histoire cohérente : version du noyau, versions des pilotes, versions du firmware, tunables, et un petit résultat de benchmark.

3) Mettez à jour par tranche contrôlée

Canaries d’abord. Pas parce que c’est tendance, mais parce que les régressions sont souvent spécifiques au matériel et vous voulez le découvrir avec un nœud, pas quarante.

4) Re‑vérifiez les valeurs par défaut qui vous importent

Les paquets pilotes livrent parfois de nouveaux paramètres par défaut. Certains sont meilleurs. D’autres supposent que votre charge est « web serving » alors que vous êtes « base de données écriture‑lourde avec SLO p99 ». Traitez les valeurs par défaut comme des suggestions du fournisseur, pas comme des lois.

5) Comparez sous charge, pas sous espoir

Les systèmes inactifs mentent. La plupart des régressions apparaissent sous concurrence, à l’extrémité des buffers, quand la couche bloc est sous pression, ou quand la modération d’interruptions change le rythme des complétions.

Deuxième et dernière blague courte : Le moyen le plus rapide de trouver une régression est d’annoncer « cette mise à jour est sûre » dans une revue de changement. L’univers le prendra personnellement.

Tâches pratiques : commandes, sorties et décisions

Ci‑dessous des tâches concrètes à lancer juste après une mise à jour. Chaque tâche inclut : la commande, ce que signifie la sortie, et quelle décision prendre.

Task 1: Confirm what actually changed (kernel + driver modules)

cr0x@server:~$ uname -r
6.5.0-28-generic
cr0x@server:~$ modinfo ixgbe | egrep 'filename|version|srcversion'
filename:       /lib/modules/6.5.0-28-generic/kernel/drivers/net/ethernet/intel/ixgbe/ixgbe.ko
version:        5.19.6-k
srcversion:     1A2B3C4D5E6F7A8B9C0D1E2

Signification : Vous avez la version du noyau en cours d’exécution et la build/version du module chargé. Si la régression est apparue « après la mise à jour », prouvez que vous exécutez bien les éléments mis à jour.

Décision : Si le noyau/le pilote n’est pas celui attendu, arrêtez : votre rollout/bootloader/pinning de paquet ne se comporte pas comme prévu. Corrigez cela avant de toucher aux tunables.

Task 2: Identify firmware versions for NIC and storage

cr0x@server:~$ sudo ethtool -i eno1
driver: ixgbe
version: 5.19.6-k
firmware-version: 0x80000d7b
bus-info: 0000:3b:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

Signification : Le firmware peut changer le comportement même si le pilote n’a pas changé. Certaines mises à jour installent le firmware via des paquets distincts ou pendant une maintenance.

Décision : Si le firmware a changé, incluez‑le dans le plan de rollback et dans les comparaisons « known‑good ». Ne supposez pas que vous pouvez le rétablir rapidement.

Task 3: Check PCIe link speed/width (silent throughput killer)

cr0x@server:~$ sudo lspci -s 3b:00.0 -vv | egrep -i 'LnkCap:|LnkSta:'
LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM not supported
LnkSta: Speed 2.5GT/s (downgraded), Width x4 (downgraded)

Signification : Le périphérique a négocié à une vitesse inférieure. Cela peut arriver après des changements BIOS, des mises à jour de firmware, ou des particularités de gestion d’alimentation.

Décision : Si LnkSta indique une vitesse/largeur réduite, arrêtez de chasser les tunables du pilote. Corrigez d’abord le problème physique/négociation PCIe (réinsérez, réglages BIOS, états d’alimentation, quirks connus de la plateforme).

Task 4: Spot storage latency vs saturation (iostat)

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0-28-generic (server) 	01/22/2026 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          11.22    0.00    6.51   18.45    0.00   63.82

Device            r/s     w/s   rkB/s   wkB/s  rrqm/s wrqm/s  %util  await  r_await  w_await
nvme0n1         820.0  1250.0 52480.0 76800.0    0.0    0.0   97.8   9.82     6.10    12.40

Signification : %util proche de 100% suggère une saturation. await indique la latence moyenne ; la division lecture/écriture aide à identifier quel pattern a empiré.

Décision : Si await a grimpé après la mise à jour avec un débit similaire, suspectez les états d’alimentation, les paramètres de file, les changements d’ordonnanceur, ou la récupération firmware. Si %util est faible mais await élevé, suspectez des problèmes de chemin ou des timeouts.

Task 5: Look for NVMe power state and APST regressions

cr0x@server:~$ sudo nvme get-feature /dev/nvme0 -f 0x0c -H
get-feature:0xc (Autonomous Power State Transition), Current value:0x00000001
APSTE: 1
APST Entries:
Entry[ 0]  Idle Time Prior to Transition (ITPT): 1000 ms
Entry[ 0]  Idle Transition Power State   (ITPS): 3

Signification : APST activé peut convenir aux portables et être une catastrophe sur des serveurs sensibles à la latence, selon le device/firmware.

Décision : Si la latence a régressé et qu’APST est activé de façon inattendue, testez la désactivation (temporaire) et voyez si p99 revient. Puis rendez‑le persistant via le mécanisme adapté à votre distro/noyau.

Task 6: Check block scheduler and queue settings

cr0x@server:~$ cat /sys/block/nvme0n1/queue/scheduler
[mq-deadline] none
cr0x@server:~$ cat /sys/block/nvme0n1/queue/nr_requests
1024
cr0x@server:~$ cat /sys/block/nvme0n1/queue/read_ahead_kb
128

Signification : Le choix de l’ordonnanceur et la profondeur de file influent l’équité et la latence sous contention. Les mises à jour changent parfois l’ordonnanceur par défaut ou les limites de requêtes.

Décision : Si l’ordonnanceur diffère du known‑good, réalignez‑le et retestez. Si nr_requests a été réduit, vous pouvez voir une chute de débit sous charge parallèle ; s’il a augmenté, attendez‑vous à des pics de latence en queue.

Task 7: Validate multipath state (SAN regressions love to hide here)

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

Signification : Les priorités de chemin et les politiques comptent. Un changement de politique peut router plus d’I/O sur un chemin plus lent ou causer du thrash pendant le basculement.

Décision : Si la sélection du chemin actif diffère après la mise à jour, comparez multipath.conf et les features de la map en cours. Corrigez la politique/gestion ALUA avant d’accuser la base de données.

Task 8: Check dmesg for driver resets, timeouts, or link flaps

cr0x@server:~$ sudo dmesg -T | egrep -i 'nvme|ixgbe|timeout|reset|link is|error' | tail -n 20
[Wed Jan 22 10:12:41 2026] nvme nvme0: I/O 123 QID 5 timeout, completion polled
[Wed Jan 22 10:12:41 2026] nvme nvme0: Abort status: 0x371
[Wed Jan 22 10:14:03 2026] ixgbe 0000:3b:00.0 eno1: NIC Link is Up 10 Gbps, Flow Control: RX/TX

Signification : Timeouts et aborts ne sont pas du « bruit ». Ce sont des tueurs de performances bien avant de devenir des pannes.

Décision : Si vous voyez de nouveaux timeouts après la mise à jour, arrêtez les réglages et commencez l’isolement : compatibilité firmware, gestion d’alimentation, câble/SFP, PCIe, ou bugs du pilote. Envisagez un rollback immédiat.

Task 9: Verify NIC link speed and negotiated settings

cr0x@server:~$ sudo ethtool eno1 | egrep 'Speed:|Duplex:|Auto-negotiation:|Link detected:'
Speed: 10000Mb/s
Duplex: Full
Auto-negotiation: on
Link detected: yes

Signification : Si la vitesse est incorrecte, tout ce qui suit en souffre. C’est l’étape « vérifiez le câble », sauf qu’en 2026 le câble est parfois une valeur par défaut de firmware.

Décision : Si la vitesse a chuté, corrigez‑la d’abord. Si la vitesse est correcte, passez aux offloads et aux tailles de rings.

Task 10: Check NIC offloads (updates love to reset them)

cr0x@server:~$ sudo ethtool -k eno1 | egrep 'tcp-segmentation-offload|generic-segmentation-offload|generic-receive-offload|rx-checksumming|tx-checksumming'
rx-checksumming: on
tx-checksumming: on
tcp-segmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on

Signification : Un seul offload désactivé peut transférer le coût CPU dans le noyau et réduire le débit. Mais activer aveuglément tout peut augmenter la latence ou casser l’observabilité.

Décision : Comparez avec le known‑good. Si TSO s’est désactivé après la mise à jour et que CPU softirq a augmenté, réactivez‑le et retestez. Si la latence est le problème, envisagez d’ajuster la coalescence plutôt que d’activer tous les offloads.

Task 11: Inspect ring sizes and drop counters

cr0x@server:~$ sudo ethtool -g eno1
Ring parameters for eno1:
Pre-set maximums:
RX:             4096
RX Mini:        0
RX Jumbo:       0
TX:             4096
Current hardware settings:
RX:             512
RX Mini:        0
RX Jumbo:       0
TX:             512
cr0x@server:~$ ip -s link show dev eno1 | tail -n 8
    RX:  bytes  packets  errors  dropped  missed  mcast
    9876543210  12345678 0       421      0       0
    TX:  bytes  packets  errors  dropped  carrier collsns
    8765432109  11223344 0       0        0       0

Signification : Des rings petits et des drops en hausse sont une régression post‑mise à jour classique quand les valeurs par défaut changent. Les drops provoquent des retransmissions, ce qui ressemble à de la « latence aléatoire ».

Décision : Si les drops augmentent et que les rings sont petits par rapport au max, augmentez les tailles de ring (avec précaution) et retestez. Si les drops persistent, regardez la coalescence et la distribution IRQ.

Task 12: Check interrupt distribution (IRQ affinity regression)

cr0x@server:~$ awk '/eno1/ {print}' /proc/interrupts | head -n 6
  121:   9843321          0          0          0   PCI-MSI 524288-edge      eno1-TxRx-0
  122:         0          0          0          0   PCI-MSI 524289-edge      eno1-TxRx-1
  123:         0          0          0          0   PCI-MSI 524290-edge      eno1-TxRx-2
  124:         0          0          0          0   PCI-MSI 524291-edge      eno1-TxRx-3

Signification : Toutes les interruptions arrivant sur un seul CPU sont une taxe de performance et un générateur de latence. Après une mise à jour, le comportement d’irqbalance ou le setup des vecteurs du pilote peut changer.

Décision : Si un vecteur est chaud et les autres froids, corrigez l’affinité (ou RPS/RFS) et retestez. Si les vecteurs ne sont pas créés comme attendu, vérifiez les paramètres du pilote et si MSI‑X est activé.

Task 13: Measure softirq load (network path pain)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0-28-generic (server) 	01/22/2026 	_x86_64_	(32 CPU)

12:20:41 PM  CPU   %usr  %nice   %sys %iowait  %irq %soft  %idle
12:20:42 PM  all  10.20   0.00   6.80   1.10   0.30  8.90  72.70
12:20:42 PM    7   2.00   0.00   4.00   0.00   0.00 65.00  29.00

Signification : Un seul CPU noyé en %soft suggère un déséquilibre de traitement des interruptions/paquets. C’est souvent un reset de paramètre du pilote, pas « l’application qui ralenti ».

Décision : Si un CPU est surchargé en %soft, ajustez l’affinité IRQ/RPS ou revoyez les offloads/la coalescence. Si softirq est bas mais la latence élevée, le goulot est peut‑être ailleurs.

Task 14: Validate I/O path concurrency with fio (controlled, short test)

cr0x@server:~$ sudo fio --name=randread --filename=/dev/nvme0n1 --direct=1 --ioengine=libaio --rw=randread --bs=4k --iodepth=64 --numjobs=4 --runtime=30 --time_based --group_reporting
randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
...
  read: IOPS=220k, BW=859MiB/s (901MB/s)(25.2GiB/30001msec)
    slat (nsec): min=920, max=110893, avg=3210.44, stdev=1800.12
    clat (usec): min=60, max=9800, avg=112.30, stdev=95.20
     lat (usec): min=62, max=9810, avg=115.60, stdev=95.50
    clat percentiles (usec):
     |  50.00th=[  98],  90.00th=[ 180],  99.00th=[ 420],  99.90th=[1200]

Signification : Vous obtenez IOPS, bande passante et distribution de latence. Les percentiles sont ce que ressentent vos utilisateurs. Une régression de pilote se manifeste souvent sur p99/p99.9 avant que la moyenne ne bouge beaucoup.

Décision : Comparez à la baseline. Si p99/p99.9 s’aggrave notablement, n’argumentez pas — rollback ou corrigez les paramètres qui ont changé.

Task 15: Check IOMMU mode (DMA performance surprises)

cr0x@server:~$ dmesg -T | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 8
[Wed Jan 22 09:01:11 2026] DMAR: IOMMU enabled
[Wed Jan 22 09:01:11 2026] DMAR: Intel(R) Virtualization Technology for Directed I/O

Signification : Certaines mises à jour de pilotes interagissent avec les valeurs par défaut IOMMU. Pour certains périphériques à fort débit, une mauvaise configuration peut ajouter une surcharge ou provoquer une contention de mapping.

Décision : Si les performances ont régressé et que le mode IOMMU a changé récemment, validez les recommandations plateforme pour votre charge (surtout DPDK/RDMA/GPU). Ne désactivez pas aveuglément ; testez sur une canary.

Task 16: Confirm CPU frequency policy (power saving can look like driver regression)

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

Signification : Après des mises à jour ou des changements BIOS, les gouverneurs peuvent basculer. Une fréquence CPU basse peut gonfler la latence des interruptions et des complétions I/O.

Décision : Si le governor est passé de performance à powersave, corrigez‑le d’abord sinon vos réglages vont chasser une cible mouvante.

Trois mini‑histoires du monde de l’entreprise

Mini‑histoire 1 : L’incident causé par une mauvaise hypothèse

Ils exploitaient un cluster d’analytics basé sur stockage. Rien d’exotique : Linux, cache NVMe, store d’objets en réseau, beaucoup de lectures parallèles. Une mise à jour du noyau est arrivée avec « correctifs de sécurité et pilotes mis à jour ». Le ticket de changement était propre. L’équipe supposait que les pilotes étaient hors sujet parce qu’« on est de toute façon CPU‑bound ».

Deux jours plus tard, les jobs nocturnes ont commencé à louper leurs deadlines. Pas catastrophique. Juste de quoi susciter une réunion quotidienne. Les graphiques étaient confus : le débit semblait à peu près stable, mais le temps d’exécution des jobs s’allongeait. Le CPU était plus bas qu’avant. Les gens prirent ça pour une bonne nouvelle.

Le vrai symptôme était la latence en queue sur de petites lectures. La nouvelle combinaison pilote/firmware NVMe a réactivé une politique agressive d’économie d’énergie. La latence moyenne a à peine bougé ; le p99.9 a doublé. La charge était un essaim de petites lectures, donc la queue lente a dominé le temps mur.

La mauvaise hypothèse n’était pas « les pilotes n’importent pas ». Elle était plus subtile : « si le débit est stable, le stockage va bien ». Le débit rassure parce qu’il est facile à tracer. La latence est celle qui paye votre salaire.

Ils ont désactivé l’état d’alimentation problématique sur des canaries, confirmé la récupération des percentiles avec de courts tests fio, puis propagé le réglage au cluster. Plus tard, ils ont rollbacké le firmware par précaution. Le postmortem contenait une ligne qui est restée : nous avons mesuré la mauvaise chose en premier.

Mini‑histoire 2 : L’optimisation qui a mal tourné

Une équipe plateforme voulait réduire l’utilisation CPU sur des nœuds API très chargés. Après une mise à jour du pilote NIC, ils ont vu apparaître plus de réglages exposés pour la modération d’interruptions. Ils ont augmenté la coalescence parce que les graphes promettaient moins d’interruptions. Le CPU a baissé. Ils ont déclaré victoire.

Puis l’incident est arrivé en costume propre : la latence client a dérivé à la hausse pendant les heures de pointe. Pas un pic, une dérive—plus difficile à alerter, parfait pour ruiner un SLA discrètement. Leurs dashboards affichaient moins de CPU et un débit réseau stable. Encore des métriques rassurantes.

Cause racine : la coalescence a augmenté le temps que les paquets passent en attente avant d’être traités. Excellent pour le débit. Mauvais pour la latence en queue. Pire, cela a interagi avec un pattern de requêtes déjà sensible au jitter, donc p99 a augmenté suffisamment pour déclencher des retries applicatives en cascade.

L’optimisation a échoué parce qu’elle optimisait le mauvais objectif. Ils visaient le CPU, pas la latence. La NIC faisait exactement ce qu’on lui demandait : regrouper le travail. La production faisait ce qu’elle a toujours fait : punir le mauvais compromis.

La correction a été chirurgicale : revenir au profil de coalescence known‑good, puis ajuster la distribution IRQ et les tailles de rings. Le CPU a un peu remonté, mais p99 s’est stabilisé. Leçon opérationnelle : « moins de CPU » n’est pas un objectif ; c’est une contrainte à gérer tout en respectant les SLO.

Mini‑histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une société de services financiers avait une politique de changement que tout le monde se moquait : pour les mises à jour de pilotes, ils exigeaient un bundle « avant/après ». Pas un processus énorme. Un script collectait la version du noyau, les versions de modules, les versions de firmware, les tunables sysfs clés, et un fio de 30 secondes plus un simple iperf dans un environnement contrôlé.

Le jour où une mise à jour du pilote de stockage est arrivée, un nœud canary a montré une petite mais constante hausse des percentiles de latence d’écriture. Rien n’était « down ». S’ils l’avaient propagée au cluster, la base de données aurait ralenti pendant le traitement de fin de journée, et ça serait devenu un vrai incident.

Le bundle de capture a rendu la régression évidente : l’ordonnanceur avait changé, nr_requests avait changé, et un paramètre de timeout avait bougé. La correction a été tout aussi ennuyeuse : pinner le paquet pilote, restaurer l’ordonnanceur et les réglages de file, et ouvrir un ticket fournisseur avec des diffs concrets.

Parce qu’ils l’ont attrapé sur la canary, personne n’a eu à expliquer aux dirigeants pourquoi « une mise à jour mineure » a causé une lenteur visible par les clients. L’équipe a encore raillé la politique, mais avec moins d’entrain. L’ennui est sous‑estimé en opérations.

Erreurs fréquentes : symptôme → cause racine → correctif

1) « Le débit est correct, mais l’appli est lente »

Symptôme : MB/s stable ; p95/p99 latence pire ; timeouts/retries apparaissent.

Cause racine : Modération d’interruptions augmentée ; APST/états d’alimentation activés ; comportement de mise en file modifié ; chemin de complétion concentré sur moins de CPUs.

Correctif : Validez les réglages de coalescence, les fonctionnalités NVMe power, la distribution IRQ. Utilisez les percentiles fio, pas la latence moyenne.

2) « Le CPU a baissé après la mise à jour, et les performances ont chuté aussi »

Symptôme : CPU inférieur ; débit inférieur ; latence des requêtes plus élevée.

Cause racine : Offloads désactivés ; lien négocié en bas débit ; périphérique revenu sur moins de lanes PCIe ; tailles de rings réduites.

Correctif : Vérifiez les offloads et la vitesse de lien via ethtool ; vérifiez LnkSta PCIe ; augmentez les rings si les drops montent.

3) « Un seul nœud est lent »

Symptôme : Un hôte régresse ; les pairs OK avec le même logiciel.

Cause racine : Mismatch firmware ; topologie PCIe/NUMA différente ; dérive de réglages BIOS ; différence de microcode ; révision du device.

Correctif : Comparez lspci -vv, ethtool -i, nvme id-ctrl entre nœuds ; alignez firmware/BIOS ; ne supposez pas l’homogénéité.

4) « Des drops réseau sont apparus après la mise à jour »

Symptôme : Compteurs RX dropped en hausse ; retransmissions ; jitter.

Cause racine : Tailles de rings réduites ; affinité IRQ effondrée ; coalescence trop agressive ; nombre de queues RSS modifié.

Correctif : Augmentez les rings ; assurez‑vous que plusieurs queues sont actives ; corrigez l’affinité ; réévaluez la coalescence pour la latence.

5) « Le stockage affiche des timeouts dans dmesg mais le disque est sain »

Symptôme : lignes nvme timeout/abort ; blocages occasionnels ; pas d’échec SMART.

Cause racine : Mismatch pilote/firmware ; transitions d’états d’alimentation ; resets de contrôleur ; problèmes d’intégrité PCIe exposés par le nouveau timing du pilote.

Correctif : Traitez‑le comme un problème de compatibilité ou de plateforme : testez le rollback, ajustez les fonctions d’alimentation, vérifiez la négociation PCIe, escaladez avec des logs reproductibles.

6) « Après la mise à jour, multipath est ‘up’ mais l’I/O est plus lente »

Symptôme : multipath -ll semble normal ; latence pire sous charge ; basculement de chemin bavard.

Cause racine : Politique changée (service-time vs round-robin) ; priorités ALUA mal prises en compte ; comportement queue_if_no_path modifié ; timing du vérificateur de chemin altéré.

Correctif : Validez policy/prio ; alignez multipath.conf ; confirmez le comportement ALUA ; retestez avec une charge contrôlée.

Listes de contrôle / plan étape par étape

Pré‑mise à jour (15 minutes qui évitent 5 heures d’incident)

  1. Définissez la surface de risque : quels pilotes/firmwares changent (NIC, HBA, NVMe, GPU, RDMA).
  2. Capturez un bundle baseline : uname -r, modinfo, ethtool -i/-k, lspci -vv (pour les devices clés), réglages scheduler/queue sysfs, multipath -ll si applicable.
  3. Choisissez 2–3 métriques golden : une métrique de débit et une métrique de latence en queue au minimum. Notez‑les dans le ticket de changement.
  4. Planifiez le rollback : étapes de downgrade de paquet, entrée noyau précédente, et contraintes de retour de firmware.
  5. Choisissez des canaries : hôtes qui représentent la variété matérielle, pas seulement « le moins occupé ».

Pendant la fenêtre de mise à jour (faites moins de choses, mais faites‑les volontairement)

  1. Mettez à jour seulement la tranche canary d’abord.
  2. Vérifiez le noyau/modules en cours d’exécution après reboot.
  3. Re‑vérifiez la largeur/vitesse du lien PCIe pour les devices touchés.
  4. Confirmez la vitesse négociée NIC et les offloads.
  5. Lancez un test court et standardisé (fio pour stockage ; un check latence/débit léger pour le réseau si vous avez un chemin sûr).
  6. Comparez à la baseline, pas à votre humeur.

Post‑mise à jour (la partie « rituel »)

  1. Réappliquez les tunables intentionnels : affinité IRQ, tailles de rings, réglages d’ordonnanceur, politique d’alimentation — tout ce que votre known‑good inclut.
  2. Surveillez les régressions retardées : les états d’alimentation et la récupération d’erreurs peuvent sembler corrects jusqu’au changement de forme de la charge.
  3. Étendez le rollout graduellement : si les canaries sont propres, procédez par lots avec une pause suffisante pour observer le comportement en charge réelle.
  4. Archivez le bundle after‑state : il devient votre nouvelle baseline s’il est bon, ou votre preuve s’il est mauvais.

Si vous suspectez une régression : échelle d’escalade

  1. Arrêtez l’hémorragie : drenez les workloads des nœuds affectés ou réduisez la concurrence.
  2. Reproduisez sur un nœud : exécutez le benchmark contrôlé et rassemblez les logs.
  3. Rollback de la plus petite chose possible : paquet pilote ou tunable d’abord ; rollback complet du noyau si nécessaire.
  4. Puis seulement, tunez : régler sans savoir ce qui a changé est la façon dont on finit avec un système fragile que seule une personne comprend.

FAQ

1) Pourquoi les mises à jour de pilotes causent‑elles des régressions de performance même si le matériel est identique ?

Parce que les pilotes encodent des politiques : dimensionnement des files, comportement d’interruptions, valeurs par défaut d’offload, gestion d’alimentation, récupération d’erreurs. Changer la politique change les performances.

2) Est‑il préférable de mettre à jour noyau et pilotes séparément ou ensemble ?

Séparément est plus simple pour l’attribution ; ensemble est parfois inévitable. Si vous devez les faire ensemble, augmentez le temps canary et capturez plus d’éléments « avant/après ».

3) Quel est le contrôle le plus rapide pour une régression NIC ?

Commencez par la vitesse/duplex du lien et les compteurs de drops. Si vous négociez en bas ou que vous perdez des paquets, tout le reste est une distraction.

4) Quel est le contrôle le plus rapide pour une régression stockage ?

iostat pour await/%util plus dmesg pour timeouts/resets. Si le noyau timeoute des I/O, l’histoire de performance est déjà écrite.

5) Dois‑je toujours désactiver NVMe APST sur les serveurs ?

Non. Vous devriez le baseliner. Certains devices se comportent bien ; d’autres punissent la latence en queue. Si vous avez des SLO p99, testez APST on/off avec des percentiles fio.

6) irqbalance peut‑il « réparer » automatiquement les problèmes d’interruptions ?

Parfois. Il peut aussi annuler un pinning intentionnel ou faire des choix corrects pour la distribution CPU moyenne mais mauvais pour la latence. Traitez‑le comme un outil, pas une garantie.

7) Pourquoi augmenter les tailles de rings a aidé le débit mais pas la latence ?

Des rings plus grands réduisent les drops et améliorent le débit sous rafale, mais peuvent aussi augmenter le buffering, ajoutant de la latence. Si la latence est prioritaire, réglez la coalescence et la distribution IRQ avec soin.

8) Quand dois‑je rollbacker plutôt que tuner ?

Si vous voyez de nouvelles erreurs/timeouts/resets, rollbackez. Si c’est un changement propre de performance sans erreurs et que vous pouvez lier cela à un changement de valeur par défaut, le tuning peut être approprié — d’abord sur des canaries.

9) Comment éviter le « théâtre des benchmarks » après des mises à jour ?

Utilisez des tests courts et standardisés et comparez le même test sur un hôte known‑good. Enregistrez percentiles, distribution CPU, et les tunables clés. Ne faites pas de cherry‑pick.

10) Que faire si la régression n’apparaît qu’en pointe et que je ne peux pas la reproduire ?

Cherchez des indicateurs de saturation : drops, mise en file, hotspots softirq sur un seul cœur, rétrogradations PCIe sous charge, et transitions d’états d’alimentation. Même si vous ne pouvez pas reproduire, vous pouvez corréler.

Conclusion : prochaines étapes concrètes

Les mises à jour de pilotes ne sont pas effrayantes. Les mises à jour de pilotes non mesurées le sont. Le remède n’est pas l’héroïsme ; c’est un rituel répétable qui traite la performance comme une propriété de correction à part entière.

  1. Construisez un bundle baseline (versions, firmware, tunables, un court fio, un check NIC) et rendez‑le obligatoire pour les changements de pilotes.
  2. Adoptez la feuille de route de diagnostic rapide : définissez « lent », choisissez le pipeline, chassez le paramètre revenu à la valeur par défaut, prouvez‑le avec un test, atténuez en sécurité.
  3. Canarisez chaque mise à jour de pilote sur les variantes matérielles. Si vous ne pouvez pas canariser, vous n’appliquez pas une mise à jour — vous pariez.
  4. Notez vos tunables known‑good et réappliquez‑les volontairement après les mises à jour. Les valeurs par défaut ne sont pas votre gestion de configuration.
  5. Préférez le rollback au « tuning mystère » lorsque vous voyez des timeouts/resets/erreurs. Les régressions de performance avec erreurs sont la façon dont se pratiquent les outages.

Si vous faites cela de façon cohérente, la « performance post‑mise à jour » cesse d’être un genre dramatique et devient une ligne de la checklist. La production adore ça.

← Précédent
Ubuntu 24.04 : Certbot renouvelle mais votre application échoue — corriger les permissions et recharger les hooks
Suivant →
ROPs, TMUs, SMs et CUs : anatomie du GPU en langage clair

Laisser un commentaire