Ви спостерігаєте за віртуальною машиною, яка «переважно» поводиться нормально. Але що кілька хвилин консоль зависає на півсекунди, звук потріскує,
RDP пропускає кадр або коміт у базі даних стрибає з 2 мс до 300 мс. Нічого не завантажено до межі. Середнє завантаження в нормі. Графіки диска виглядають нормально.
Моніторинг показує… відчуття.
Це той тип несправності, через який розумні люди починають звинувачувати застосунок, гіпервізор, мережу, фази місяця
і врешті одне одного. Частіше, ніж комусь хочеться визнати, винуватець нудний і електричний: те, як переривання доставляються,
транслюються й маршрутизуються — зокрема MSI/MSI‑X та перенаправлення переривань.
Зручна ментальна модель: чому переривання викликають «випадкові» зависання
Проблема зависань ВМ часто є проблемою розподілу затримок, а не пропускної спроможності.
Переривання — основний рушій хвостової затримки, бо вони пробивають дірки в часі CPU.
Коли дірка припадає не вчасно — під час виконання vCPU, під час хвилі прийому мережі або завершень зберігання — ви не отримуєте «повільніше»,
ви отримуєте спайки.
Чим MSI/MSI‑X відрізняється від застарілого INTx
Застарілі PCI‑переривання (INTx) — це рівнезбуджені лінії, що діляться між пристроями. «Спільне використання» — ввічливий термін.
На практиці це може перетворитися на голосний груповий чат: один пристрій піднімає лінію, CPU має перепитувати низку пристроїв
«це ти?» доки не знайде правильний. Ця додаткова робота — джиттер.
MSI (Message Signaled Interrupts) замінив «підняти пін» на «записати повідомлення в конкретну адресу APIC».
MSI‑X пішов далі з багатьма векторами, дозволяючи пристрою розподіляти навантаження по чергах (уявіть multiqueue NIC і NVMe).
Правильне використання MSI‑X — один з тих тихих героїв сучасного низьколатентного I/O.
Де з’являється перенаправлення переривань
У віртуалізації та passthrough ви доставляєте переривання не просто хосту.
Ви доставляєте їх правильному гість‑вміснику, безпечно, не дозволяючи пристрою писати переривання в довільні місця.
Це відображення — мапінг повідомлення MSI/MSI‑X від пристрою до дозволеної цілі — і є перенаправленням переривань,
яке зазвичай реалізує IOMMU (Intel VT‑d або AMD‑Vi).
Без перенаправлення переривань ядро може відмовитися вмикати MSI/MSI‑X у деяких сценаріях passthrough,
або перейти на застарілий INTx чи менш ефективні шляхи. Навіть коли «все працює», ви можете отримати:
- Шторми переривань, що консолідуються на одному ядрі CPU
- Накопичення softirq і трешинг ksoftirqd
- Черги всередині vhost‑net, virtio або блочного шару
- Непередбачувані підміни vCPU (то саме відчуття зависання)
Сухо‑смішна правда: CPU відмінно виконує обчислення і жахливо — коли його переривають усі одразу, як хірурга, якого просять ще й відповісти на офісний телефон.
Як «випадкове зависання» виглядає на рівні переривань
Класичний патерн — короткі але сильні сплески затримок, що корелюють з:
- Мережевими хвилями (RX/TX завершення)
- Чергами завершень NVMe
- USB‑контролерами (так, це буває) які створюють піки обробки IRQ на хості
- Дивними особливостями доставки переривань при GPU passthrough
- Взаємодією таймерного тіку й планувальника, коли хост трохи перепідписаний
Хост може показувати низьке загальне завантаження CPU, але одне ядро отримає натиск переривань і softirq, тоді як інші простоюють.
Ось чому «середнє CPU» — неправильний графік для спостереження.
Ще одна практична тонкість: «переривання» включають як жорсткі IRQ‑контексти, так і softirq/NAPI‑обробку.
NIC може генерувати переривання, які запускають softirq‑обробку на тому самому CPU, і це може відбирати час у потоків KVM vCPU.
Ви помітите зависання навіть при великому запасі ресурсів.
Цитата (переказ ідеї) від Werner Vogels: Ви будуєте — ви експлуатуєте; оперативна відповідальність змінює підходи до проєктування й відлагодження систем.
Якщо ви керуєте гіпервізорами, переривання — це не «апаратна штука». Це ваш продукт.
Факти й історія, що справді мають значення
Музей вам не потрібен, але кілька конкретних фактів допоможуть припинити повторювати ті самі помилкові припущення:
- MSI широко з’явився з апаратурою епохи PCI 2.2, щоб зменшити спільні лінії переривань і покращити масштабованість.
- MSI‑X з’явився з PCI 3.0 і значно розширив кількість векторів, дозволивши пер‑чергові переривання для високопродуктивних пристроїв.
- Застарілий INTx — рівнезбуджений і спільний; він схильний до сканування «хто підняв лінію?» і дивних взаємодій під навантаженням.
- Сучасні NIC і NVMe розраховані на MSI‑X; відкат до INTx може непомітно зруйнувати паралелізм і додати джиттер.
- Перенаправлення переривань — стільки ж функція безпеки, скільки продуктивності; воно не дає пристроям цілитися в довільні CPU/гості при MSI‑записах.
- VT‑d/AMD‑Vi IOMMU часто постачаються ввімкненими для ізоляції DMA, але перенаправлення переривань все одно може бути відключено або недоступне залежно від прошивки/параметрів.
- Журнали Intel DMAR — ваші друзі; ядро повідомить, коли перенаправлення переривань вимкнено, примусово відключено або зламано — якщо ви подивитесь.
- x2APIC і posted interrupts змінили правила гри для масштабування доставки переривань і зменшення накладних витрат VM‑exit в деяких шляхах віртуалізації.
- irqbalance — не інструмент для продуктивності; це компроміс; він може допомагати або шкодити в залежності від черг, прив’язки CPU і стратегії ізоляції.
Другий короткий жарт: Якщо хтось каже «переривання не можуть викликати зависань, бо CPU лише на 20%», вони винайшли нову одиницю заперечення.
Швидкий план діагностики (перший/другий/третій)
Перший: доведіть, що це затримка переривань/softirq, а не сире CPU чи пропускна здатність диска
- Перевірте розподіл IRQ по CPU і тиск softirq.
- Зкорелюйте сплески з пристроєм (NIC, NVMe, USB, HBA, GPU).
- Пошукайте відкат до INTx і відсутність MSI/MSI‑X.
Другий: перевірте, що IOMMU + перенаправлення переривань справді увімкнені
- Підтвердіть параметри завантаження ядра: Intel
intel_iommu=on, AMDamd_iommu=on. - Переконайтесь, що журнали DMAR/IVRS показують, що перенаправлення переривань увімкнене.
- Якщо ви використовуєте VFIO passthrough: переконайтесь, що платформа підтримує це і ядро його використовує.
Третій: виправте топологію переривань (афінність, ізоляція, черги)
- Розподіліть вектори MSI‑X по CPU навмисно, а не «як склалося при завантаженні».
- Зробіть так, щоб прив’язка CPU і афінність IRQ узгоджувалися (не прив’язуйте vCPU до того самого ядра, що обробляє всі NIC‑переривання).
- Повторно перевірте зависання: ваша мета — згладжена хвостова затримка, а не обов’язково вища пропускна здатність.
Практичні завдання: команди, виводи, рішення (12+)
Це чекліки, які я фактично виконую на хості Linux KVM (Proxmox, Ubuntu, Debian, RHEL‑подібні).
Вони впорядковані так, щоб ви могли зупинитись раніше, якщо знайдете явну причину.
Кожне завдання включає: команду, реалістичний вивід, що це означає, і рішення, яке потрібно прийняти.
Завдання 1: Підтвердити, що IOMMU увімкнено в командному рядку ядра
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.8.0 root=/dev/mapper/vg0-root ro quiet intel_iommu=on iommu=pt
Що це означає: intel_iommu=on увімкне VT‑d IOMMU. iommu=pt використовує режим passthrough для пристроїв хоста, щоб зменшити накладні витрати, зберігаючи при цьому доступну трансляцію.
Рішення: Якщо ви не бачите intel_iommu=on або amd_iommu=on, додайте його і перезавантажтесь. Якщо ви використовуєте VFIO, зазвичай потрібно його увімкнути. Якщо у вас лише virtio, це також часто допомагає для цілісності перенаправлення переривань.
Завдання 2: Перевірити журнали DMAR/IVRS для статусу перенаправлення переривань
cr0x@server:~$ dmesg -T | egrep -i 'dmar|ivrs|iommu|interrupt remapping' | head -n 30
[Mon Feb 3 10:12:11 2026] DMAR: IOMMU enabled
[Mon Feb 3 10:12:11 2026] DMAR: Interrupt remapping enabled
[Mon Feb 3 10:12:11 2026] DMAR: x2apic enabled
[Mon Feb 3 10:12:12 2026] pci 0000:3b:00.0: DMAR: Skip IOMMU disabling for graphics
Що це означає: Це індикатор «не ускладнюйте». Якщо він каже, що перенаправлення переривань увімкнене, платформа + прошивка + ядро співпрацюють.
Рішення: Якщо ви бачите Interrupt remapping disabled або помилки, зупиніться і виправте це перед тонким налаштуванням афінності IRQ. Без цієї функції ви не знайдете простого рішення в налаштуваннях.
Завдання 3: Підтвердити, що існують групи IOMMU (перевірка для користувачів VFIO)
cr0x@server:~$ find /sys/kernel/iommu_groups/ -maxdepth 2 -type l | head
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/1/devices/0000:00:01.0
/sys/kernel/iommu_groups/2/devices/0000:00:02.0
Що це означає: Наявність груп сильно вказує на те, що IOMMU активний.
Рішення: Якщо директорія порожня/відсутня, у вас немає реальної конфігурації IOMMU. Виправте налаштування BIOS/UEFI (VT‑d/AMD‑Vi) і параметри ядра.
Завдання 4: Визначити, які PCI‑пристрої використовують MSI/MSI‑X або INTx
cr0x@server:~$ lspci -nnk | egrep -A3 -i 'ethernet|nvme|usb|sata|raid|vga|3d'
3b:00.0 Ethernet controller [0200]: Intel Corporation Ethernet Controller X710 for 10GbE SFP+ [8086:1572]
Subsystem: Intel Corporation Device [8086:0000]
Kernel driver in use: i40e
Kernel modules: i40e
5e:00.0 Non-Volatile memory controller [0108]: Samsung Electronics Co Ltd NVMe SSD Controller [144d:a808]
Kernel driver in use: nvme
0a:00.0 USB controller [0c03]: ASMedia Technology Inc. ASM2142 USB 3.1 Host Controller [1b21:2142]
Kernel driver in use: xhci_hcd
Що це означає: Це показує, хто має значення. NIC + NVMe + USB — часті джерела зависань.
Рішення: Далі перевірте кожен пристрій на предмет «MSI/MSI‑X увімкнено» та кількості векторів.
Завдання 5: Для пристрою перевірити, чи MSI/MSI‑X увімкнено і скільки векторів
cr0x@server:~$ sudo lspci -s 3b:00.0 -vv | egrep -i 'msi|msi-x|interrupt'
Capabilities: [70] MSI-X: Enable+ Count=64 Masked-
Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+
Interrupt: pin A routed to IRQ 16
Що це означає: MSI‑X увімкнено з 64 векторами. MSI присутній, але вимкнений (нормально, коли використовується MSI‑X). Рядок «Interrupt pin … IRQ 16» може існувати навіть коли MSI‑X використовується; не панікуйте.
Рішення: Якщо ви бачите MSI-X: Enable- і очікували багаточергову продуктивність, ви знайшли ймовірного винуватця. Розбирайтесь, чому він вимкнений (параметри драйвера, кухні ядра, проблеми VFIO/IR).
Завдання 6: Виявити використання застарілого INTx через шаблони /proc/interrupts
cr0x@server:~$ cat /proc/interrupts | head -n 15
CPU0 CPU1 CPU2 CPU3
16: 91233 3 1 2 IO-APIC 16-fasteoi i40e
24: 501223 0 0 0 PCI-MSI 524288-edge nvme0q0
25: 198772 0 0 0 PCI-MSI 524289-edge nvme0q1
26: 77211 0 0 0 PCI-MSI 524290-edge nvme0q2
Що це означає: Рядки IO-APIC часто вказують на застаріле або пінове переривання; PCI-MSI вказує на вектори MSI/MSI‑X. Також зверніть увагу на розподіл по CPU: все, що звалюється на CPU0, — це пастка латентності.
Рішення: Якщо гарячі пристрої мають IO‑APIC і в основному на CPU0, перейдіть на MSI/MSI‑X і/або налаштуйте афінність. Якщо вони MSI, але все одно зосереджені на CPU0, налагодьте афінність і irqbalance.
Завдання 7: Перевірити тиск softirq (прихований «наслідок переривань»)
cr0x@server:~$ cat /proc/softirqs
CPU0 CPU1 CPU2 CPU3
HI: 3 0 0 0
TIMER: 1123456 902233 877112 889001
NET_TX: 8221 9102 8455 8601
NET_RX: 9981234 21002 19511 20110
BLOCK: 302112 88011 90122 89300
IRQ_POLL: 0 0 0 0
TASKLET: 1022 1101 1002 1010
SCHED: 512001 490002 488901 487112
HRTIMER: 42 39 41 40
RCU: 980002 910001 905551 907221
Що це означає: CPU0 має величезний NET_RX порівняно з іншими. Це саме той профіль «одне ядро вбивають» при зависаннях.
Рішення: Розпороште черги NIC (RSS), налаштуйте афінність IRQ або змініть RPS/XPS. Якщо ви прив’язуєте vCPU, тримайте CPU з інтенсивними IRQ подалі від ядер, чутливих до затримки vCPU-потоків.
Завдання 8: Перевірити, які IRQ належать чергам вашого NIC і де вони виконуються
cr0x@server:~$ grep -iE 'i40e|mlx|ixgbe|bnxt|ena' /proc/interrupts | head
16: 91233 3 1 2 IO-APIC 16-fasteoi i40e
98: 501223 0 0 0 PCI-MSI 327680-edge i40e-TxRx-0
99: 498877 0 0 0 PCI-MSI 327681-edge i40e-TxRx-1
100: 490112 0 0 0 PCI-MSI 327682-edge i40e-TxRx-2
Що це означає: Чергові переривання застрягли на CPU0. Або афінність встановлена погано за замовчуванням, або irqbalance їх зафіксував там.
Рішення: Явно встановіть афінність для цих IRQ або налаштуйте irqbalance, щоб уникати ядер ваших vCPU.
Завдання 9: Перевірити поточні маски афінності IRQ
cr0x@server:~$ sudo cat /proc/irq/98/smp_affinity
1
Що це означає: Маска 1 означає лише CPU0.
Рішення: Змініть її, щоб розпорошити по CPU (приклад: CPU 0–3 — маска f; CPU 4–7 — f0 на 8‑ядерній системі). Підбирайте згідно з вашою топологією CPU і планом прив’язки.
Завдання 10: Обережно встановити афінність IRQ для черги
cr0x@server:~$ echo f | sudo tee /proc/irq/98/smp_affinity
f
Що це означає: Ви дозволили IRQ 98 виконуватись на CPU 0–3. Це грубий інструмент, але швидка перевірка.
Рішення: Якщо зависання зменшились негайно, ви підтвердили діагноз. Далі зробіть налаштування стійким (systemd unit, tuned profile або політика irqbalance).
Завдання 11: Перевірити, чи працює irqbalance і що він може робити з вашою системою
cr0x@server:~$ systemctl status irqbalance --no-pager
● irqbalance.service - irqbalance daemon
Loaded: loaded (/lib/systemd/system/irqbalance.service; enabled)
Active: active (running) since Mon 2026-02-03 10:12:38 UTC; 1h 3min ago
Main PID: 812 (irqbalance)
Tasks: 1
Memory: 2.4M
CPU: 1.231s
Що це означає: irqbalance активний. Він може покращити розподіл, або зруйнувати вашу ізоляцію CPU і скасувати ретельну прив’язку.
Рішення: Якщо ви використовуєте ізоляцію/прив’язку CPU для ВМ, подумайте про налаштування заборон в irqbalance або відключення його й управління афінністю явно.
Завдання 12: Перевірити, чи ядро не примусово вимикає PCI MSI глобально
cr0x@server:~$ cat /proc/cmdline | grep -o 'pci=.*' || true
Що це означає: Немає pci=nomsi у командному рядку. Добре.
Рішення: Якщо ви знайдете pci=nomsi у cmdline (так, люди копіюють це зі старих форумів), приберіть його. Це фабрика зависань на сучасних пристроях.
Завдання 13: Перевірити, чи ядро не відключає перенаправлення переривань через кухні
cr0x@server:~$ dmesg -T | egrep -i 'remapping.*(off|disable)|no IR|intremap' | head
Що це означає: У цьому прикладі нічого тривожного не знайдено. На зламаних системах ви можете побачити повідомлення, що IR вимкнено через баги BIOS або обмеження платформи.
Рішення: Якщо ви бачите примусове відключення, оновіть BIOS/UEFI і мікрокод. Якщо це не допоможе, можливо, потрібне інше обладнання для стабільної роботи VFIO/MSI.
Завдання 14: Перевірити розміщення потоків KVM і чи vCPU ділять ядра з IRQ‑штормами
cr0x@server:~$ ps -eLo pid,psr,comm | egrep 'kvm|qemu-system' | head
2311 0 qemu-system-x86
2315 0 CPU 0/KVM
2316 1 CPU 1/KVM
2317 2 CPU 2/KVM
2318 3 CPU 3/KVM
Що це означає: Потоки vCPU розміщені на CPU 0–3. Якщо ваші переривання також сконцентровані там, відбувається конфлікт за планування.
Рішення: Або відсуньте IRQ від ядер vCPU, або перемістіть vCPU подалі від ядер з інтенсивними IRQ. Не «діліться чемно» й не сподівайтесь на диво.
Завдання 15: Швидкий перегляд використання softirq по CPU в реальному часі
cr0x@server:~$ mpstat -P ALL 1 5
Linux 6.8.0 (server) 02/03/2026 _x86_64_ (8 CPU)
11:21:01 AM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
11:21:02 AM all 7.11 0.00 6.33 0.12 0.10 3.52 0.00 82.82
11:21:02 AM 0 4.00 0.00 9.00 0.00 0.60 18.40 0.00 68.00
11:21:02 AM 1 8.00 0.00 6.00 0.00 0.00 1.00 0.00 85.00
11:21:02 AM 2 9.00 0.00 5.00 0.00 0.00 0.90 0.00 85.10
11:21:02 AM 3 8.00 0.00 5.00 0.00 0.00 0.80 0.00 85.20
Що це означає: CPU0 має високий відсоток %soft, що часто корелює з NET_RX‑затримками. Це класичний генератор затримок ВМ.
Рішення: Якщо одне CPU показує підвищений softirq, націльтесь на черги пристрою, що маплені на нього, і перерасподіліть.
5‑хвилинне виправлення: що змінити і чому
«5 хвилин» припускає, що у вас є доступ до консолі і ви можете перезавантажитись один раз. Якщо перезавантаження неможливе, ви все одно можете валідувати і частково пом’якшити проблему через афінність.
Основна ідея проста: переконайтесь, що MSI/MSI‑X увімкнено, і що перенаправлення переривань увімкнене, щоб доставка MSI була безпечною і швидкою у віртуалізованих сценаріях.
Крок 1: Увімкнути IOMMU і перенаправлення переривань у прошивці
У BIOS/UEFI увімкніть:
- Intel: VT‑d (іноді «Intel Virtualization Technology for Directed I/O»)
- AMD: AMD‑Vi / IOMMU
Також перевірте перемикачі «Interrupt Remapping» або «DMA Remapping», якщо прошивка їх показує.
Інтерфейси прошивки бувають від доглянутих до проклятих. Шукайте будь‑що, що звучить як IOMMU/VT‑d/AMD‑Vi.
Крок 2: Увімкнути IOMMU в параметрах завантаження ядра
Додайте один з цих рядків у ваш завантажувач:
intel_iommu=on iommu=ptamd_iommu=on iommu=pt
iommu=pt часто є гарним значенням за замовчуванням для хостів, що не тримають «усе за трансляцією весь час».
Воно може зменшити накладні витрати, залишаючи механізм IOMMU доступним для перенаправлення і призначення пристроїв.
Крок 3: Перезавантажитись, перевірити DMAR/IVRS на рядок «Interrupt remapping enabled»
Якщо воно не увімкнене, зупиніться. Не робіть складних налаштувань афінності поверх некоректної конфігурації платформи.
Виправляйте BIOS/UEFI, оновлюйте прошивку/мікрокод або міняйте обладнання за потреби.
Крок 4: Переконатися, що пристрої дійсно використовують MSI/MSI‑X і мають очікувані вектори черг
Для NIC очікуйте кілька Tx/Rx черг. Для NVMe очікуйте кілька черг завершень.
Якщо ви бачите один вектор або MSI‑X присутній, але вимкнений, сплески при навантаженні — закономірний наслідок.
Крок 5: Рознести переривання від ядер vCPU
Хитрість продуктивності не в «рознести все скрізь». Це — розділення обов’язків:
- Виберіть ядра CPU для роботи хост‑IRQ/softirq (мережа, зберігання)
- Виберіть ядра CPU для vCPU ВМ (латентно‑чутливі гостьові ОС)
- Зробіть політику афінності, яка відповідає цим виборам
Якщо нічого не робити, принаймні не дозволяйте всім чергам переривань йти на CPU0. CPU0 вже виконує обов’язки з прибирання на багатьох системах.
Дайте йому віддих.
Три корпоративні міні‑історії з поля бою переривань
Інцидент: неправильне припущення («певно, проблема в зберіганні»)
Середня компанія експлуатувала кластер віртуалізації з внутрішнім CI, кількома базами даних і VDI‑фермою.
Користувачі скаржилися, що «ВМ на секунду зависають» кілька разів на годину. Передбачувано, першими опитали команду зберігання,
бо «зберігання завжди перше отримує дзвінок».
Початкове припущення було знайоме: зависання = латентність зберігання. Команда дивилася на графіки SAN, статистику multipath
і повторні передачі iSCSI. Нічого. Затримка була стабільною. Пропускна здатність мала запас. Постачальник SAN був трохи нудьгуючим.
SRE виконав просту перевірку: /proc/softirqs і /proc/interrupts. CPU0 мав величезні NET_RX лічильники.
10GbE NIC був «здатний multiqueue», але його вектори IRQ фактично були приклеєні до одного ядра.
Вони також виявили, що перенаправлення переривань було вимкнено у прошивці після того, як профіль BIOS скинувся під час оновлення платформи.
З вимкненим перенаправленням переривань хост застосував менш оптимальний шлях доставки переривань для частини пристроїв.
При вибуховому VDI‑трафіку обробка IRQ/softirq на хості коротко позбавляла потоки KVM vCPU часу процесора.
Користувачі сприймали це як «зависання ВМ».
Виправлення було нудним: знову увімкнути VT‑d/IOMMU + перенаправлення переривань, підтвердити MSI‑X увімкненим, а потім розподілити черги переривань подалі від vCPU‑ядер.
SAN нічого не змінював. Тикети припинилися. Команда зберігання не отримала вибачень, але менш напружені чергування.
Оптимізація, що дала зворотний ефект: «вимкнути IOMMU заради продуктивності»
Інша організація експлуатувала щільний обчислювальний кластер: багато ВМ, інтенсивна мережа, помірна локальна NVMe.
Хтось прочитав, що IOMMU додає накладні витрати, і ввів зміну, щоб вимкнути його по всьому флоту. Це подавалося як «безкоштовна продуктивність».
Зміна була розгорнута під час рутинного оновлення ядра.
Бенчмарки пропускної здатності виглядали нормально. Ось пастка: середні показники майже не змінилися.
Але за тиждень підтримка почала бачити «мікрозависи» в віддалених сесіях і дивні сплески втрат пакетів у гостях.
Це не було послідовно. Було гірше на вузлах з певними версіями прошивки NIC. Звісно, це переросло в міжкомандну суперечку.
Постмортем виявив дві проблеми. По‑перше: без IOMMU перенаправлення переривань було недоступне, і деякі випадки passthrough відкотилися на невигідні шляхи.
По‑друге: їхня стратегія прив’язки CPU припускала, що IRQ будуть відбалансовані від ізольованих vCPU‑ядер. irqbalance зробив навпаки на деяких вузлах,
і без очікуваних функцій переривань розподіл був ще гірший.
Відкат був простим: знову увімкнути IOMMU з iommu=pt, щоб уникнути зайвої трансляції для пристроїв хоста,
перевірити перенаправлення переривань у dmesg, а потім повторно перевірити афінність IRQ. «Безкоштовна продуктивність» дала безкоштовний джиттер.
Висновок: зміна, що покращує середню пропускну здатність, може знищити хвостову латентність.
Для користувацьких систем (VDI, голос, ігри, трейдинг, латентність комітів БД) хвостова латентність — критична.
Нудна, але правильна практика, яка врятувала: «апаратні профілі і перевірки при завантаженні»
Команда фінансових послуг експлуатувала невелике, але критичне середовище KVM. Їхня робота не була гламурною: внутрішні сервіси,
пакетні завдання, кілька латентно‑чутливих компонентів і вимоги відповідності, що ускладнювали зміни.
Вони рано зрозуміли, що «та сама модель сервера» не означає «ті ж налаштування прошивки».
Вони стандартизували базовий образ хоста:
VT‑d/IOMMU увімкнено, перенаправлення переривань увімкнене, узгоджені профілі BIOS експортовані і версіоновані,
і перевірка під час завантаження, яка сигналізує, якщо в dmesg немає очікуваного рядка «Interrupt remapping enabled».
Вони також прив’язували системні IRQ і черги NIC на призначені ядра, залишаючи чисті ядра для vCPU.
Одного кварталу їм довелося поміняти несправну материнську плату в стислому терміні. Замінник прийшов з профілем BIOS за замовчуванням:
віртуалізаційні функції частково вимкнені. Хост завантажився «нормально». ВМ запустилися «нормально». І тоді графіки латентності почали шепотіти.
Їхня перевірка при завантаженні спіймала проблему за хвилини. Вони виправили налаштування прошивки до того, як користувачі помітили щось.
Ніяких інцидентних викликів, жодних «war room», без взаємних звинувачень. Просто тикет із чеклістом і замкнуте коло.
Це непрестижна реальність надійності: нудні практики не запобігають кожній проблемі,
але вони запобігають дорогим інцидентам — тим, що виявляються тільки коли ваш CEO сидить у завислому VDI.
Поширені помилки: симптом → корінна причина → виправлення
1) Симптом: «Випадкові зависання 200–800 мс, CPU низький»
Корінна причина: Гарячі точки IRQ/softirq на одному CPU (часто CPU0), що періодично позбавляють потоки vCPU часу.
Виправлення: Перевірити MSI‑X, перерасподілити афінність IRQ, відділити ядра для IRQ від ядер vCPU, розглянути налаштування RPS/XPS.
2) Симптом: «VFIO passthrough працює, але затримка погана під навантаженням»
Корінна причина: Перенаправлення переривань вимкнене/недоступне; переривання пристрою доставляються через запасні шляхи або обмежене використання MSI.
Виправлення: Увімкнути VT‑d/AMD‑Vi + перенаправлення переривань у прошивці й ядрі. Оновити BIOS/мікрокод. Повторно перевірити dmesg.
3) Симптом: «NIC 10/25/40GbE поводиться як 1GbE при сплесках»
Корінна причина: MSI‑X не увімкнено, або активний лише один вектор/черга; multiqueue не працює.
Виправлення: Підтвердити MSI-X: Enable+ і число векторів; перевірити налаштування черг драйвера (ethtool -l), прошивку та параметри ядра, що вимикають MSI.
4) Симптом: «Зависання почалися після оновлення BIOS»
Корінна причина: Профіль BIOS скинувся і вимкнув VT‑d/IOMMU або перенаправлення переривань; іноді x2APIC змінився.
Виправлення: Заново застосуйте відомий‑добрий профіль BIOS; перевірте журнали DMAR/IVRS; додайте перевірки під час завантаження.
5) Симптом: «Все покращилося, крім однієї ВМ, яка все ще зависає»
Корінна причина: vCPU цієї ВМ прив’язані до того ж CPU, що обробляє NVMe або NIC‑переривання; або конкретний passthrough‑пристрій використовує інший шлях IRQ.
Виправлення: Узгодьте прив’язку vCPU з афінністю IRQ; ізолюйте ядра для хост‑IRQ; підтвердіть MSI‑X і статус IR пристрою, який передається.
6) Симптом: «Вимкнення irqbalance зробило гірше»
Корінна причина: Ви вимкнули балансування, але не замінили його продуманим планом афінності; переривання повернулись до значень за замовчуванням.
Виправлення: Або налаштуйте irqbalance з заборонами CPU, щоб захистити vCPU, або керуйте афінністю вручну з постійними правилами (systemd unit) для груп IRQ.
7) Симптом: «Оновлення ядра змінило поведінку»
Корінна причина: Драйвер змінив за замовчуванням параметри черг; кухні MSI/MSI‑X змінились; обробка топології CPU/NUMA змінилась; політика irqbalance змінилась.
Виправлення: Заново виконайте перевірки з розділу «практичні завдання». Не припускайте, що вчорашній розподіл переривань зберігся після оновлень.
Контрольні списки / покроковий план
Контрольний список A: Один хост — швидка діагностика зависань (15 хвилин)
- Запустіть фільтр dmesg для DMAR/IVRS і підтвердіть «Interrupt remapping enabled».
- Перевірте
/proc/interruptsі/proc/softirqsна предмет гарячих точок CPU. - Для підозрюваних пристроїв (NIC/NVMe/USB/HBA) підтвердіть, що MSI/MSI‑X увімкнено через
lspci -vv. - Перевірте, чи потоки vCPU ВМ знаходяться на тих самих CPU, що й гарячі IRQ.
- Тимчасово розпороште афінність IRQ для гарячих IRQ і спостерігайте за зменшенням зависань.
Контрольний список B: Стійке виправлення для вузла віртуалізації (change‑controlled)
- Стандартизувати профіль BIOS: увімкнути VT‑d/AMD‑Vi і перенаправлення переривань.
- Встановити параметри ядра:
intel_iommu=on iommu=pt(або AMD‑еквівалент). - Перезавантажитись; зафіксувати журнали DMAR/IVRS в інвентарі вузла.
- Підтвердити кількість векторів MSI‑X на NIC і NVMe; переконатись, що multiqueue активний.
- Визначити розподіл CPU: які ядра для IRQ/softirq хоста, які — для vCPU.
- Реалізувати постійну політику афінності IRQ (заборони irqbalance або явні маски).
- Перевірити під навантаженням хвостову затримку (p99), а не лише середню пропускну здатність.
Контрольний список C: Запобігання для всього кластера
- Додати перевірку при завантаженні, що сповіщує, якщо перенаправлення переривань вимкнене.
- Відслідковувати версії прошивок і дрейф налаштувань BIOS; не покладатись на «така ж модель».
- Після оновлень ядра/драйверів повторно валідувати увімкнення MSI‑X і кількість черг на canary‑вузлі.
- Документувати шлях відкату, включно з параметрами cmdline ядра і профілями BIOS.
FAQ
1) Чи потрібне перенаправлення переривань для доброї продуктивності?
Не завжди, але для VFIO/passthrough і деяких сучасних шляхів доставки переривань воно часто є різницею між чистим використанням MSI/MSI‑X і відкатом.
Це також межа безпеки. Якщо вам важлива хвостова латентність і коректність, увімкніть його.
2) Я увімкнув IOMMU. Чому я все одно бачу зависання?
Увімкнення IOMMU не гарантує, що переривання добре розподілені. Ви можете мати ідеальне перенаправлення і все одно звалити всі черги на CPU0.
Перевірте /proc/interrupts, /proc/softirqs і маски афінності IRQ.
3) У чому практична різниця між MSI і MSI‑X?
MSI зазвичай має невелику кількість векторів; MSI‑X підтримує багато векторів. Багато векторів дозволяють пер‑чергові переривання, що дає можливість NIC/NVMe масштабуватись по ядрам і зменшувати конкуренцію.
Для сучасного високошвидкісного I/O MSI‑X — нормальний цільовий стан.
4) Чи робить iommu=pt систему небезпечною?
Воно зменшує накладні витрати трансляції для пристроїв, що не ізолюються, але не «вимикає» існування IOMMU. Для пристроїв VFIO ви все одно отримаєте ізоляцію.
Безпека залежить від повної конфігурації; не використовуйте це як заміну розумінню моделі загроз.
5) Чи варто відключити irqbalance?
Якщо ви використовуєте ізоляцію/прив’язку CPU для ВМ, вам слід як мінімум контролювати irqbalance. Неконтрольований irqbalance може зруйнувати ізоляцію.
Або налаштуйте його, щоб уникати ваших vCPU‑ядер, або відключіть і встановіть афінність IRQ явно і постійно.
6) Чому CPU0 завжди виглядає підозрілим?
CPU0 часто обробляє системні завдання і за замовчуванням має афінність для великої кількості переривань. Він не злий; він просто зручний.
Зручність — поганий план продуктивності.
7) Чи може USB‑контролер справді викликати зависання ВМ?
Так. Голосний USB‑контролер (або пристрій на ньому) може генерувати переривання, що забирають час CPU, особливо якщо вони зосереджені на ядрі, де виконуються vCPU.
Це трапляється рідше, ніж з NIC/NVMe, але достатньо реальне, щоб перевіряти.
8) Як зрозуміти, що я відкотився до INTx?
Дивіться /proc/interrupts на рядки IO‑APIC, прив’язані до вашого пристрою, і підтвердіть увімкнення MSI/MSI‑X через lspci -vv.
Якщо MSI‑X показує Enable- або ви бачите лише один інтеррупт там, де має бути багато черг, підозрюйте відкат.
9) Моя ВМ використовує лише virtio. Чи має це значення?
Так, бо хост все одно обробляє переривання фізичних пристроїв (NIC, NVMe, HBA), що забезпечують virtio.
Навіть без passthrough поганий розподіл переривань може позбавити потоки vhost часу та виконання vCPU.
10) Який найшвидший спосіб переконатися, що зміни спрацювали?
Ви хочете побачити: DMAR каже, що перенаправлення переривань увімкнене, пристрої показують MSI‑X увімкненим з очікуваною кількістю векторів, і навантаження IRQ/softirq розподілене по запланованих CPU.
Потім перевірте хвостову латентність: p99/p999 у гості, а не лише середню пропускну здатність на хості.
Висновок: наступні кроки, які можна впровадити сьогодні
Випадкові зависання ВМ часто є проблемою топології переривань у масці. MSI/MSI‑X і перенаправлення переривань — не нішева опція;
це комунікаційні трубопроводи, що дозволяють сучасним пристроям масштабуватись, не перетворюючи одне CPU на панічну кімнату.
Практичні наступні кроки:
- На одному вузлі з зависаннями підтвердьте, що DMAR/IVRS показує «Interrupt remapping enabled». Якщо ні — виправте прошивку + параметри ядра.
- Переконайтесь, що ваші «гарячі» пристрої (NIC/NVMe) мають увімкнений MSI‑X і кілька векторів.
- Перевірте
/proc/interruptsі/proc/softirqsна гарячі точки CPU; не приймайте «CPU низький» як пояснення. - Узгодьте афінність IRQ з прив’язкою vCPU: відведіть ядра для хост‑переривань, залиште чисті ядра для VM.
- Зробіть це стійким: версіонуйте профілі BIOS, додайте перевірки при завантаженні і перевіряйте після оновлень.
Зробіть це один раз, правильно, і ви перестанете ставитися до «зависання» як до містичної історії. Це просто маршрутизація.