Je vais vous expliquer étape par étape comment je SoftIRQ sous Linux- mesurer l'utilisation des ressources, mettre en évidence les goulots d'étranglement et reprendre le contrôle en modifiant quelques paramètres du noyau. Ce faisant, je privilégie les effets mesurables : des temps de traitement plus courts Latence, des cœurs de processeur équilibrés et un traitement stable des paquets en cas de forte charge réseau.
Points centraux
- Points de mesure Comprendre : /proc/softirqs, softnet_stat, interrupts
- Symptômes Détecter : charge ksoftirqd, pertes de paquets, pics de latence
- Tuning paramètres : netdev_budget et netdev_budget_usecs
- Distribution Sauvegarder : affinité IRQ, RSS, mappage des files d'attente
- Suivi Exécuter : mpstat, perf, Tracing
Aperçu des SoftIRQ : comment fonctionne le noyau
Après une interruption matérielle, le noyau transfère une partie du travail vers ce qu'on appelle des SoftIRQs, afin que les chemins critiques soient rapidement libérés et que le traitement puisse rester prévisible. C'est notamment dans le chemin réseau que les gestionnaires NAPI collectent les paquets provenant des anneaux des cartes réseau, déclenchent le traitement des protocoles et transmettent les données au Pile réseau. Lorsque le nombre d'événements augmente, des threads par CPU tels que ksoftirqd/cpuN prennent le relais et se chargent de l'interrogation et du traitement des tâches en attente. Ce découplage améliore le débit global, mais peut, en cas de surcharge, entraîner de longs temps d'exécution des SoftIRQ sur certains Noyaux entraîner. Je surveille donc dès le début si les chemins NET_RX et NET_TX dominent et si ksoftirqd consomme de manière visible du temps CPU. Cela me permet de détecter quand les SoftIRQ deviennent un goulot d'étranglement et de prendre d'autres Optimisations sont nécessaires.
Identifier les symptômes typiques d'une charge élevée des SoftIRQ
Je constate d'abord une charge SoftIRQ importante par le fait qu'elle reste constamment élevée CPU du noyau et les processus ksoftirqd, qui restent au maximum pendant plusieurs secondes. Parallèlement, les latences des E/S réseau et des E/S par blocs augmentent, ce qui se traduit par des handshakes TLS laborieux ou des APIs a déclaré. Les pertes de paquets se multiplient souvent, tandis que les anneaux de la carte réseau sont saturés et que les retards s'accumulent. Lorsque les interruptions sont mal réparties, le processeur 0 en pâtit souvent fortement, car de nombreuses lignes d'IRQ, ainsi que les tâches qui en découlent, sont concentrées sur un Noyau se produire. Ce blocage sur un seul cœur augmente les temps d'attente pour les services et réduit le débit effectif. Je vérifie donc si ce phénomène est systématique ou s'il ne se produit que dans Peaks conduit.
Points de mesure clés : bien interpréter /proc et les outils
Je commence par /proc/softirqs, car c'est là que je peux voir, pour chaque processeur et chaque type, à quel point environ NET_RX, NET_TX, TIMER ou BLOCK augmentent. Dans /proc/net/softnet_stat, j'examine les lignes en me concentrant sur les champs qui signalent des dépassements de budget ou des paquets perdus, ce qui, en cas d'augmentation constante, indique clairement que Cycles d'interrogation suggère. /proc/interrupts permet ensuite de déterminer si les interruptions matérielles sont réparties de manière inégale entre les processeurs et quelles sont les IRQ les plus actives. Des outils tels que mpstat, top ou htop m'aident à identifier ksoftirqd/cpuN et à analyser la répartition des Temps Softirq à évaluer par cœur. Si nécessaire, perf fournit des points chauds dans la pile, ce qui me permet d'identifier les gestionnaires et les chemins de pilotes qui consomment le plus de temps. Le tableau suivant résume les principaux points de mesure, indicateurs et cas typiques Actions ensemble.
| Point de mesure | Principaux domaines/indicateurs | interprétation | Action |
|---|---|---|---|
| /proc/softirqs | NET_RX, NET_TX, BLOCK respectivement CPU | On constate une répartition inégale de la charge | Régler l'affinité IRQ, activer RSS |
| /proc/net/softnet_stat | Compteur de budget/de baisses, troisième Colonne | Budgets insuffisants, les colis s'accumulent | Augmenter netdev_budget/usecs, vérifier RPS |
| /proc/interrupts | Lignes IRQ par CPU, mappage de files d'attente | Trop d'IRQ sur un nombre restreint de cœurs | Vérifier irqbalance, définir smp_affinity |
| mpstat / perf | %soft, points d'accès, Stacks | Les nœuds et les nœuds principaux dominants sont visibles | Donner la priorité à l'optimisation des pilotes et de la pile |
Causes et schémas des charges élevées
Les pics sont souvent dus à une très forte Débit, de nombreuses connexions parallèles ou des rafales UDP qui dominent NET_RX. Parfois, les paramètres par défaut des pilotes prévoient de petits lots, ce qui génère un nombre excessif d'interruptions et surcharge ksoftirqd, tandis que GRO/LRO reste inutilisé reste. Des affinités défavorables concentrent le travail sur le CPU 0, alors que plusieurs files d'attente seraient disponibles et que le RSS pourrait faciliter la répartition. Dans les machines virtuelles, les vNIC sollicitent le noyau hôte, ce qui augmente les temps de SoftIRQ sur l'hôte au détriment des invités augmente. Les « overlays » de conteneurs ajoutent des paquets supplémentaires à la pile, ce qui transforme soudainement des flux simples en chemins plus complexes. Ce n’est qu’en combinant répartition, budget et Batching Cela donne une image cohérente.
Surveillance ciblée : rendre les SoftIRQ visibles
Pour assurer un suivi efficace, je lis régulièrement /proc- Je sélectionne les interfaces et je les associe à des métriques de l'hôte telles que la charge et les latences de planification. Je établis une corrélation entre les pics de NET_RX et les compteurs de paquets perdus afin de déterminer si seul le débit augmente ou si des paquets sont perdus en cours de route. restent. La commande `mpstat` me fournit, pour chaque CPU, la répartition du temps entre les SoftIRQ, tandis que `top`/`htop` affichent les threads `ksoftirqd/cpuN` qui attirent l'attention. À l'aide de `perf record`/`perf top`, j'isole les chemins coûteux, par exemple les déchargements de sommes de contrôle, la fusion GRO ou qdisc-Travail. Les traces basées sur eBPF ou ftrace indiquent le début et la fin des gestionnaires, ce qui me permet d'évaluer leur durée d'exécution et les effets de la planification. On obtient ainsi une vision claire de la situation grâce aux métriques, aux courbes temporelles et Points chauds.
Réglage à l'aide de netdev_budget et netdev_budget_usecs
Si le chemin NAPI est trop court, je l'augmente progressivement net.core.netdev_budget et net.core.netdev_budget_usecs, afin de traiter davantage de paquets par cycle d’interrogation. Je surveille alors la troisième colonne dans /proc/net/softnet_stat ; si la courbe de croissance s’aplatit, cela signifie que les modifications ont porté leurs fruits et que les latences sont plus court. J'augmente modérément ces valeurs, par exemple de 300 à 600 paquets et de 2 000 à 4 000 microsecondes, et je vérifie si les autres tâches conservent suffisamment de temps CPU. Un excès bloque le planificateur, c’est pourquoi je surveille de près les pics de charge, les changements de contexte et la longueur des files d’attente d’exécution. accompagne. Il est également utile de vérifier les paramètres RPS/RFS, GRO/LRO et MTU afin d'exploiter au mieux le regroupement de paquets et la taille des paquets. Pour réduire les avalanches d'interruptions, je tiens compte Coalescence d'interruption et réglez les mêmes paramètres avec les pilotes NIC, si ce curseur est disponible est.
Optimisation de la répartition des interruptions et de l'affinité IRQ
Pour éviter les goulots d'étranglement liés à un seul cœur, je répartis les IRQ entre plusieurs CPUs, soit via irqbalance, soit à l'aide de masques smp_affinity définis manuellement. Pour cela, je me base sur les files d'attente des cartes réseau existantes et j'active le RSS afin que le matériel répartisse uniformément les flux entrants et que chaque cœur bénéficie d'une charge de travail allégée lots . Je veille à ne pas mélanger les IRQ de contrôle avec les chemins de données critiques afin de préserver la localité du cache et la prévisibilité. Des affinités correctement définies réduisent les latences et limitent les pertes, car le traitement des SoftIRQ ne reste plus bloqué sur un seul cœur reste. Les pilotes affichent souvent les associations entre les files d'attente et les cœurs dans sysfs ; c'est là que je vérifie si chaque file d'attente dispose d'un cœur correspondant et qu'il n'y a pas d'asymétries. Pour aller plus loin, je me réfère à des guides tels que Affinité IRQ, afin de prendre également en compte les aspects NUMA et l'effet du cache prendre en compte.
Guide pratique : des symptômes à la solution
Pour commencer, je vérifie les symptômes : ksoftirqd/cpuN dans top, la part des SoftIRQ par cœur dans mpstat et des pics NET_RX marquants. Je recueille ensuite des données concrètes à partir de /proc/softirqs, /proc/net/softnet_stat et /proc/interrupts afin de recenser les chemins dominants et les répartitions déséquilibrées. Je procède ensuite à de petits ajustements, en commençant par les budgets netdev, puis en passant à l'affinité IRQ et au RSS, à chaque fois avec une surveillance minutieuse Contrôle. Si des pertes de paquets persistent, je vérifie les paramètres des pilotes, les options de coalescing, les déchargements et le comportement GRO/LRO. Sur les hôtes de machines virtuelles ou de conteneurs, j'évalue en outre la manière dont les vNIC interagissent avec la pile de l'hôte physique et où se situent les Points chauds réelle. J'évalue chaque modification à l'aide de séries chronologiques, jusqu'à ce que les indicateurs et les latences se stabilisent à un bon niveau atterrissent.
Bonnes pratiques pour une performance durable
Je mets en place une surveillance régulière des compteurs SoftIRQ, car seules des valeurs constantes Transparence évite les retours en arrière en cas de goulots d'étranglement. Les versions actuelles du noyau sont avantageuses, car NAPI et Stack continuent d'être améliorés en interne, ce qui offre des réserves pour les situations difficiles Charges mettre en place. Une répartition équilibrée sur plusieurs cœurs reste indispensable, tout comme des budgets raisonnables permettant de traiter suffisamment de paquets sans saturer le planificateur. Pour les profils d'hébergement générant un trafic HTTPS et API important, il vaut la peine de se pencher sur SoftIRQ dans l'hébergement, car c'est là que l'on constate à quel point le choix des cartes réseau (NIC), des files d'attente et des réglages optimise la qualité de service. Lors de la planification des capacités, je tiens compte des cœurs de processeur, des fonctionnalités des cartes réseau, de la mémoire et des zones NUMA, afin de disposer de réserves avant que Pointes survenir. La plateforme reste ainsi résiliente et réagit de manière fluide aux fluctuations saisonnières ou liées aux campagnes heures de pointe.
softnet_stat en détail : ce que signifient réellement ces chiffres
Pour affiner davantage mes connaissances, je lis /proc/net/softnet_stat au fur et à mesure, et interprète notamment les premières colonnes. Les champs initiaux comptabilisent les paquets traités et rejetés par CPU, les troisième colonne indique une contrainte de temps (en résumé : budget ou délai insuffisant, NAPI doit s'arrêter). Si les « drops » ou la pression temporelle augmentent de manière linéaire avec la charge, les budgets ou la coalescence constituent les premiers leviers à actionner. En revanche, si j’observe des pics sans augmentation durable, les rafales ne font que concentrer le travail à court terme – dans ce cas, le traitement par lots (GRO) s’avère plus souvent efficace que des budgets importants. Les noyaux plus récents enrichissent les statistiques de champs pour les RPS/RFS et les limites de flux ; si ceux-ci augmentent, je répartis plus judicieusement via les RPS ou je réduis les RFS lorsque leurs consultations deviennent plus coûteuses que leur utilité. Je corrèle toujours les compteurs avec /proc/softirqs: Si la valeur NET_RX augmente sur certains cœurs parallèlement à une pression temporelle dans softnet_stat, je me concentre d'abord sur la répartition (IRQ/RSS) et, dans un deuxième temps seulement, sur des budgets plus importants.
RPS/RFS et XPS : maîtrise de la gestion logicielle et de l'optimisation des files d'attente
Si le RSS matériel fait défaut ou est insuffisant, je configure RPS (Receive Packet Steering) afin de répartir la charge de réception entre plusieurs cœurs. À l'aide de rps_cpus, j'attribue aux files d'attente de réception les cœurs qui correspondent aux travailleurs actifs et, dans la mesure du possible, NUMA-proche se trouvent. Dans de nombreux flux, j'ajoute RFS (Receive Flow Steering), afin que les paquets entrants aboutissent là où les sockets correspondantes sont traitées – ce qui est bénéfique pour la localité du cache, tant que les tables de flux ne deviennent pas un goulot d'étranglement. Du côté de l'envoi, cela aide à XPS (Transmit Packet Steering), qui consiste à adapter le choix de la file d'attente d'émission (TX) à l'affectation de l'application au processeur. L'objectif est de faire en sorte qu'un flux passe systématiquement par la même file d'attente de réception/émission (RX/TX) et le même noyau, ce qui réduit les latences et GRO- Les lots deviennent plus volumineux. Je teste toujours les répartitions par étapes : je commence par activer le RPS sur quelques files d’attente, je mesure l’impact (pertes, %soft, latences), puis j’ajoute le RFS/XPS. Si le RPS entraîne une surcharge des cœurs ou une dégradation du taux de réussite L3, je réduis à nouveau les masques CPU ou j’associe plus étroitement les files d’attente aux cœurs des services concernés.
NUMA, isolation des processeurs et interactions entre les planificateurs
Les meilleurs budgets et répartitions ne servent pas à grand-chose si les accès à la mémoire empruntent des chemins NUMA trop longs. Je veille à ce que les interruptions NIC, le traitement NAPI et les processus demandeurs se trouvent, dans la mesure du possible, au sein de la même Domaine NUMA restent. Dans les configurations dotées de cœurs dédiés au temps réel ou à faible latence, je les isole à l'aide de politiques CPU et Cgroup, et j'y exclue délibérément toute activité liée aux SoftIRQ. ksoftirqd ne doit pas aboutir sur des cœurs isolés, sinon les paquets s’accumulent sans que l’on s’en aperçoive. À l’inverse, les cœurs isolés ne doivent pas se retrouver totalement privés de gestion des IRQ lorsqu’ils terminent des chemins de données – une question évidente d’affinité et de Entretien ménager- Une stratégie est indispensable. Pour les charges de travail soumises à des SLO stricts, j'évite les priorités SCHED_FIFO/RR trop agressives, qui pourraient évincer l'exécution NAPI. Je surveille la longueur des files d’attente d’exécution, les réveils et les taux de préemption : lorsque les temps de SoftIRQ augmentent à mesure que l’interactivité de l’application s’accroît, j’ajuste la granularité et les affinités plutôt que d’augmenter les budgets de manière globale.
qdisc, déchargements et Busy-Poll : trouver le juste équilibre entre latence et débit
Sur le chemin de sortie, chaque qdisc- Temps CPU par opération. Je choisis la discipline en fonction du profil : fq_codel aide à lutter contre le « buffer bloat » et lisse les pics de trafic, tandis que mq-des variantes de cartes réseau à files d'attente multiples. En cas de débit de données pur sur des liaisons stables, un qdisc plus léger peut minimiser les pics de latence. Sur l'entrée, il est utile d'ajuster avec précision GRO/TSO/GSO: Les lots plus volumineux réduisent le taux de SoftIRQ, mais augmentent, dans certains cas limites, le temps de traitement des paquets dans la pile. Je vérifie si les intervalles de vidage GRO ou les déchargements matériels entraînent la formation d'agrégats trop volumineux, ce qui nuit à l'application. Pour les chemins où la latence est un facteur critique, je définis busy_poll et j'utilise « busy_read » avec parcimonie pour extraire activement les paquets du pilote – mais en surveillant de près le processus, afin que les autres tâches ne soient pas négligées. De même, je configure Coalescence d'interruption En ce qui concerne les pics de trafic : augmenter légèrement la durée des micro-secondes améliore le débit, mais une augmentation excessive retarde les ACK et allonge les phases de négociation. Il est important d'évaluer chaque modification séparément : les pics simulés, les véritables pics de production et les périodes d'inactivité présentent souvent des profils de latence différents.
Liste de contrôle pour le diagnostic et restauration en toute sécurité
Je procède systématiquement aux modifications en suivant une courte liste de contrôle : 1) Vérifier les symptômes (ksoftirqd, %soft, Drops). 2) Vérifier la répartition (/proc/interrupts, Queue->CPU, état RSS/RPS). 3) Ajuster les budgets, observer l'effet dans softnet_stat surveiller (la pression temporelle diminue, les pertes stagnent). 4) Affiner les réglages des offloads/coalescing, examiner le qdisc. 5) Vérifier à nouveau les liaisons NUMA/CPU et les cgroups. Chaque étape se termine par une nette amélioration des indicateurs ou par la Retour en arrière jusqu'au dernier état satisfaisant. Je consigne les valeurs cibles et réelles (latence P95/P99, %soft par cœur, taux de perte, changements de contexte) afin que les itérations ultérieures ne se déroulent pas à l'aveuglette. Si plusieurs petits gains ne permettent pas d’alléger la charge, j’interromps le processus et je recherche les causes structurelles (goulots d’étranglement dans les files d’attente, blocs d’application, influences du stockage). Cette rigueur permet d’éviter les corrélations erronées et de se prémunir contre les spirales d’optimisation qui, bien qu’elles augmentent les chiffres de débit, détériorent l’interactivité et la stabilité.
Distinguer clairement les cas limites et les profils de charge de travail
Je fais délibérément la distinction entre les transferts en masse, les API sensibles à la latence et le trafic en rafales UDP-Trafic. Pour les données en masse, je privilégie le traitement par lots et la fusion dès que possible, tant qu’il n’y a pas de perte de paquets. Pour le trafic API, je privilégie une répartition homogène, des lots limités et des latences E2E stables, même si le débit maximal diminue légèrement en valeur nominale. Je lutte de préférence contre les rafales UDP par l’élargissement des files d’attente et les affinités ; sinon, des budgets trop importants ne font qu’accroître le blocage en tête de file. Si un environnement utilise de nombreux sauts de conteneurs ou de superpositions, je prévois un travail supplémentaire au niveau de la pile et je répartis plus largement la charge des SoftIRQ. J’évalue également séparément les surcoûts liés au pare-feu et à Conntrack : lorsque les tables atteignent leurs limites, la charge SoftIRQ augmente inévitablement, quelle que soit la qualité de la répartition des IRQ. Ce n’est que lorsque les chemins par profil sont systématiquement allégés que le réglage fin des derniers pourcents en vaut la peine.
Les SoftIRQ dans les environnements cloud et de conteneurs
Dans les environnements virtualisés, la charge est acheminée via des vSwitches, des réseaux superposés et des piles d'hôtes ; c'est pourquoi je dois tenir compte à la fois des environnements invités et des environnements hôtesMétriques analyser. Des temps SoftIRQ élevés sur l'hôte ralentissent immédiatement les conteneurs et les machines virtuelles, même si les systèmes invités semblent fonctionner sans problème agissent. Je vérifie donc les opérations d'offload et de coalescing sur la carte réseau physique, tandis que RPS/RFS, sur l'hôte, répartit plus efficacement le trafic via la voie logicielle. Pour les charges de travail en conteneurs, je vérifie si les limites des cgroups pour le CPU et le traitement des IRQ sont définies de manière appropriée, afin que les services importants ne se retrouvent pas dans Files d'attente mourir de faim. Les vNIC prenant en charge plusieurs files d'attente (Multi-Queue) avec RSS améliorent le parallélisme, à condition que les affinités et les mappages de files d'attente soient correctement configurés. Grâce à cette approche, je maintiens des chemins de données courts et je stabilise Latence et des performances fiables et reproductibles.
Résumé : Maîtriser parfaitement l'analyse des SoftIRQ
Pour analyser correctement la charge des SoftIRQ, il faut utiliser des points de mesure clairs, examiner les répartitions et mettre en place des mesures échelonnées Étapes. Je commence par /proc/softirqs et softnet_stat, j'établis une corrélation avec ksoftirqd et mpstat, puis j'en déduis l'ordre de mes Mesures. Je commence par ajuster les paramètres netdev_budget et netdev_budget_usecs, puis j'optimise l'affinité IRQ, le RSS ainsi que les options de traitement par lots telles que GRO et les déchargements. Chaque modification reste minime, est mesurée et n'est poursuivie que si elle a un effet positif, jusqu'à ce que les pertes disparaissent et Latence diminuer. Cette discipline permet d'éviter les effets secondaires, de préserver l'interactivité au niveau du processeur et de maintenir les services même en cas de pics de trafic réactif. Ainsi, les performances de Linux restent transparentes, robustes et adaptables, sans que des points de goulot d'étranglement cachés n'affectent la Stabilité mettre en danger.


