SR-IOV проти Passthrough: коли IOMMU допомагає (а коли — ні)

Було корисно?

Іноді ваша «віртуалізована» мережна карта спокійно витрачає 2% CPU і дає 25 Gbps. Інші дні вона скидкує пакети під навантаженням, p99 затримки схожі на сейсмограф, і хтось радить «просто ввімкніть SR-IOV», ніби це універсальний розчинник.

Це доросла версія тієї розмови: що насправді дають SR-IOV і PCI passthrough, що робить IOMMU, і конкретні способи, якими ви можете погіршити продуктивність, аплодуючи собі за «наближення до апаратури».

Ментальна модель: PF, VF, DMA і навіщо потрібен IOMMU

Визначимо терміни так, як це робить ваше ядро, а не як у маркетингових слайдах.

Passthrough (VFIO) в одному абзаці

PCI passthrough призначає повну PCIe-функцію віртуальній машині (або контейнероподібному навантаженню), тож гість стає власником пристрою. У Linux/KVM зазвичай це VFIO: хост прив’язує пристрій до vfio-pci, а QEMU відображає його в гість. Пристрій виконує DMA в пам’ять гостя, і IOMMU (якщо ввімкнено) гарантує, що DMA не виходить за межі дозволеного гостю.

SR-IOV в одному абзаці

SR-IOV розділяє фізичну PCIe-функцію (PF) на кілька легковагових PCIe-функцій (VF). Кожна VF виглядає як окремий PCI-пристрій з власним простором конфігурації, BAR-ами та чергами (залежить від реалізації), тому ви можете передавати окремі VF гостям. PF залишається під управлінням хоста (інколи — «сервісної ВМ»), а VF — «переважно апаратна», з політичними ручками через драйвер PF і прошивку.

Де тут DMA і чому це важливо

SR-IOV і passthrough — про одне: хто може виконувати DMA і наскільки дорого це робити безпечно. Пристрої не «відправляють пакети» — вони через DMA записують дескриптори й payload у пам’ять. Якщо пристрій може DMA куди завгодно, він може читати ваші секрети, писати в ядро і перетворити надійність на інтерпретативний танець.

Саме для цього потрібен IOMMU: транслювати й обмежувати адреси DMA пристроїв, подібно до того, як MMU процесора обмежує процесну пам’ять. Без IOMMU «призначені» пристрої все ще можуть DMA в пам’ять хоста, якщо ізоляцію налаштовано неправильно. З IOMMU ви платите за трансляцію (інколи мізерну, інколи помітну), але отримуєте реальну ізоляцію і фічі на кшталт перенаправлення переривань.

Суха емпірична порада: якщо ви робите passthrough у продакшні й не використовуєте IOMMU, ви не «сміливі», ви просто керуєте іншим моделлю загроз, ніж думаєте.

Жарт №1: IOMMU — як бодігарді в нічному клубі для DMA. Він не виправить погані рішення всередині, але тримає випадкових незнайомців за дверима.

Що тут означає «продуктивність»

Люди кажуть «SR-IOV швидше за virtio». Іноді так. Але треба уточнити, по якій осі продуктивності:

  • Продуктивність (Gbps або IOPS) при заданому бюджеті CPU
  • Хвостова затримка (p99/p999), особливо під конкуренцією
  • Джиттер (варіативність), що ламає додатки близькі до реального часу
  • Ефективність CPU (цикли на пакет/IO)
  • Операційна продуктивність (наскільки швидко ви можете відлагодити і відновити сервіс)

SR-IOV і passthrough можуть бути чудовими для пропускної здатності й ефективності CPU. Вони також можуть погіршити хвостову затримку, якщо ви неправильно налаштували переривання, нічого не прилагаєте й дозволяєте планувальнику хоста імпровізувати.

SR-IOV проти passthrough: реальні компроміси

Ось суб’єктивна версія:

  • Якщо одній ВМ потрібен повний контроль над пристроєм (GPU, FPGA, HBA): використовуйте passthrough. SR-IOV не завжди доступний, і навіть коли є — паритет функцій буває дивним.
  • Якщо багатьом гостям потрібна продуктивність NIC близька до bare-metal: використовуйте SR-IOV, але ставтеся до управління VF як до частини платформи, а не як до хобі для кожної ВМ.
  • Якщо потрібна гнучкість (live migration, snapshopти, гетерогенні хости): віддавайте перевагу virtio і прийміть витрати CPU, якщо немає доведеної причини інакше.

Безпека та ізоляція: це різні історії

З passthrough гість отримує весь пристрій. Це добре для продуктивності і доступу до функцій, але погано для шарінгу. Ізоляція сильно залежить від коректності IOMMU і від поведінки пристрою. У SR-IOV ви ділите фізичний пристрій між орендарями, і ізоляція залежить від реалізації VF у NIC (розділення черг, обмеження швидкості, перевірки спуфінгу) плюс драйвер PF. Деякі VF можуть робити те, чого не повинні, якщо залишити певні прапори довіри ввімкненими.

Практичні поради:

  • Багатокорисувацький SR-IOV можливий, але потрібно явно налаштувати перевірку спуфінгу VF, примусове VLAN і налаштування trust на PF.
  • Passthrough для недовірених гостей сильно залежить від IOMMU і перенаправлення переривань. Якщо будь-яке з них відсутнє — ви приймаєте ризик.

Операції: SR-IOV виграє до першої проблеми

SR-IOV виглядає операційно «простим», бо ви можете роздавати VFs як цукерки. Потім з’являється прихована складність:

  • Провізіонування VF і збір сміття після ребутів
  • Несумісності прошивки/драйверів, що ламаються тільки при певній кількості черг
  • Прогалини в спостережуваності (хост бачить статистику PF; гість бачить VF; ніхто не бачить «end-to-end»)
  • Маршрування пакетів і афінність IRQ, що стають вимогою платформи

Passthrough простіший у сенсі «одна ВМ володіє пристроєм — один стек відлагоджується». Але складніший у сенсі втрати віртуалізаційних зручностей (міграція, snapshot-и, overcommit) і ризику вивести мережу хоста з ладу, якщо передати не те.

Брудна таємниця: обидва підходи все ще потребують банальної гігієни Linux

Прив’язка CPU, вирівнювання NUMA, афінність IRQ, розміри кілець і розумні MTU все ще мають значення. SR-IOV не врятує від ВМ, що запущена на неправильному сокеті, а passthrough не врятує від гостьового драйвера, налаштованого як науковий експеримент.

Коли IOMMU допомагає (і чому)

1) Утримання: ізоляція DMA — це головна мета

Без IOMMU пристрій, що виконує DMA, може отримати доступ до фізичних адрес пам’яті, які ви не мали наміру відкривати. У passthrough це може означати, що гостьовий керований пристрій (або його програмування гостем) може читати або псувати пам’ять хоста. З IOMMU простір адрес DMA (IOVA) транслюється через таблиці, якими керує хост.

У SR-IOV VF також виконують DMA. Якщо ви призначаєте VF гостям, ви все одно хочете IOMMU, щоб обмежити DMA VF пам’яттю гостя. Так, NIC «віртуалізований», але він все ще пристрій, що робить DMA.

2) Перенаправлення переривань: менше способів зіпсувати день

Сучасні IOMMU також можуть перенаправляти переривання (MSI/MSI-X), тож пристрій не може інжектити переривання в дивний спосіб. Це важливо при передачі пристроїв гостям. Без перенаправлення переривань ви можете опинитися в небезпечних режимах або отримати нестабільну поведінку залежно від підтримки платформи.

3) Дозволяє ввімкнути безпечні фічі, які інакше були б страшними

Якщо ви робите призначення пристроїв у масштабі, IOMMU — це шар, що дозволяє гарантувати «цей пристрій торкається тільки того, що повинен». Він відкриває можливість робити passthrough для реальних робочих навантажень, а не лише для лабораторних стендів.

4) Деякі шляхи продуктивності передбачають його

Парадоксально: інколи відключення IOMMU запускає відкат ядра, вимикає перенаправлення переривань або змінює стратегії відображення DMA. На деяких платформах «IOMMU вимкнений» — це не «режим швидкості», а «режим сумісності». Ви не обираєте пригоди; ваша материнська плата вже обрала їх за вас.

Коли IOMMU не допомагає (і може зашкодити)

Ось та частина, яку людям не хочеться чути: IOMMU — не магічний перемикач продуктивності. Це функція безпеки з наслідками для продуктивності. Іноді ці наслідки мізерні. Іноді вони лягають у ваш p99.

1) Високошвидкісний обробіток малих пакетів може підсилити накладні витрати трансляції

Якщо ваше навантаження — 64-байтові пакети при дуже високому PPS, вартість мапінгу/анмапінгу DMA, тиск на TLB в IOMMU і промахи IOTLB можуть виявитися помітними. Хороші драйвери амортизують витрати мапінгу (довгоживучі мапінги, hugepages, батчинг). Погані налаштування штампують мапінги й платять за це.

2) Неправильні hugepages або фрагментація пам’яті погіршують ситуацію

Якщо пам’ять гостя фрагментована, IOMMU потребує більше записів у таблицях сторінок, що підвищує ймовірність промахів IOTLB. З hugepages (і правильним pinning) ви зменшуєте відбиток трансляції. Ось чому інколи «SR-IOV повільніший за virtio»: це не SR-IOV; це стратегія відображення й розклад пам’яті.

3) Ви можете втратити фічі, на які розраховували

Деякі середовища вмикають IOMMU у режимі, що ламає або вимикає peer-to-peer DMA (пристроїв між собою) або змінює, як працюють ATS/PRI. Для стеків зберігання, що залежать від певних шаблонів DMA, ви можете отримати регресії, що виглядають як «баг у драйвері», але насправді це зміна поведінки трансляції.

4) Діагностика ускладнюється, бо режимів відмов більше

Якщо задіяний IOMMU, відмова може бути через:

  • баг гостьового драйвера
  • баг VFIO/QEMU на хості
  • платформний баг/особливість IOMMU
  • невідповідну настройку BIOS
  • дивні ACS-групування
  • поведінку прошивки під навантаженням

Жарт №2: Увімкнути IOMMU, щоб «поправити продуктивність», — як купити динамометричний ключ для ремонту пробитого колеса. Корисний інструмент, але не по темі.

Цікаві факти та історичний контекст

  • IOMMU з’явилися до хмарного хайпу. Вони виникли в різних формах для вирішення обмежень адресації DMA й ізоляції значно до того, як «multi-tenant» став маркетинговим терміном.
  • Адресація DMA колись була реальним обмеженням. Ранні системи мали пристрої, що могли DMA лише в межах обмежених діапазонів; IOMMU допомагали через перенаправлення адрес.
  • Intel VT-d і AMD-Vi зробили призначення пристроїв мейнстримом. Аппаратна трансляція DMA стала стандартною для серверів, що хотіли серйозну віртуалізацію.
  • MSI-X змінило гру для високопродуктивних NIC. Багато векторів переривань дозволили дизайни «черга на ядро», на які сильно покладається SR-IOV.
  • SR-IOV — стандарт PCI-SIG. Це не магія вендора, хоча реалізації вендорів сильно відрізняються за якістю і налаштуваннями.
  • «IOMMU groups» — про межі ізоляції. Групування відображає те, що апарат може ізолювати; це не винахід Linux, а експозиція апаратної реальності.
  • ACS став незручним героєм. Access Control Services впливає на те, як пристрої ізольовані за PCIe-комутаторами; відсутність ACS може змусити великі IOMMU-групи.
  • Virtio дозрів завдяки вимогам операційників. Virtio — не просто «повільна емуляція». Він еволюціонував у надійний парaвіртуальний інтерфейс, придатний для хмарних операцій.
  • DPDK і user-space мережі підвищили очікування. Коли люди побачили лінійну швидкість у user space, вони почали вимагати подібної поведінки від ВМ, що підштовхнуло SR-IOV у виробництво.

Швидкий план діагностики

Мета — швидко знайти вузьке місце, а не «повністю зрозуміти PCIe». Це можна зробити потім.

Перше: підтвердіть, що ви справді розгорнули

  1. Чи використовує навантаження virtio, SR-IOV VF чи повний passthrough?
  2. Чи ввімкнений IOMMU і працює (не лише «в BIOS задано»)?
  3. Чи перенаправлені переривання і чи ввімкнено MSI-X?

Друге: знайдіть домен конкуренції

  1. Вирівнювання NUMA: чи ВМ знаходиться на тому ж сокеті, що й PCIe-пристрій?
  2. Афінність IRQ: чи переривання прив’язані до відповідних CPU?
  3. Кількість черг: чи достатньо черг, або їх надто багато?

Третє: вирішіть, чи ви CPU-bound, IRQ-bound або DMA/IOMMU-bound

  1. Якщо CPU завантажений у softirq/ksoftirqd: це обробка пакетів і переривань/маршрування.
  2. Якщо CPU в нормі, але p99 поганий: дивіться на міграцію IRQ, стани живлення і IOTLB churn.
  3. Якщо пропускна здатність підрізається підозріло: перевірте швидкість лінку/ширину, узгоджений PCIe і offload-и.

Четверте: доведіть експериментом

  • Прив’яжіть vCPU і пам’ять до NUMA-вузла пристрою, повторіть тест.
  • Змініть афінність IRQ для черг VF, повторіть тест.
  • Увімкніть/вимкніть hugepages (або 2M vs 1G) на одному хості, повторіть тест.

Не змінюйте п’ять змінних і не оголошуйте перемогу. Так народжується фольклор.

Практичні завдання: команди, виходи та рішення

Це перевірки, які я реально виконую, коли хтось каже «SR-IOV повільний» або «passthrough нестабільний». Кожне завдання включає рішення, яке я приймаю за результатом.

Завдання 1: Підтвердити, що IOMMU ввімкнений у ядрі

cr0x@server:~$ dmesg | egrep -i 'iommu|vt-d|amd-vi|dmari' | head -n 25
[    0.142311] DMAR: IOMMU enabled
[    0.142355] DMAR: Host address width 46
[    0.142360] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.381200] DMAR-IR: Enabled IRQ remapping in x2apic mode

Що це означає: У вас є перенаправлення DMA (DMAR: IOMMU enabled) і перенаправлення переривань (DMAR-IR).

Рішення: Якщо ви не бачите цих рядків, не прикидайтеся, що існує ізоляція passthrough. Виправте BIOS/аргументи ядра перед діагностикою продуктивності.

Завдання 2: Перевірити cmdline ядра щодо режиму IOMMU і поширених пасток

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.8.0 root=/dev/mapper/vg0-root ro quiet intel_iommu=on iommu=pt mitigations=auto

Що це означає: intel_iommu=on його вмикає; iommu=pt використовує passthrough-мепінги для хост-пристроїв (часто зменшує накладні витрати для не‑призначених пристроїв).

Рішення: Для змішаних навантажень iommu=pt зазвичай розумний вибір. Якщо ви налагоджуєте ізоляцію, тимчасово можна його прибрати, щоб подивитися на зміну поведінки — але документуйте причину.

Завдання 3: Визначити, чи ви використовуєте SR-IOV VFs або повні пристрої

cr0x@server:~$ lspci -D | egrep -i 'ethernet|network' | head
0000:3b:00.0 Ethernet controller: Intel Corporation Ethernet Controller XXV710 for 25GbE SFP28
0000:3b:02.0 Ethernet controller: Intel Corporation Ethernet Virtual Function
0000:3b:02.1 Ethernet controller: Intel Corporation Ethernet Virtual Function

Що це означає: PF — 3b:00.0, і VFs існують на 3b:02.x.

Рішення: Якщо ви очікуєте SR-IOV, але бачите лише PF — SR-IOV не використовується; ви налагоджуєте не ту річ.

Завдання 4: Підтвердити кількість створених VF на PF

cr0x@server:~$ sudo cat /sys/class/net/enp59s0f0/device/sriov_numvfs
8

Що це означає: На PF наразі ввімкнено 8 VFs.

Рішення: Якщо 0 — VF немає. Якщо більше, ніж планували, ви можете виснажувати ресурси PF (черги, TCAM, переривання). Зменшіть кількість VF і повторно перевірте стабільність.

Завдання 5: Перевірити IOMMU-групи для меж ізоляції

cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group $(basename $g):"; ls -1 $g/devices; done | sed -n '1,40p'
Group 12:
0000:3b:00.0
0000:3b:00.1
Group 13:
0000:3b:02.0
0000:3b:02.1

Що це означає: Пристрої в одній групі апаратно не можна безпечно ізолювати один від одного.

Рішення: Якщо ваш цільовий пристрій ділить групу з тим, що ви не можете передати (наприклад контролер зберігання), не використовуйте passthrough на такому хості. Виправте топологію PCIe або прийміть virtio.

Завдання 6: Перевірити, до якого драйвера прив’язано (на стороні хоста)

cr0x@server:~$ lspci -nnk -s 0000:3b:02.0
3b:02.0 Ethernet controller [0200]: Intel Corporation Ethernet Virtual Function [8086:154c]
	Subsystem: Intel Corporation Device [8086:0000]
	Kernel driver in use: vfio-pci
	Kernel modules: iavf

Що це означає: VF прив’язано до VFIO для passthrough; нативний VF драйвер існує, але не активний на хості.

Рішення: Якщо ви очікували хостову мережу через VF, бачити vfio-pci — нормально. Якщо очікували, що хост буде його використовувати — це ваша неправильна конфігурація.

Завдання 7: Перевірити, чи ВМ справді має пристрій прикріпленим (QEMU/libvirt)

cr0x@server:~$ sudo virsh domiflist vm-netperf-01
Interface  Type     Source     Model   MAC
-------------------------------------------------------
vnet0      bridge   br0        virtio  52:54:00:aa:bb:cc

Що це означає: Ця ВМ все ще використовує virtio через міст, а не SR-IOV VF passthrough.

Рішення: Припиніть сперечатися про налаштування SR-IOV. Спочатку прикріпіть VF-пристрій і підтвердьте зміни драйвера всередині гостя.

Завдання 8: Перевірити узгоджену швидкість/ширину PCIe (типова безшумна капса)

cr0x@server:~$ sudo lspci -s 3b:00.0 -vv | egrep -i 'LnkSta:|LnkCap:' | head -n 4
LnkCap:	Port #0, Speed 8GT/s, Width x8
LnkSta:	Speed 8GT/s, Width x4

Що це означає: Картка підтримує x8, але працює на x4. Це фізична/топологічна/BIOS проблема, а не баг драйвера.

Рішення: Якщо обмеження пропускної здатності відповідає x4, переставте карту, змініть riser або виправте налаштування біфуркації BIOS. Не налаштовуйте черги, щоб вирішити відсутні лінії.

Завдання 9: Перевірити NUMA-локальність PCI-пристрою

cr0x@server:~$ cat /sys/bus/pci/devices/0000:3b:00.0/numa_node
1

Що це означає: Пристрій приєднано до NUMA-вузла 1.

Рішення: Розмістіть vCPU і пам’ять ВМ на вузлі 1. Якщо не можете — прийміть вищу затримку й нижчу пропускну здатність або переставте пристрій на інший сокет.

Завдання 10: Знайти IRQ черг VF і подивитися, де вони опиняються

cr0x@server:~$ grep -E 'enp59s0f0v0|iavf|vfio|msi' /proc/interrupts | head -n 8
 178:     120433          0          0          0  IR-PCI-MSI 524288-edge      vfio-msi[0]
 179:     118901          0          0          0  IR-PCI-MSI 524289-edge      vfio-msi[1]
 180:     119552          0          0          0  IR-PCI-MSI 524290-edge      vfio-msi[2]

Що це означає: Всі переривання лягають на CPU0 (перший стовпець), бо афінність не налаштована або irqbalance зробив «креативний» вибір.

Рішення: Прив’яжіть IRQ до CPU, локальних для NIC, і бажано розподіліть черги по ізольованих ядрах. Потім повторно перевірте p99 затримку.

Завдання 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-02 09:14:12 UTC; 1 day ago

Що це означає: irqbalance запущений і може динамічно переміщувати IRQ.

Рішення: Для чутливих до затримки SR-IOV/passthrough навантажень розгляньте відключення irqbalance і явне встановлення афінності — особливо на хостах з CPU-ізоляцією.

Завдання 12: Перевірити конфігурацію hugepages (хост)

cr0x@server:~$ grep -i huge /proc/meminfo | head -n 6
HugePages_Total:    2048
HugePages_Free:     1980
HugePages_Rsvd:       12
Hugepagesize:       2048 kB
Hugetlb:         4194304 kB

Що це означає: 2M hugepages доступні і майже вільні.

Рішення: Якщо ви ганяєтеся за накладними витратами IOMMU/IOTLB, hugepages — важливий важіль. Якщо HugePages_Free низький, можлива фрагментація або витік резервацій; виправте перед тим, як звинувачувати SR-IOV.

Завдання 13: Перевірити, чи ВМ використовує hugepages (libvirt)

cr0x@server:~$ sudo virsh dumpxml vm-netperf-01 | egrep -n 'memoryBacking|hugepages|locked'
112:  
113:    
114:    
115:  

Що це означає: Пам’ять ВМ підкріплена hugepages і заблокована (зменшує churn сторінок і сюрпризи).

Рішення: Якщо ви використовуєте SR-IOV/passthrough і дбаєте про хвостову затримку, це зазвичай варто зробити. Якщо не можете заблокувати пам’ять — чекайте варіативності при тиску хоста.

Завдання 14: Перевірити на помилки IOMMU (ви будете здивовані)

cr0x@server:~$ dmesg | egrep -i 'DMAR:.*fault|IOMMU.*fault|AMD-Vi:.*Event' | tail -n 10
[12345.671234] DMAR: [DMA Read] Request device [3b:02.0] fault addr 0x7f3a1000 [fault reason 0x05] PTE Read access is not set

Що це означає: Пристрій намагався виконати DMA поза дозволеними мапінгами або мапінги неправильно знімаються.

Рішення: Стоп. Це не тюнінг issue; це питання коректності. Перевірте версії VFIO/QEMU, баги драйверів і чи ви не відключаєте пристрої небезпечно під час роботи.

Завдання 15: Перевірити NIC offload-и всередині гостя (SR-IOV VFs відрізняються)

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

Що це означає: Offload-и ввімкнені як очікувалося; LRO вимкнено (часто корисно для латентності/спостережуваності).

Рішення: Якщо offload-и несподівано вимкнені — ви платите CPU. Якщо вони ввімкнені, але бачите дивні трасування пакетів, розгляньте відключення GRO для налагодження — не як постійне «вирішення».

Завдання 16: Перевірити антиспуфінг і налаштування trust для VF на PF (хост)

cr0x@server:~$ sudo ip link show enp59s0f0
2: enp59s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
cr0x@server:~$ sudo ip link show enp59s0f0 vf 0
vf 0 MAC 52:54:00:11:22:33, vlan 100, spoof checking on, link-state auto, trust off, query_rss on

Що це означає: VF має VLAN-примус, перевірку спуфінгу ввімкнено, trust вимкнено. Це добрий дефолт для спільних середовищ.

Рішення: Якщо бачите trust on «бо це щось виправило», вимагайте конкретного пояснення і додайте компенсуючі контролі. Trust має властивість розповзатися як цвіль.

Завдання 17: Підтвердити governor частоти CPU/стани живлення (джерело хвостових затримок)

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

Що це означає: CPU може агресивно знижувати частоту, що шкодить p99 затримці.

Рішення: Для високопродуктивних dataplane-хостів використовуйте governor performance або платформно‑адекватне налаштування. Якщо не можете — не чекайте детермінованої латентності.

Завдання 18: Перевірити softirq-навантаження (здоров’я мережевого dataplane)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server)  02/04/2026  _x86_64_  (32 CPU)

02:11:01 PM  CPU   %usr %nice %sys %iowait %irq %soft %steal %idle
02:11:02 PM  all   12.5  0.0   9.8    0.0   2.1  18.7    0.0   56.9

Що це означає: Високий %soft вказує на інтенсивну обробку softirq; типово для пакетно‑насичених навантажень.

Рішення: Додайте черг/ядер, покращіть IRQ affinity/RPS/XPS або переходьте на SR-IOV/DPDK, якщо virtio є вузьким місцем. Якщо ви вже на SR-IOV — це вказує на steering і розміщення CPU.

Три корпоративні міні-історії з поля бою

Міні-історія 1: Інцидент через неправильне припущення

Вони впроваджували NIC passthrough для сервісу, чутливого до затримки. Ідея була проста: «прибрати віртуальний комутатор, зменшити накладні витрати, знизити p99». Тестовий хост пройшов. Канарка пройшла. А потім продакшн почав дивно поводитися.

Один кластер почав ребутитися під навантаженням. Не всі вузли. Лише ті в певному ряду шаф. Логи показували спорадичні DMA‑фолти і іноді жорсткий локдаун без чистого panic. Команда спочатку думала «баг драйвера». Вони оновлювали гостьові драйвери. Оновлювали QEMU. Тиснули offload-и. Привиди продовжувалися.

Неправильне припущення було в тому, що «IOMMU ввімкнено в BIOS» означає «IOMMU реально працює повністю». На уражених вузлах BIOS мав цю настройку, але платформа постачалася із перенаправленням переривань вимкненим через старішу прошивку. Linux вмикав DMA‑ремапінг, але не міг коректно ввімкнути перенаправлення переривань на цій ревізії апаратури.

Вони передавали пристрій, який сипав MSI‑X під піковим навантаженням, і без гарантій правильної роботи перенаправлення переривань платформа поводилася непередбачувано. Проблема була не в тому, що IOMMU «вимкнено»; вона була в тому, що критична частина функціоналу не була надійно увімкнена.

Виправлення було нудним: стандартизувати BIOS‑профілі, додати boot‑time перевірку, що відкидає вузол, якщо DMAR-IR не увімкнено, і відмовлятися від планування passthrough на таких хостах. Продуктивність потім покращилася, але інцидент завершився, коли припинили обманювати себе щодо можливостей платформи.

Міні-історія 2: Оптимізація, що відкотилася назад

Інша компанія використовувала SR-IOV VF для високопропускних навантажень. Хтось зауважив, що накладні витрати трансляції IOMMU можуть додавати CPU‑вартість при екстремальному PPS. Вони знайшли iommu=pt і вирішили «оптимізувати» ще далі: відключити IOMMU на хості, бо «гості мають тільки VF і NIC їх ізолює».

Спочатку виглядало як виграш. Мікробенчмарки трохи покращилися, графіки CPU стали охайніші. Потім реальне навантаження вдарило: спорадична корупція даних у сервісі збереження, що також використовував інший passthrough‑пристрій на деяких вузлах. Не скрізь — лише там, де планування зіткнулося з певною комбінацією призначення пристроїв і тиску пам’яті.

Без IOMMU поганий пристрій (або баг у взаємодії) міг DMA в пам’ять, куди не повинен був. Корупція була тихою: рідкісні невідповідності контрольних сум, випадкові крахи процесів, «неможливі» переходи станів. Найгірший тип інциденту: той, що змушує команду сумніватися в фізиці.

Вони відкликали зміну, і корупція зупинилася. Постмортем не був ласкавим: оптимізація гналася за теоретичною вигодою, стираючи запобіжну огорожу. Вартість «виграшу» — дні реагування на інциденти, огляди ризиків і нова політика: IOMMU залишається ввімкненим; якщо продуктивність проблема, виправляйте стратегію відображення (hugepages, pinning) або змінюйте дизайн dataplane.

Міні-історія 3: Нудна правильна практика, що врятувала день

Одна платформа мала змішаний флот: хости для загальної віртуалізації (virtio всюди) і менший пул для високопродуктивного SR-IOV та інколи GPU passthrough. Вони були відомі тим, що надто суворі щодо профілів хостів.

Кожний бут виконував чекліст: перевірити IOMMU ввімкнено, перевірити перенаправлення переривань, перевірити ширину лінку NIC, перевірити версії прошивки по allowlist, перевірити кількість VF, перевірити обмеження NUMA. Якщо будь-яка перевірка провалювалася, вузол автоматично дренувався. Ніяких героїчних дій. Жодних переговорів.

Одного дня прийшла партія серверів із тонкою відмінністю топології PCIe. NIC узгодив x4 замість x8 у певній конфігурації слота. Ніщо «не ламалося». Жодних алертів від драйвера NIC. Додатки просто стали повільніші, ніби «стрибок трафіку».

Boot gate це підловив: LnkSta не відповідав очікуванням. Вузли не потрапили в SR-IOV пул. Робочі навантаження залишилися на здорових хостах, а єдиний «інцидент» — тикет в операції дата‑центру переставити карти в інші слоти.

Практика, що врятувала їх, не була хитрим tюнінгом ядра. Вона полягала в відмові приймати мовчазну деградацію. Надійність — це переважно вирішення того, що ви не готові терпіти.

Поширені помилки: симптом → корінь → виправлення

1) Симптом: «Passthrough увімкнено, але продуктивність гірша ніж virtio»

Корінь: ВМ знаходиться в remote‑NUMA від пристрою; переривання лягають на невідповідні CPU; пам’ять не закріплена; IOTLB churn через фрагментовану пам’ять.

Виправлення: Вирівняйте vCPU і пам’ять до NUMA‑вузла NIC, ввімкніть hugepages + locked memory, налаштуйте афінність IRQ, підберіть кількість черг під ядра.

2) Симптом: «SR-IOV VF рандомно втрачає лінк або зависає під навантаженням»

Корінь: Баг драйвера PF/прошивки, тригерується кількістю VF, кількістю черг або комбінацією offload‑ів; інколи погіршується при ресетах.

Виправлення: Оновіть прошивку NIC + драйвер PF; зменшіть VF/черги; уникайте екзотичних комбінацій offload; додайте health checks, що відтворюють VF при помилці.

3) Симптом: «VFIO attach не вдається: device is busy / can’t reset»

Корінь: Пристрій прив’язано до драйвера хоста або є частиною групи з іншими функціями в використанні; обмеження FLR/reset.

Виправлення: Правильно відв’яжіть, переконайтеся в ізоляції за IOMMU group, уникайте passthrough пристроїв без надійної семантики reset або використайте SR-IOV замість цього.

4) Симптом: «IOMMU groups величезні; не можу ізолювати NIC»

Корінь: Топологія PCIe не має ACS або пристрої ділять upstream компоненти, що не можуть забезпечити ізоляцію.

Виправлення: Змініть слот/топологію, використайте хости з ACS‑сумісними комутаторами або припиніть намагатися робити безпечний passthrough на цій платформі.

5) Симптом: «Висока p99 затримка лише під час конкуренції на хості»

Корінь: Масштабування частоти CPU, міграція IRQ, reclaim пам’яті або шумні сусіди на тому ж сокеті.

Виправлення: Ізолюйте ядра для dataplane, встановіть governor performance, відключіть irqbalance (або налаштуйте його), резервуйте hugepages, заблокуйте пам’ять, встановіть реальні політики NUMA.

6) Симптом: «Пакети падають у гості, а хост виглядає нормально»

Корінь: Голод черг VF, недостатній розмір кілець, надто агресивне згортання переривань або неправильне налаштування гостьового драйвера.

Виправлення: Збільшіть розміри кілець, відкоригуйте coalescing, переконайтеся в MSI‑X векторах, забезпечте достатню кількість черг, прив’яжіть vCPU і перевірте версію гостьового драйвера.

7) Симптом: «Команда безпеки каже, що SR-IOV небезпечний»

Корінь: Політики VF trust/spoof/VLAN залишені надмірно дозволеними; нерозуміння ризиків спільного апаратного забезпечення.

Виправлення: Запровадьте політики VF на PF, обмежте функції для орендаря, проведіть аудит призначення пристроїв, увімкніть IOMMU, документуйте модель загроз.

Контрольні списки / покрокові плани

Контрольний список A: Вибір SR-IOV vs passthrough (рішення, не враження)

  1. Потрібно шарувати пристрій між багатьма гостями? SR-IOV. Якщо пристрій погано підтримує SR-IOV — перегляньте обладнання.
  2. Потрібні повні функції пристрою (GPU, HBA advanced modes, вендорські інструменти)? Passthrough.
  3. Потрібна live migration/snapshots? Віддавайте перевагу virtio. SR-IOV/passthrough ускладнюють або блокують це.
  4. Низька толерантність до ризику багатокористувацького середовища? Passthrough з IOMMU і суворими перевірками платформи, або взагалі уникайте призначення пристроїв.
  5. Операційна зрілість: Якщо ви не можете стандартизувати BIOS/прошивку/версії ядра — не робіть призначення пристроїв у масштабі.

Контрольний список B: План впровадження SR-IOV (що робити по порядку)

  1. Стандартизувати BIOS налаштування (VT-d/AMD-Vi увімкнено, SR-IOV увімкнено, узгоджені PCIe параметри).
  2. Стандартизувати cmdline ядра і валідовувати через dmesg ворота.
  3. Обрати кількість VF на PF базуючись на апаратних обмеженнях і потребах черг (не максимізуйте за замовчуванням).
  4. Визначити політику VF: перевірка спуфінгу ввімкнена, trust вимкнено за замовчуванням, VLAN політика явна.
  5. Визначити політику розміщення NUMA для SR-IOV хостів і примусово її застосувати через scheduler.
  6. Реалізувати стратегію афінності IRQ; не покладайтеся на випадок.
  7. Провести канарку під реальними шаблонами трафіку (PPS + розміри пакетів + кількість потоків).
  8. Спостерігати p99/p999, падіння пакетів, ресети і IOMMU‑fault; просуватися далі тільки коли все нудно стабільно.

Контрольний список C: План впровадження passthrough (не спалюйте хост)

  1. Перевірити, що IOMMU і перенаправлення переривань увімкнені і стабільні між перезавантаженнями.
  2. Перевірити IOMMU‑групи і переконатися, що пристрій можна ізолювати.
  3. Перевірити підтримку скидання пристрою (FLR або вендорні механіки reset) на надійність.
  4. Прив’язати пристрій до vfio-pci і підтвердити, що сервіси хоста його не потребують.
  5. Прив’язати vCPU і пам’ять ВМ до NUMA‑вузла пристрою; використовувати hugepages, якщо важлива детермінованість.
  6. Інструментувати: збирати dmesg IOMMU‑fault, PCIe AER помилки і метрики розподілу переривань.
  7. Мати відкат: від’єднати пристрій, переприв’язати до драйвера хоста, відновити мережеві/зберігальні шляхи.

FAQ

1) Чи SR-IOV завжди швидший за virtio?

Ні. SR-IOV часто зменшує CPU на пакет і покращує пропускну здатність, але може програти за хвостовою затримкою, якщо IRQ/NUMA/відображення пам’яті налаштовані погано. Virtio може бути «достатньо швидким» і значно простішим у експлуатації.

2) Чи passthrough завжди найшвидший варіант?

Часто для власності пристрою одним орендарем — так. Але «найшвидший» залежить від розміщення і обробки переривань. Remote‑NUMA passthrough може бути повільнішим за добре налагоджений virtio шлях.

3) Чи потрібен IOMMU для SR-IOV?

Якщо ви призначаєте VF гостям — бажано мати IOMMU для ізоляції DMA. Якщо все лишається на хості, це менше про ізоляцію — але багато платформ поводяться краще з консистентною конфігурацією IOMMU.

4) Що насправді робить iommu=pt?

Зазвичай воно встановлює identity/pass-through мапінги для хост‑пристроїв, щоб вони не платили за трансляцію, водночас дозволяючи трансляцію для призначених пристроїв. Це компроміс між продуктивністю і безпекою.

5) Чому мої IOMMU‑групи «занадто великі»?

Тому що ваше апаратне забезпечення не може ізолювати ці пристрої один від одного. Топологія PCIe і підтримка ACS визначають групування. Linux показує межу, якій він може довіряти, а не ту, яку ви хотіли б мати.

6) Чи можна жити мігрувати ВМ з SR-IOV або passthrough?

Не в звичному «просто працює» сенсі. Призначення пристроїв прив’язує ВМ до стану конкретного обладнання. Деякі екосистеми мають спеціальні підходи до міграції, але ставте це як спеціальний проєкт, а не галочку.

7) Яка найпоширеніша причина повідомлень «SR-IOV нестабільний»?

Несумісність прошивки/драйвера і перевантаження ресурсів на NIC (занадто багато VF, занадто багато черг, надто агресивні налаштування). Друга причина — операційна: VF не відновлюються послідовно після ребута або подій лінку.

8) Чи додає IOMMU помітну затримку?

Може, особливо коли мапінги часто оновлюються або промахи IOTLB ростуть. З закріпленою пам’яттю, hugepages і стабільними мапінгами накладні витрати часто невеликі в порівнянні з рештою dataplane.

9) Чи варто відключити irqbalance на SR-IOV/passthrough хостах?

Для чутливих до латентності навантажень — так, якщо тільки ви явно не налаштували irqbalance з урахуванням ізоляції і локальності. Динамічна міграція IRQ і детермінований p99 — погані сусіди.

10) Яка найпростіша «безпечна за замовчуванням» архітектура?

Virtio для загальних обчислень, окремий пул SR-IOV для продуктивних навантажень і passthrough тільки для пристроїв, що дійсно потребують повної власності. Тримайте профілі хостів суворими і валідованими.

Практичні подальші кроки

Рішення приймайте на підставі вашої операційної реальності, а не знімка бенчмарку.

  1. Визначте базу: якщо ви зараз на virtio — спочатку очистіть NUMA/IRQ гігієну. Інакше ви не зрозумієте, що саме покращив SR-IOV.
  2. Увімкніть IOMMU правильно: підтвердіть перенаправлення DMA і переривань у dmesg. Заблокуйте флот на цьому.
  3. Обирайте правильну модель: SR-IOV для прискорення спільних NIC, passthrough для повної власності пристрою, virtio для гнучкості.
  4. Операціоналізуйте: стандартизувати прошивку, BIOS, аргументи ядра, кількість VF і політику безпеки VF. Автоматизуйте перевірки; дренуйте вузли при невідповідності.
  5. Вимірюйте правильні речі: стежте за p99/p999 затримками і падіннями, а не лише за середньою пропускною здатністю. Більшість інцидентів живе в хвостах.

Цитата, варта нотатки: «Hope is not a strategy.» — General Gordon R. Sullivan

← Попередня
Кластер Proxmox: чому Corosync виглядає нормально, а ваш кластер гине
Наступна →
Однорядкові PowerShell, що замінюють 10 кліків у GUI (використовуйте щодня)

Залишити коментар