Ik leg stap voor stap uit hoe ik Linux SoftIRQ-de belasting meet, knelpunten zichtbaar maak en met een paar kernel-aanpassingen weer de controle terugkrijg. Daarbij geef ik voorrang aan meetbare resultaten: kortere Latencies, evenwichtige CPU-kernen en stabiele pakketverwerking bij een hoge netwerkbelasting.
Centrale punten
- Meetpunten begrijpen: /proc/softirqs, softnet_stat, interrupts
- Symptomen herkennen: ksoftirqd-belasting, pakketverlies, pieken in de latentie
- Afstemmen instellingen: netdev_budget en netdev_budget_usecs
- Distributie opslaan: IRQ-affiniteit, RSS, wachtrijtoewijzing
- Controle uitvoeren: mpstat, perf, Tracing
SoftIRQ's in een notendop: hoe de kernel werkt
Na een hardware-interrupt verschuift de kernel delen van het werk naar zogenaamde SoftIRQ's, zodat kritieke paden snel vrijkomen en de verwerking voorspelbaar blijft. Met name in het netwerkpad verzamelen NAPI-handlers pakketten uit de NIC-ringen, zetten ze protocolbewerkingen in gang en geven ze de gegevens door aan de Netwerkstapel. Als het aantal gebeurtenissen toeneemt, nemen per-CPU-threads zoals ksoftirqd/cpuN het over en zorgen ze voor de polling en de nabewerking. Deze ontkoppeling verbetert de totale doorvoercapaciteit, maar kan bij overbelasting leiden tot lange SoftIRQ-looptijden op afzonderlijke Kernen leiden. Daarom houd ik al in een vroeg stadium in de gaten of NET_RX- en NET_TX-paden de overhand hebben en of ksoftirqd zichtbaar CPU-tijd opslokt. Zo kan ik vaststellen wanneer SoftIRQ’s een bottleneck worden en verdere Optimalisaties nodig zijn.
Typische symptomen van een hoge SoftIRQ-belasting herkennen
Een aanzienlijke SoftIRQ-belasting merk ik in de eerste plaats aan een constant hoge Kernel-CPU en ksoftirqd-processen die gedurende vele seconden pieken vertonen. Tegelijkertijd nemen de latenties voor netwerk- en blok-I/O toe, wat zich uit in trage TLS-handshakes of haperende API's uit. Vaak raken pakketten zoek, terwijl de ringen van de netwerkkaart overlopen en de achterstanden toenemen. Als interrupts slecht worden verdeeld, heeft CPU 0 daar vaak zwaar onder te lijden, omdat veel IRQ-lijnen, inclusief de daaruit voortvloeiende verwerking, op één Kern landen. Deze binding aan één kern zorgt ervoor dat de wachttijden voor diensten toenemen en de effectieve doorvoer afneemt. Ik onderzoek daarom of dit patroon systematisch is of slechts Pieken leidt.
Belangrijke meetpunten: /proc en tools correct interpreteren
Ik begin met /proc/softirqs, want daar kan ik per CPU en type zien in hoeverre NET_RX, NET_TX, TIMER of BLOCK stijgen. In /proc/net/softnet_stat controleer ik de regels, waarbij ik vooral let op velden die wijzen op overschrijdingen van het budget of drops, wat bij een gestage stijging duidelijk duidt op te korte Pollingcycli wijst erop. /proc/interrupts laat vervolgens zien of hardware-interrupts ongelijkmatig over de CPU’s worden verdeeld en welke IRQ’s het meest opvallen. Tools zoals mpstat, top of htop helpen me om ksoftirqd/cpuN te identificeren en de verdeling van de Softirq-tijden per kern te beoordelen. Indien nodig geeft perf hotspots in de stack weer, zodat ik handlers en stuurprogramma-paden met een hoog tijdsaandeel kan vinden. De volgende tabel geeft een overzicht van de belangrijkste meetpunten, indicatoren en typische Acties samen.
| Meetpunt | Belangrijkste gebieden/indicatoren | Interpretatie | Actie |
|---|---|---|---|
| /proc/softirqs | NET_RX, NET_TX, BLOCK per CPU | Onregelmatige lastverdeling waarneembaar | IRQ-affiniteit aanpassen, RSS inschakelen |
| /proc/net/softnet_stat | Budget-/drop-teller, derde Kolom | Budgetten te klein, pakketten blijven liggen | netdev_budget/usecs verhogen, RPS controleren |
| /proc/onderbrekingen | IRQ-lijnen per CPU, wachtrijtoewijzing | Te veel IRQ's op te weinig kernen | irqbalance controleren, smp_affinity instellen |
| mpstat / perf | %soft, hotspots, Stapels | Dominante handlers en kernen zichtbaar | Prioriteit geven aan het afstemmen van stuurprogramma’s en stacks |
Oorzaken en patronen van hoge belasting
Pieken ontstaan vaak door zeer hoge Doorvoer, veel parallelle verbindingen of UDP-bursts die NET_RX domineren. Soms zijn in de standaardinstellingen van stuurprogramma’s kleine batches ingesteld, waardoor er te veel interrupts ontstaan en ksoftirqd overbelast raakt, terwijl GRO/LRO ongebruikt blijft blijft. Ongunstige affiniteiten concentreren de belasting op CPU 0, hoewel er meerdere wachtrijen beschikbaar zouden zijn en RSS de verdeling zou kunnen vergemakkelijken. In virtuele machines belasten vNIC’s de host-kernel, waardoor de SoftIRQ-tijden in de host ten koste gaan van de gasten verhoogt. Container-overlays voegen extra pakketten toe aan de stack, waardoor eenvoudige flows plotseling complexere paden worden. Pas de combinatie van distributie, budget en Batching dat geeft een compleet beeld.
Gericht monitoren: SoftIRQ's zichtbaar maken
Voor een degelijke monitoring lees ik regelmatig /proc-Ik selecteer interfaces en koppel ze aan host-metrieken zoals belasting en scheduler-latenties. Ik breng stijgingen in NET_RX in verband met drop-tellers om te achterhalen of alleen de doorvoer toeneemt of dat er pakketten onderweg verloren gaan blijf. mpstat geeft me per CPU de tijdsverdeling voor SoftIRQ’s, terwijl top/htop de opvallende ksoftirqd/cpuN-threads weergeven. Met perf record/perf top breng ik kostbare paden in kaart, bijvoorbeeld checksum-offloads, GRO-samenvoeging of qdisc-Werk. Traces op basis van eBPF of ftrace geven het begin en einde van de handlers weer, waardoor ik de uitvoeringstijden van handlers en de effecten van de scheduling kan beoordelen. Zo ontstaat een duidelijk beeld van de situatie op basis van statistieken, tijdsverloop en Hotspots.
Tuning met netdev_budget en netdev_budget_usecs
Als het NAPI-pad te kort is, verhoog ik het stapsgewijs net.core.netdev_budget en net.core.netdev_budget_usecs, om meer pakketten per pollingcyclus te verwerken. Daarbij houd ik de derde kolom in /proc/net/softnet_stat in de gaten; als de stijging afneemt, zijn de aanpassingen raak en worden de latenties korter. Ik verhoog de waarden geleidelijk, bijvoorbeeld van 300 naar 600 pakketten en van 2000 naar 4000 microseconden, en controleer of andere taken voldoende CPU-tijd overhouden. Een te grote belasting blokkeert de scheduler, daarom houd ik piekbelastingen, contextwisselingen en de lengte van de runqueue nauwlettend in de gaten begeleid. Daarnaast is het de moeite waard om RPS/RFS, GRO/LRO en de MTU te controleren, om op een zinvolle manier gebruik te maken van batching en pakketgroottes. Om het aantal interrupts te verminderen, houd ik rekening met Interrupt samenvoegen en stel dezelfde fijnafstellingen in met de NIC-stuurprogramma's, indien deze schakelaar beschikbaar is is.
Interrupt-toewijzing en IRQ-affiniteit optimaliseren
Om bottlenecks in één kern te voorkomen, verdeel ik de IRQ’s over meerdere CPU's, hetzij via irqbalance, hetzij met handmatige smp_affinity-maskers. Daarbij houd ik rekening met de bestaande NIC-wachtrijen en schakel ik RSS in, zodat de hardware inkomende flows gelijkmatig verdeelt en elke kern werkverlichtende Batches ontvangt. Ik zorg ervoor dat ik besturings-IRQ’s niet vermeng met intensief gebruikte gegevenspaden, om de cache-localiteit en de planbaarheid te behouden. Correct ingestelde affiniteiten verlagen de latentie en verminderen het aantal drops, omdat de verwerking van SoftIRQ’s niet langer op één kern vastloopt blijft. Drivers tonen vaak de toewijzingen van wachtrijen aan CPU’s in sysfs; daar controleer ik of elke wachtrij een bijbehorende kern heeft en of er geen asymmetrieën ontstaan. Voor een meer diepgaande analyse baseer ik me op handleidingen zoals IRQ affiniteit, om ook NUMA-aspecten en cache-effecten te rekening houden met.
Praktische gids: van symptomen naar oplossing
Eerst controleer ik de symptomen: ksoftirqd/cpuN in top, het aandeel SoftIRQ’s per kern in mpstat en opvallende NET_RX-pieken. Vervolgens verzamel ik harde feiten uit /proc/softirqs, /proc/net/softnet_stat en /proc/interrupts om dominante paden en scheve verdelingen vast te leggen. Vervolgens voer ik kleine afstemmingsstappen uit, eerst op de netdev-budgetten, gevolgd door IRQ-affiniteit en RSS, telkens met nauwkeurige Controle. Als er nog steeds drops zichtbaar zijn, controleer ik de driverinstellingen, coalescing-opties, offloads en het GRO/LRO-gedrag. In VM- of containerhosts onderzoek ik bovendien hoe de vNIC’s communiceren met de fysieke hoststack en waar de Hotspots werkelijk liggen. Ik evalueer elke wijziging aan de hand van tijdreeksen, totdat de statistieken en latenties stabiel op een goed niveau liggen land.
Best practices voor duurzame prestaties
Ik zorg ervoor dat de SoftIRQ-tellers regelmatig worden gecontroleerd, want alleen constante Transparantie voorkomt dat er opnieuw knelpunten ontstaan. De nieuwste kernelversies loont de moeite, omdat NAPI en Stack intern verder worden verbeterd en daarmee reserves creëren voor zware Ladingen zorgen. Een evenwichtige verdeling over meerdere cores blijft een must, net als verstandige budgetten die voldoende pakketten verwerken zonder de scheduler te overbelasten. Voor hostingprofielen met veel HTTPS- en API-verkeer is het de moeite waard om eens te kijken naar SoftIRQ bij hosting, want daar wordt duidelijk hoezeer de keuze van NIC’s, wachtrijen en afstemming de servicekwaliteit verbetert. Bij de capaciteitsplanning houd ik rekening met CPU-kernen, NIC-functies, geheugen en NUMA-zones, zodat er reserves beschikbaar zijn voordat Tips binnenkomen. Zo blijft het platform robuust en reageert het soepel op seizoensgebonden of campagnegerelateerde spitsuren.
softnet_stat in detail: wat de cijfers werkelijk betekenen
Om mijn kennis gericht aan te scherpen, lees ik /proc/net/softnet_stat in de loop en interpreteer met name de eerste kolommen. De eerste velden geven het aantal verwerkte en afgewezen pakketten per CPU weer, de derde kolom wijst op tijdsdruk (kort gezegd: te weinig budget/tijd, NAPI moet worden afgebroken). Als de drops of de tijdsdruk lineair toenemen met de belasting, zijn budgetten of coalescing de eerste hefbomen. Zie ik daarentegen pieken zonder duurzame stijging, dan verdichten bursts het werk slechts op korte termijn – dan helpt batching (GRO) vaker dan grote budgetten. Nieuwere kernels breiden de statistieken uit met velden voor RPS/RFS en flowlimieten; als deze stijgen, verdeel ik bewuster via RPS of verlaag ik RFS wanneer de lookups duurder worden dan het nut ervan. Ik breng de tellers altijd in verband met /proc/softirqs: Als NET_RX op afzonderlijke kernen stijgt en de tijdsdruk in softnet_stat toeneemt, richt ik me eerst op de verdeling (IRQ/RSS) en pas in een tweede stap op grotere budgetten.
RPS/RFS en XPS: softwarebesturing en wachtrijafstemming onder controle
Als er geen of onvoldoende hardware-RSS is, gebruik ik RPS (Receive Packet Steering), om de ontvangstbelasting over meerdere kernen te verdelen. Via rps_cpus wijs ik de ontvangstwachtrijen kernen toe die bij de actieve workers passen en, indien mogelijk, Dichtbij NUMA liggen. Bij veel flows voeg ik toe RFS (Receive Flow Steering), zodat inkomende pakketten terechtkomen waar de bijbehorende sockets worden verwerkt – goed voor de cache-localiteit, zolang de flowtabellen geen bottleneck vormen. Aan de verzendzijde helpt XPS (Transmit Packet Steering), waarbij de keuze van de TX-wachtrij wordt afgestemd op de CPU-toewijzing van de toepassing. Het doel is dat een flow consistent via dezelfde RX/TX-wachtrij en dezelfde kern verloopt, waardoor de latentie afneemt en GRO-Batches worden groter. Ik test distributies altijd stapsgewijs: eerst RPS op een paar wachtrijen activeren, het effect meten (drops, %soft, latenties), en vervolgens RFS/XPS toevoegen. Als cores door RPS overbelast raken of de L3-hitrate verslechtert, verklein ik de CPU-maskers weer of koppel ik wachtrijen nauwer aan de cores van de betreffende diensten.
NUMA, CPU-isolatie en interacties tussen schedulers
Zelfs de beste budgetten en toewijzingen hebben weinig nut als geheugentoegangen lange NUMA-paden volgen. Ik zorg ervoor dat NIC-interrupts, NAPI-nabewerking en de aanvragende processen zoveel mogelijk binnen dezelfde NUMA-domein blijven. In opstellingen met speciale realtime- of latentiekernen isoleer ik deze via CPU- en Cgroup-beleidsregels en houd ik SoftIRQ-activiteiten daar bewust buiten. ksoftirqd mag niet op geïsoleerde kernen terechtkomen, anders hopen pakketten zich onopgemerkt op. Omgekeerd mogen geïsoleerde kernen niet volledig zonder IRQ-afhandeling blijven zitten wanneer ze datapaden afsluiten – een duidelijke affiniteit en Huishouding-Een strategie is essentieel. Voor workloads met strenge SLO’s vermijd ik te agressieve SCHED_FIFO/RR-prioriteiten, die de NAPI-uitvoering zouden kunnen verdringen. Ik houd de lengte van de runqueues, het aantal wake-ups en de preemptiepercentages in de gaten: als de SoftIRQ-tijden toenemen naarmate de interactiviteit van de app toeneemt, pas ik de granulariteit en affiniteiten aan, in plaats van de budgetten klakkeloos te verhogen.
qdisc, offloads en Busy-Poll: latentie en doorvoersnelheid in evenwicht brengen
Op het Egress-pad kost elke qdisc-CPU-tijd. Ik kies de methode die bij het profiel past: fq_codel helpt bij bufferbloat en vlakkt pieken af, terwijl mq-varianten van Multi-Queue-NIC’s. Bij pure gegevensdoorvoer over stabiele verbindingen kan een lichtere qdisc de latentiepieken minimaliseren. Op de ingress loont het de moeite om de fijnafstemming van GRO/TSO/GSO: Grotere batches verlagen de SoftIRQ-frequentie, maar verhogen in het uiterste geval de pakkettijd in de stack. Ik meet of GRO-flush-intervallen of hardware-offloads leiden tot te grote aggregaten die de toepassing schaden. Voor paden waarbij latentie van cruciaal belang is, stel ik busy_poll en gebruik ik `busy_read` met mate om pakketten actief uit de driver te halen – maar alleen onder nauwlettend toezicht, zodat andere taken niet in de steek worden gelaten. Ook stel ik Interrupt samenvoegen Houd rekening met pieken in het verkeer: iets meer microseconden extra helpen de doorvoersnelheid, maar te veel vertraagt ACK’s en verlengt handshakes. Het is belangrijk om elke wijziging afzonderlijk te beoordelen: gesimuleerde pieken, echte productiepieken en rustperiodes vertonen vaak verschillende latentieprofielen.
Diagnosechecklist en veilige rollback
Ik werk wijzigingen consequent af aan de hand van een korte checklist: 1) Symptomen vaststellen (ksoftirqd, %soft, drops). 2) De verdeling controleren (/proc/interrupts, Queue->CPU, RSS/RPS-status). 3) Budgetten aanpassen, effect in softnet_stat observeren (tijdsdruk neemt af, drops stagneren). 4) Offloads/coalescing nauwkeurig afstellen, qdisc controleren. 5) NUMA/CPU-koppelingen en cgroups dubbel controleren. Elke stap eindigt met een duidelijke verbetering van de statistieken of met de Terugdraaien naar de laatste goede status. Ik documenteer streef- en werkelijke waarden (latentie P95/P99, %soft per kern, drop-percentages, contextwisselingen), zodat latere iteraties niet in het duister plaatsvinden. Als meerdere kleine verbeteringen geen verlichting opleveren, stop ik ermee en ga ik op zoek naar structurele oorzaken (wachtrij-bottlenecks, app-blokkades, invloeden van opslag). Deze discipline voorkomt valse correlaties en beschermt tegen ‘tuning-spiralen’, die weliswaar de doorvoercijfers verhogen, maar de interactiviteit en stabiliteit verslechteren.
Grensgevallen en werkbelastingprofielen duidelijk van elkaar scheiden
Ik maak bewust onderscheid tussen bulk-overdracht, API’s waarbij latentie van cruciaal belang is en burst-verkeer UDP-Verkeer. Voor bulkgegevens geef ik de voorkeur aan vroegtijdig batchen en coalescing, zolang er geen pakketverlies optreedt. Bij API-verkeer geef ik prioriteit aan een gelijkmatige verdeling, beperkte batches en stabiele E2E-latenties, zelfs als de maximale doorvoersnelheid nominaal iets daalt. UDP-bursts bestrijd ik bij voorkeur via queue-verbreding en affiniteiten – te grote budgetten vergroten anders alleen maar head-of-line-blocking. Als een omgeving veel container- of overlay-hops gebruikt, houd ik rekening met extra stackwerk en spreid ik de SoftIRQ-belasting breder uit. Ik beoordeel bovendien firewall-/Conntrack-overheads afzonderlijk: wanneer tabellen hun grenzen bereiken, stijgt de SoftIRQ-belasting onvermijdelijk, hoe goed de IRQ-verdeling ook is. Pas wanneer de paden per profiel consistent slank zijn, loont het de moeite om de laatste paar procenten te finetunen.
SoftIRQ's in cloud- en containeromgevingen
In gevirtualiseerde omgevingen wordt de belasting verdeeld via vSwitches, overlay-netwerken en host-stacks, en daarom houd ik zowel de gast- als de host-Metriek analyseer. Lange SoftIRQ-tijden in de host remmen containers en VM’s onmiddellijk af, zelfs als de gastsystemen ogenschijnlijk rustig draaien werk. Ik controleer daarom offloads en coalescing op de fysieke NIC, terwijl RPS/RFS in de host het softwarepad beter verdeelt. Voor container-workloads kijk ik of de cgroup-limieten voor CPU en IRQ-verwerking op een zinvolle manier zijn ingesteld, zodat belangrijke diensten niet in Wachtrijen uitgasten. vNIC’s met ondersteuning voor meerdere wachtrijen (Multi-Queue) en RSS verbeteren de parallelliteit, mits de affiniteiten en wachtrijtoewijzingen kloppen. Met deze benadering houd ik de gegevenspaden kort en zorg ik voor stabiliteit Latencies en betrouwbare, reproduceerbare prestaties.
Samenvatting: SoftIRQ-analyse met gemak onder de knie krijgen
Wie de SoftIRQ-belasting grondig analyseert, maakt gebruik van duidelijke meetpunten, bekijkt verdelingen en past een gedifferentieerde Stappen. Ik begin bij /proc/softirqs en softnet_stat, breng dit in verband met ksoftirqd en mpstat en leid daaruit de volgorde van mijn Maatregelen. Eerst pas ik netdev_budget en netdev_budget_usecs aan, daarna optimaliseer ik de IRQ-affiniteit, RSS en batching-opties zoals GRO en offloads. Elke aanpassing blijft klein, wordt gemeten en alleen doorgevoerd als deze een positief effect heeft, totdat de drops verdwijnen en Latencies dalen. Deze discipline voorkomt neveneffecten, behoudt de interactiviteit op de CPU en houdt diensten ook tijdens pieken in het verkeer in stand responsief. Zo blijft de prestatie van Linux transparant, robuust en aanpasbaar, zonder dat verborgen knelpunten de Stabiliteit in gevaar brengen.


