Ubuntu 24.04 — жорсткі зависання: швидко зібрати докази та звузити коло причин

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

Жорсткі зависання — найгірший різновид «система зависла», бо вони настільки серйозні, що забирають з собою ядро. Ваш SSH сеанс застигне, консоль перестане оновлюватися, і єдиним чутливим елементом залишиться кнопка живлення. Потім ви перезавантажуєтеся, і dmesg зустрічає вас рядком: “watchdog: BUG: hard LOCKUP”. Чудово. І що далі?

Це практичний, придатний для продакшену підхід «спочатку докази» для Ubuntu 24.04: зберіть потрібні артефакти під час наступного зависання, швидко звузьте простір пошуку й уникайте випадкових змін, які роблять проблему неможливою для доведення.

Що насправді означає «жорстке зависання» (і чого воно не означає)

У Linux «hard lockup» — це сповіщення ядра про те, що одне апаратне ядро CPU перестало реагувати на переривання занадто довго. Таймер watchdog очікує періодичної активності (зазвичай від високопріоритетного таймерного переривання або контексту NMI залежно від налаштувань). Якщо CPU застряг з вимкненими перериваннями, крутиться в нескінченному циклі, завис у мікрокоді/прошивці або потрапив у зламаний шлях драйвера, watchdog кричить.

Чим воно не є: не розмите повідомлення «система була повільною». Можна мати жахливу латентність, безконтрольний iowait або перевантажену машину без жорстких зависань. Hard lockup ближчий до «CPU пішов у відпустку і нікому не повідомив».

У dmesg зазвичай бачите щось на кшталт:

  • watchdog: BUG: hard LOCKUP on cpu X
  • Іноді передує скидання GPU, таймаути NVMe, RCU stall або повідомлення «NMI watchdog»
  • Іноді після цього немає нічого, бо система занадто зависла, щоб логувати

Жорсткі зависання можуть спричиняти:

  • Краєві випадки енергоменеджменту CPU (C-states, P-states, драйвери cpufreq)
  • Помилки прошивки/BIOS (SMI-шторм, биті ACPI-таблиці, взаємодія з мікрокодом)
  • Драйвери пристроїв (GPU, HBA, NIC, модулі поза ядром)
  • IOMMU/маршрутизація переривань
  • Таймаути прошивки сховища, що викликають патологічні гілки коду ядра
  • Теплова/вольтажна нестабільність (так, іноді «це апарат» — правильна відповідь)

Є родич: «soft lockup». Це коли CPU занадто довго виконує код ядра без сдавання, але переривання все ще працюють. Soft lockups погані; hard lockups — «дзвоніть резервному інженеру» погані.

Факти та невеликі історичні підказки, які стануть у пригоді о 3 ранку

  • Факт 1: Детектор hard-lockup у Linux історично орієнтується на NMI watchdog на x86, бо NMI спрацьовує навіть коли звичайні переривання вимкнені.
  • Факт 2: Попередження «RCU stall» часто з’являються поруч із зависаннями, але вони не те саме, що hard lockup. RCU stall означає, що CPU не досягає квазіштатних станів; hard lockup — швидше випадок, коли CPU перестав відповідати взагалі.
  • Факт 3: Проблеми ACPI та SMI (System Management Interrupt) давно є класичним джерелом «все змовкло» поведінки — особливо на прошивці виробників, оптимізованій під Windows, а не під детерміністичність Linux.
  • Факт 4: Обробка помилок NVMe значно покращилася з роками, але «шторм скидань» усе ще може ескалувати до загальносистемних зависань, якщо переривання й таймаути накопичуються невірним чином.
  • Факт 5: Детектори зависань у ядрі навмисно консервативні. Краще надокучити попередженням, ніж пропустити реальний випадок «мертвого» CPU.
  • Факт 6: Датчик «hung task» ядра — знову інший: він виявляє заблоковані таски (часто I/O waits), а не мертві CPU. Люди постійно їх плутають.
  • Факт 7: Ранні роботи над «tickless» ядром (NO_HZ) покращили енергоспоживання, але також змінили поведінку таймінгів; деякі баги виявляються лише при специфічних поєднаннях таймерів/idle.
  • Факт 8: Оновлення мікрокоду може виправити зависання, але також може виявити латентні проблеми драйверів чи прошивки через зміну таймінгів. «Після оновлень стало гірше» не обов’язково означає «оновлення поламало».

Одна парафразована ідея надійності, яка досі вірна: якщо ви не можете виміряти — ви не можете керувати. — W. Edwards Deming (парафраз)

Швидкий план діагностики (перший/другий/третій)

Це розділ «перестань гортати, зроби це зараз». Мета — швидко вирішити, чи маєте ви справу з: (a) відомою проблемою драйвера/прошивки, (b) краєвим випадком енергоменеджменту, (c) патологією шляху сховища/переривань, або (d) відмовою апаратного забезпечення.

Перший: підтвердьте, що це lockup, і збережіть останні релевантні рядки

  1. Витягніть логи попереднього завантаження (persistent journal) і шукайте найраніші передвісники: скидання NVMe, GPU Xid, помилки прошивки iwlwifi, «irq X: nobody cared», «RCU stall», MCE-помилки.
  2. Визначте, чи потрібен дамп ядра. Якщо ви можете відтворювати раз на тиждень або частіше — вам потрібен kdump. Інакше ви будете сперечатися на рівні відчуттів.
  3. Занотуйте версії ядра та прошивки перед будь-якими змінами. Оновлення змінюють таймінги і можуть «виправити» випадково.

Другий: ізолюйте типових підозрюваних контрольованими перемиканнями

  1. Модулі поза ядром і GPU: тимчасово звантажуйте без пропрієтарних драйверів GPU або DKMS-модулів, якщо це можливо.
  2. Енергоменеджмент: робіть по одній зміні за раз: відключіть глибокі C-states (processor.max_cstate=1) або відключіть intel_pstate (або змініть governor). Не кидатися десятьма параметрами ядра одночасно.
  3. IOMMU: перемикайте налаштування IOMMU, якщо бачите помилки DMA/IOMMU або дивну поведінку переривань.

Третій: навантажте підозрілу підсистему і спостерігайте лічильники

  1. Сховище: запустіть контрольоване I/O навантаження й слідкуйте за лічильниками помилок NVMe, латентністю та скиданнями.
  2. CPU/тепловий режим: перевірте MCE-логи, температури та поведінку частоти.
  3. Переривання: ідентифікуйте шторм переривань або «завислі» IRQ; встановіть, який пристрій володіє шумною лінією.

Жарт #1: Жорстке зависання — це спосіб вашого сервера запросити «team-building» між ядром і BIOS.

Підхід «спочатку докази» — налаштування перед будь-якими змінами

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

Ваше завдання — виробити артефакти, що переживуть перезавантаження. Для Ubuntu 24.04 короткий список:

  • Persistent журнал системи між перезавантаженнями
  • Кільцева буферна пам’ять ядра з попереднього завантаження (або вивід netconsole)
  • Каптур kdump (vmcore + dmesg), якщо машина може панікувати/перезавантажуватися
  • Логи апаратних помилок: MCE, EDAC, IPMI SEL (для серверів), SMART/NVMe логи
  • Версії прошивки та мікрокоду
  • Малий журнал змін: що ви тестували і що змінилося

Забезпечте збереження логів після перезавантаження (journald persistence)

Ubuntu часто за замовчуванням має persistent логи на серверах, але не завжди; контейнери/VM можуть поводитися дивно. Зробіть це явним:

cr0x@server:~$ sudo grep -R "^\s*Storage=" /etc/systemd/journald.conf /etc/systemd/journald.conf.d/* 2>/dev/null || true
...output...

Якщо нічого не бачите — задайте persistent і перезапустіть journald:

cr0x@server:~$ sudo install -d -m 2755 /etc/systemd/journald.conf.d
cr0x@server:~$ printf "[Journal]\nStorage=persistent\nSystemMaxUse=2G\n" | sudo tee /etc/systemd/journald.conf.d/persistent.conf
[Journal]
Storage=persistent
SystemMaxUse=2G
cr0x@server:~$ sudo systemctl restart systemd-journald

Рішення: Якщо ваші зависання рідкісні, persistent логи обов’язкові. Якщо диск малий — обмежте розмір; не відключайте збереження.

Увімкніть kdump (коли вам потрібні відповіді, а не здогадки)

Kdump — ваш чорний ящик. Він не завжди спрацьовує при hard lockup (бо система може бути надто «мертва», щоб акуратно панікувати), але коли спрацьовує — це золото. В Ubuntu:

cr0x@server:~$ sudo apt-get update
cr0x@server:~$ sudo apt-get install -y linux-crashdump crash kexec-tools
...output...

Потім виділіть пам’ять для crashkernel і вмикніть:

cr0x@server:~$ sudo sed -n '1,200p' /etc/default/grub
...output...

Відредагуйте, додавши щось на кшталт crashkernel=512M для типової машини (більше для великих ОЗП), потім:

cr0x@server:~$ sudo update-grub
...output...
cr0x@server:~$ sudo systemctl enable --now kdump-tools
...output...

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

Увімкніть Magic SysRq (інколи вдається «розмережити» систему та зняти стан)

Hard lockups часто ігнорують SysRq, бо переривання мертві на ураженому CPU. Але на SMP-системах інший CPU може ще працювати досить довго, щоб SysRq згенерував backtrace.

cr0x@server:~$ cat /proc/sys/kernel/sysrq
176

Значення різняться; 176 зазвичай дозволяє sync/remount/reboot та деякі debug-функції. Для повного ввімкнення:

cr0x@server:~$ echo 'kernel.sysrq = 1' | sudo tee /etc/sysctl.d/99-sysrq.conf
kernel.sysrq = 1
cr0x@server:~$ sudo sysctl -p /etc/sysctl.d/99-sysrq.conf
kernel.sysrq = 1

Рішення: У тимчасових цілях вмикайте SysRq на хостах для відлагодження. У високобезпечних середовищах врахуйте політику; але при інцидентах докази важливіші за чистоту.

Розгляньте netconsole для «рядка логу безпосередньо перед смертю»

Коли диски зависають і локальна консоль заморожена, передача повідомлень ядра по UDP на інший хост може зловити останній видих. Це особливо корисно для випадків зі сховищем і драйверами.

Практичні завдання: команди, виводи, рішення (12+)

Це польові завдання. Запустіть їх, прочитайте вивід і прийміть рішення. Кожне завдання тут тому, що воно змінює те, що ви робитимете далі.

Завдання 1: Підтвердьте точну версію ядра, збірку й параметри завантаження

cr0x@server:~$ uname -a
Linux server 6.8.0-52-generic #53-Ubuntu SMP PREEMPT_DYNAMIC Fri Nov 15 12:34:56 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0-52-generic root=UUID=... ro quiet splash

Що це означає: Потрібна точна версія ядра для кореляції з відомими регресіями і щоб перевірити, що зміни справді застосовано.

Рішення: Якщо ви запускаєте HWE/edge ядра або кастомні збірки — зафіксуйте це. Не змішуйте «можливо, це ядро» з невідомим походженням.

Завдання 2: Витягніть логи ядра попереднього завантаження (journal) і відфільтруйте сигнали зависання

cr0x@server:~$ sudo journalctl -k -b -1 | egrep -i "hard LOCKUP|soft lockup|watchdog|RCU stall|NMI|hung task|MCE|IOMMU|nvme|AER|Xid|amdgpu|i915|EDAC" | tail -n 120
...output...

Що це означає: Шукайте передвісники: скидання NVMe, PCIe AER спам, помилки GPU, machine check exceptions, IOMMU помилки.

Рішення: Якщо бачите апаратні помилки (MCE/EDAC/AER) — пріоритет апаратних/прошивкових варіантів перед програмною тонкою настройкою.

Завдання 3: Перевірте, чи логи зберігаються і чи розмір адекватний

cr0x@server:~$ journalctl --disk-usage
Archived and active journals take up 1.2G in the file system.

Що це означає: Якщо використання диску маленьке і ви часто перезавантажуєтесь, можливо, втрачається релевантна історія.

Рішення: Збільшіть SystemMaxUse, якщо ви обрізаєте старі завантаження; зменшіть, якщо кореневий диск малий.

Завдання 4: Подивіться, як виглядало попереднє вимкнення (чисте чи аварійне)

cr0x@server:~$ last -x | head -n 12
reboot   system boot  6.8.0-52-generic Mon Dec 29 09:18   still running
crash    system crash 6.8.0-52-generic Mon Dec 29 09:02 - 09:18  (00:16)
...output...

Що це означає: Записи «crash» часто вказують на раптові скидання або watchdog-перезавантаження.

Рішення: Якщо є записи crash без логів — налаштуйте netconsole і kdump, щоб ловити більше даних.

Завдання 5: Перевірте апаратні логи помилок (MCE на x86)

cr0x@server:~$ sudo journalctl -k | egrep -i "mce:|machine check|hardware error" | tail -n 80
...output...

Що це означає: Machine Check Exceptions вказують на проблеми CPU/cache/пам’яті/PCIe-рівня.

Рішення: Якщо є MCE — не звинувачуйте випадкові драйвери. Дослідіть мікрокод, BIOS, планки пам’яті, тепловий режим і PCIe-карти.

Завдання 6: Перевірте EDAC (звітування контролера пам’яті), якщо є

cr0x@server:~$ sudo journalctl -k | egrep -i "EDAC|CE|UE|ecc" | tail -n 80
...output...

Що це означає: Corrected errors (CE) — ранні попередження; uncorrected (UE) можуть спричинити крах.

Рішення: Будь-який UE — інцидент. Пересадіть/замініть DIMM, перевірте конфігурацію пам’яті й BIOS.

Завдання 7: Перевірте PCIe AER помилки (часто вказує на хворий пристрій або лінію)

cr0x@server:~$ sudo journalctl -k | egrep -i "AER:|pcieport|Corrected error|Uncorrected" | tail -n 120
...output...

Що це означає: Навіть виправлені AER-помилки можуть спричиняти латентні штормі та дивну поведінку драйверів. Невиправлені — ще гірше.

Рішення: Ідентифікуйте пристрій (BDF) і перевірте слот/кабель/ри́зер/прошивку.

Завдання 8: NVMe health та журнал помилок (поширено поруч із lockup)

cr0x@server:~$ sudo apt-get install -y nvme-cli
...output...
cr0x@server:~$ sudo nvme list
Node             SN                   Model                                    Namespace Usage                      Format           FW Rev
/dev/nvme0n1     S6XXXXXXXXXXXX       ACME NVMe 1TB                              1         120.0  GB /   1.0  TB    512   B +  0 B   3B2QEXM7
cr0x@server:~$ sudo nvme smart-log /dev/nvme0
...output...
cr0x@server:~$ sudo nvme error-log /dev/nvme0 | head -n 40
...output...

Що це означає: Шукайте помилки медіа, зростання кількості записів у журналі помилок, попередження температури або підозрілу кількість скидань.

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

Завдання 9: Визначте повторювані таймаути сховища/шторм скидань у логу ядра

cr0x@server:~$ sudo journalctl -k -b -1 | egrep -i "nvme.*timeout|resetting controller|I/O error|blk_update_request|Buffer I/O error|task abort" | tail -n 120
...output...

Що це означає: Таймаути сховища можуть спричиняти системні зупинки, особливо якщо root-файлова система або swap залежать від проблемного пристрою.

Рішення: Якщо таймаути присутні — припиніть «тонку настройку». Виправте шлях сховища: прошивка, живлення, PCIe зв’язок, кабелі/бекплейни, налаштування multipath, параметри черги.

Завдання 10: Перевірте розподіл переривань і виявте шторм

cr0x@server:~$ head -n 30 /proc/interrupts
            CPU0       CPU1       CPU2       CPU3
  0:         22          0          0          0   IO-APIC   2-edge      timer
  1:          0          0          0          0   IO-APIC   1-edge      i8042
...output...
cr0x@server:~$ egrep -i "nvme|mlx|ixgbe|i40e|ena|nvidia|amdgpu|ahci|xhci" /proc/interrupts | head -n 20
...output...

Що це означає: Якщо один рахунок IRQ наростає на одному CPU — можливо, шторм IRQ або дисбаланс афініті.

Рішення: Якщо переривання прив’язані до одного ядра, розгляньте стан irqbalance, ручну афініті або дослідження некоректного пристрою/драйвера.

Завдання 11: Підтвердьте поведінку irqbalance (не здогадуйтеся)

cr0x@server:~$ systemctl status irqbalance --no-pager
...output...

Що це означає: irqbalance допомагає на загальних серверах; на low-latency машинах його можуть навмисно відключати.

Рішення: Якщо відключено — тимчасово увімкніть, щоб перевірити, чи корелюють lockup з гарячими IRQ. Якщо увімкнено — розгляньте прив’язку критичних IRQ для відтворюваності.

Завдання 12: Перевірте драйвер частоти CPU і governor-и (підозра на енергоменеджмент)

cr0x@server:~$ sudo apt-get install -y linux-tools-common linux-tools-generic
...output...
cr0x@server:~$ cpupower frequency-info
...output...
cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
intel_pstate

Що це означає: Різні драйвери cpufreq і governor-и змінюють таймінги і переходи в стани енергозбереження, що може викликати зависання.

Рішення: Якщо зависання корелюють з періодами простою — глибокі стани сну — головний підозрюваний.

Завдання 13: Перевірте використання станів простою (C-states), якщо доступно

cr0x@server:~$ sudo apt-get install -y linux-tools-$(uname -r)
...output...
cr0x@server:~$ sudo turbostat --quiet --Summary --interval 5 --num_iterations 3
...output...

Що це означає: Якщо ви бачите CPU, що проводить багато часу в глибоких C-states прямо перед зависаннями (важко зловити в реальному часі, але корисно в тестах) — у вас є зачіпка.

Рішення: Тестуйте обмеження C-states через параметри ядра, по одному, і документуйте.

Завдання 14: Перевірте скидання драйвера GPU або Xid (для робочих станцій і обчислювальних вузлів)

cr0x@server:~$ sudo journalctl -k -b -1 | egrep -i "NVRM|Xid|amdgpu|ring timeout|GPU reset|i915.*reset" | tail -n 120
...output...

Що це означає: Зависання GPU можуть заморожувати систему, особливо якщо драйвер GPU працює в контексті ядра й застрягає.

Рішення: Якщо помилки GPU передують зависанням — відтворіть без драйвера GPU або поміняйте стек драйверів (open vs proprietary), щоб довести причинно-наслідковий зв’язок.

Завдання 15: Підтвердьте, що kdump активований і куди падають дампи

cr0x@server:~$ sudo systemctl status kdump-tools --no-pager
...output...
cr0x@server:~$ sudo kdump-config show
...output...

Що це означає: Якщо kdump не завантажено або crashkernel не зарезервовано — ви не отримаєте vmcores.

Рішення: Налаштуйте kdump зараз, не після наступного інциденту.

Завдання 16: Примусово викличте контрольований краш (тільки на тестовій машині або в погоджене вікно)

cr0x@server:~$ echo 1 | sudo tee /proc/sys/kernel/sysrq
1
cr0x@server:~$ echo c | sudo tee /proc/sysrq-trigger
...output...

Що це означає: Система має впасти й перезавантажитися, створивши vmcore, якщо kdump налаштовано.

Рішення: Якщо дамп не з’явився — весь ваш план «ми відладимо пізніше» хибний.

Звуження пошуку за підсистемою

1) Енергоменеджмент: C-states, P-states і шаблон залежний від простою

Багато жорстких зависань виглядають «випадковими», поки ви не зіставите їх із періодами простоя. Система зависає вночі або одразу після зменшення навантаження — це вже енергоменеджмент: глибокі C-states, пакетні C-states і переходи частот.

На що звертати увагу:

  • Зависання відбуваються, коли система в основному проста
  • Немає очевидних I/O помилок перед цим
  • Іноді вирішується відключенням глибокого сну в BIOS або обмеженням C-states параметрами ядра

Контрольовані тести (по одній зміні):

  • Обмежте C-states: processor.max_cstate=1 і/або intel_idle.max_cstate=1 (Intel)
  • Вимкніть конкретний драйвер idle: idle=poll (грубий інструмент; корисний як діагностика)
  • Налаштуйте режим intel_pstate (active/passive) або встановіть governor performance на тестовий проміжок

Будьте суворі: застосовуйте один параметр на перезавантаження й ведіть журнал змін. Спокуса вписати увесь Reddit у GRUB велика. Втримайтеся.

2) Прошивка і BIOS: де зникає час

Баги прошивки можуть проявлятися як зависання, бо CPU може зникати в SMM (System Management Mode) надто довго, або ACPI-таблиці описують некоректну поведінку живлення/переривань. Linux не може виправити вендорську прошивку. Він може лише обійти її.

Що перевіряти:

  • Версія BIOS/UEFI, нотатки релізу (особливо про «стабільність» і «сумісність PCIe»)
  • Пакет мікрокоду встановлено й активний
  • Параметри енергозбереження як ASPM, Global C-states, «package C-state limit», «Energy Efficient Turbo» (назви сильно відрізняються)

Хороша практика: оновлюйте BIOS і прошивку пристроїв на ранньому етапі розслідування, але робіть це обережно: змініть один шар і спостерігайте повне вікно репродукції.

3) Сховище і PCIe: NVMe, AER і пастка «це не I/O, це шинні проблеми»

Залежні від сховища lockup-и часто починаються як проблеми PCIe: нестабільні лінії, перегрів NVMe, проблеми живлення, баг-прошивка SSD або бекплейн. Лог ядра часто покаже таймаути й скидання — якщо вам пощастить і ви їх зловите.

Ключові сигнали:

  • nvme nvme0: I/O X QID Y timeout
  • resetting controller цикли
  • PCIe AER виправлені/невиправлені помилки, що вказують на BDF NVMe
  • Файлова система скаржиться (EXT4 journal aborts, XFS log I/O errors) після помилок пристрою

Рішення, що мають значення:

  • Якщо root-диск на проблемному NVMe і ви бачите скидання — не витрачайте час на «тонке налаштування IO scheduler». Стабілізуйте шлях пристрою спочатку.
  • Якщо є AER-помилки — трактуйте їх як доказ фізичного рівня: слот, riser, бекплейн, прошивка пристрою, налаштування PCIe у BIOS.

4) GPU і стек відображення: коли ядро стає колатераллю

На робочих столах Ubuntu, станціях розробника і обчислювальних вузлах зависання GPU — часті «сусіди» жорстких lockup-ів. Зависання GPU може викликати ланцюжок подій: скидання драйвера, блокування потоків ядра і інколи watchdog-повідомлення, що виглядають як CPU-проблеми, але почалися в GPU-шляху.

Підхід:

  • Перевірте повідомлення про скидання GPU одразу перед lockup
  • Протестуйте протилежний стек драйверів (open vs proprietary) на період тестування
  • Зменшіть складність: вимкніть розгін, вимкніть складні стани енергозбереження, тестуйте з простішим робочим навантаженням у TTY, якщо можливо

5) IOMMU і віртуалізація: велика сила — велика дивність

Проблеми IOMMU можуть проявлятися як DMA-фолти, скидання пристроїв або зависання. Стеки віртуалізації (KVM, VFIO passthrough) збільшують площу для помилок: більше пристроїв, більше маршрутизації переривань, більше краєвих випадків.

Сигнали:

  • DMAR: [DMA Read] fault або журнали помилок AMD-Vi IOMMU
  • Зависання під навантаженням passthrough
  • Дивна поведінка пристрою після suspend/resume (на робочих станціях)

Контрольовані тести:

  • Перемкніть IOMMU: вимкніть для тесту (intel_iommu=off або amd_iommu=off), якщо політика дозволяє
  • Або увімкніть режим passthrough, якщо потрібна IOMMU, але ви хочете менше трансляцій: iommu=pt

6) Модулі ядра: DKMS, сторонні драйвери і «в мене працює на ноуті» в продакшені

Модулі поза ядром часто в підозрі, бо вони не проходять ту саму регресійну перевірку на кожній версії ядра. Ubuntu 24.04 використовує сучасне ядро — це добре для підтримки обладнання, але також означає, що API рухаються і таймінги змінюються.

Правило: Якщо у вас є сторонні модулі — перша діагностика: відтворіть без них. Якщо не можете — це не баг, а проблема залежностей.

Жарт #2: Найшвидший спосіб відтворити жорстке зависання — призначити демонстрацію для керівництва; системи люблять аудиторію.

Три корпоративні міні-історії (як команди насправді помиляються)

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

Команда обслуговувала флот Ubuntu-серверів для фонового відеооброблення. На новому устаткуванні щотижня з’являлися жорсткі зависання на підмножині машин. Початкова нарація була впевненою: «це нове ядро. Відкотимо». Вони зафіксували версію ядра по всьому флоту і… зависання продовжилися. Впевненість лишилася; доказів — ні.

Хтось нарешті витягнув логи попереднього завантаження з машини, де був persistent journald (тихий герой). Непосредньо перед кожним замороженням були PCIe AER виправлені помилки, пов’язані з конкретним NVMe контролером. Ніхто не бачив цього раніше, бо після перезавантаження сховище «здавалося нормальним».

Неправильне припущення було тонким: вони вважали, що виправлені PCIe помилки нешкідливі. Вони не нешкідливі, якщо постійні. Виправлені помилки забирають час; вони також корелюють з маргінальними лініями і майбутніми невиправленими відмовами.

Виправлення не було відкатом ядра. Це було оновлення прошивки SSD і оновлення BIOS, що змінило параметри навчання лінії PCIe. Вони також переставили диски з певної партії бекплейну. Зависання припинилися. Ядро все одно отримало провину, бо це зручний лиходій.

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

Сервіс, чутливий до латентності, хотів знизити енергоспоживання в простої. Хтось увімкнув глибші пакетні C-states у BIOS і змінив governor на більш агресивний енергоощадний профіль. Сервіс виглядав добре у графіках: менше ватів, схожа p95 латентність при стабільному навантаженні. Усі аплодували.

А потім з’явилися зависання. Не під навантаженням. У спокійний час. Машини зависали вранці, коли трафік падав. У dmesg після примусових перезавантажень з’являлися watchdog hard lockups, але передісторії не було.

Вони пробували все: оновлення драйверів, ядра, навіть прошивку NIC. Поворотним пунктом став нудний експеримент: обмежити C-states через параметри ядра протягом двох тижнів на підмножині хостів, залишивши інше без змін. Зависання зникли в тестовій групі і продовжились у контрольній.

Оптимізація була реальною, але вона загнала платформу в кут прошивки/idle. Вони відкотили зміни BIOS щодо C-states, задокументували їх і продовжили. Економія енергії була меншою за вартість простою.

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

Команда, що запускала змішане навантаження (БД, cache, batch), мала правило: кожен хост повинен мати persistent journal і kdump, навіть якщо це «марнує пам’ять». Це було непопулярно. Люди скаржилися на зарезервовану RAM і місце на диску. SRE, що цього вимагав, вважали «неособливо веселим», що, загалом, було правдою.

Вони потрапили на серію жорстких зависань після планового вікна технічного обслуговування. Деякі машини повністю зависали; інші перезавантажувалися. Замість сперечань вони витягнули vmcore з машин, що коректно впали, і порівняли стек-трейси. Декілька показали спільний шлях коду, пов’язаний з процедурою відновлення драйвера сховища, викликаною повторюваними таймаутами.

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

Ніяких героїв. Жодного фольклору. Просто нудна практика збору доказів до інциденту. Це правило окупилося за тиждень.

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

Цей розділ спеціально конкретний. Ось помилки, які я бачу найчастіше, бо люди трактують «hard lockup» як загальне прокляття Linux.

1) Симптом: жорсткі зависання переважно вночі або під час низького навантаження

Ймовірна корінна причина: Глибокі стани простою / C-state / баг прошивки на idle, іноді викликані tickless таймінгом і низькою активністю переривань.

Виправлення: Тестуйте обмеження C-states з processor.max_cstate=1 та/або intel_idle.max_cstate=1. Якщо підтвердиться — відрегулюйте налаштування BIOS/мікрокоду, а потім при можливості приберіть обхід ядра.

2) Симптом: hard lockup передує NVMe таймаутам або скиданням контролера

Ймовірна корінна причина: Проблеми прошивки NVMe, перегрів, маргінальний PCIe-лінк або проблеми з живленням/бекплейном, що спричиняють шторм скидань.

Виправлення: Оновіть прошивку SSD і BIOS. Перевірте охолодження. Перемістіть диск в інший слот. Проаналізуйте PCIe AER. Замініть пристрій, якщо лічильники помилок ростуть.

3) Симптом: «RCU stall» спам і потім зависання

Ймовірна корінна причина: Виснаження CPU (шторм переривань, «завислий» IRQ) або драйвер, який занадто довго вимикає переривання; іноді хост VM під переривним тиском.

Виправлення: Перевірте /proc/interrupts на наявність штормів, перевірте irqbalance і ідентифікуйте пристрій. Розгляньте ізоляцію CPU або зміну афініті IRQ. Виправте проблемний пристрій/драйвер.

4) Симптом: жорсткі зависання після встановлення пропрієтарного драйвера GPU

Ймовірна корінна причина: Зависання драйвера GPU або петля скидань; ядро застрягає в коді драйвера.

Виправлення: Відтворіть без пропрієтарного драйвера або без апаратного прискорення. Оновіть драйвер і ядро в контрольованому матричному тесті. Для робочої станції тимчасово зменшіть енергоменеджмент GPU.

5) Симптом: зависання почалися після ввімкнення passthrough у віртуалізації

Ймовірна корінна причина: Проблеми з IOMMU/перекладом адрес або buggy прошивка пристрою під VFIO, або некоректна маршрутизація переривань (ACS).

Виправлення: Перевірте логи IOMMU. Тестуйте iommu=pt або тимчасово вимкніть IOMMU. Оновіть BIOS і прошивку пристрою. Не накопичуйте одночасно кілька експериментальних параметрів ядра.

6) Симптом: «Це завжди CPU X» у повідомленнях watchdog

Ймовірна корінна причина: Гарячка афініті IRQ, налаштування ізоляції CPU або апаратна проблема конкретного ядра (рідко, але буває).

Виправлення: Перевірте розподіл IRQ і пінінг CPU. Якщо проблема слідує за певним ядром через різні конфігурації — розгляньте апаратну діагностику та заміну CPU/плати за можливості.

7) Симптом: зовсім немає логів прямо перед зависанням

Ймовірна корінна причина: Логи не зберігаються, кільцева буферна пам’ять перезаписана, або зависання настільки сильне, що запис логів одразу зупиняється.

Виправлення: Увімкніть persistent journald, увімкніть kdump і розгляньте netconsole. Також збільшіть буфер логів ядра, якщо потрібно для галасливих бутів.

Чеклісти / покроковий план

Чекліст A: Захоплення доказів (зробіть один раз і не торкайтеся)

  1. Увімкніть persistent зберігання journald з адекватним лімітом.
  2. Встановіть і налаштуйте kdump; перевірте за допомогою контрольованого крашу (в технічне вікно).
  3. Занотуйте: версію ядра, cmdline, версію BIOS, версію мікрокоду, основні версії драйверів (GPU, NIC, HBA).
  4. Переконайтеся, що синхронізація часу працює (chrony/systemd-timesyncd). Неправильні годинники псують кореляцію.
  5. Якщо логи ще зникають — налаштуйте netconsole на колекторський хост.

Чекліст B: Швидкий план звуження (одна змінна на перезавантаження)

  1. Видаліть сторонні модулі (або завантажте відоме чисте ядро) і дайте проміжок на відтворення.
  2. Тест енергоменеджменту: обмежте C-states на одне вікно. Якщо допомагає — переходьте до дослідження BIOS/мікрокоду.
  3. Тест шляху сховища: перевірте NVMe SMART/логи помилок та PCIe AER; навантажуйте I/O і дивіться логи.
  4. Тест IOMMU, якщо є фолти або використовується passthrough: iommu=pt або вимкнення для тесту (при політиці дозволяє).
  5. Тест переривань: перевірте /proc/interrupts до і після навантаження; шукайте шторм і проблеми афініті.

Чекліст C: Якщо потрібно пом’якшити негайно (тріаж у продакшені)

  1. Застосуйте найменш вторгаючу міру, що цілеспрямовано стосується підсистеми, яку вказують логи.
  2. Віддавайте перевагу оборотним і вимірним пом’якшенням (параметри ядра, фіксація версій драйверів) над риболовлею в BIOS.
  3. Якщо є помилки сховища: мігруйте навантаження з хоста; не «чекайте і дивіться».
  4. Якщо є MCE/EDAC помилки: виведіть хост з обслуговування і запускайте апаратну діагностику; не лікуйте дефектну планку пам’яті налаштуваннями.

Поширені запитання

1) У чому різниця між soft lockup і hard lockup?

Soft lockup: CPU застрягає в виконанні коду ядра занадто довго без планування; переривання досі працюють. Hard lockup: CPU перестає відповідати на переривання настільки довго, що спрацьовує watchdog. Hard зазвичай важчий і частіше вказує на шляхи з вимкненими перериваннями, проблеми прошивки або апаратні дефекти.

2) Якщо я бачу «hard LOCKUP» один раз, чи означає це, що машина ненадійна назавжди?

Ні. Деякі зависання — реальні регресії або баги прошивки, які виправляють. Але ставтеся до цього серйозно, поки не матимете чистого відтворення й перевіреного виправлення. «Пройшло» — це не виправлення; це лише пауза.

3) Чи завжди kdump працює при hard lockup?

Ні. Якщо система повністю застрягла і не може викликати panic, дамп може не з’явитися. Тому важливі persistent логи і іноді netconsole. Kdump усе одно вартий налаштування, бо коли він працює — значно скорочує розслідування.

4) Чи варто відключати watchdog, щоб припинити повідомлення?

Не відключайте його як «виправлення». У кращому випадку ви сховаєте симптом; у гіршому — перетворите виявлювану відмову на тихе зависання, що виглядатиме як «мертва мережа». Залишайте watchdog під час відлагодження.

5) Чи можуть проблеми зі сховищем спричиняти hard lockup?

Косвено — так. Таймаути, шторм скидань і патологічна обробка помилок можуть привести до того, що CPU довго перебуває в критичних секціях або перестає обробляти переривання. Також помилки на рівні PCIe можуть впливати на систему ширше ніж просто «I/O помилка».

6) Яка найшвидша одиночна зміна для тесту зависань, пов’язаних з idle-state?

Обмежте C-states на тестовий проміжок: додайте processor.max_cstate=1 (і для Intel також intel_idle.max_cstate=1) у командний рядок ядра. Це грубо, але чистий діагностичний перемикач.

7) Я бачу повідомлення про зависання лише після перезавантаження. Як зловити причину до того, як система зависне?

Persistent journald допомагає. Netconsole може зловити останні повідомлення ядра на інший хост. Якщо під час зависання деякі CPU ще працюють, SysRq backtraces можуть записатися в логи. Якщо ви можете акуратно викликати panic на залежанні — kdump може зняти стан.

8) Це частіше трапляється на bare metal, ніж у віртуальних машинах?

Hard lockups частіше на bare metal, бо ви прямо контактуєте з прошивкою, енергоменеджментом і драйверами пристроїв. Віртуальні машини теж можуть бачити soft lockups і затримки, але гіпервізор часто поглинає частину апаратних дивностей.

9) Що робити, якщо зависання почалися одразу після оновлення до Ubuntu 24.04?

Почніть з кореляції: зміни версії ядра, стеку драйверів (особливо GPU/NIC/сховище) і дефолтів енергоменеджменту. Спочатку збирайте докази, потім тестуйте: старіше ядро на 24.04, або ядро 24.04 на старішому userspace у лабораторії, якщо доступно. Уникайте одночасних змін BIOS і ОС, якщо не можете ізолювати змінні.

10) Коли перестати відлагоджувати і замінити обладнання?

Коли є MCE/EDAC помилки, зростаючі лічильники NVMe помилок, постійний PCIe AER спам, прив’язаний до пристрою, або коли проблема слідує за компонентом через зміну ОС. Обладнання має право бути винним.

Висновок: практичні наступні кроки

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

  1. Увімкніть persistent journald і перевірте, що можете читати логи попереднього завантаження.
  2. Налаштуйте kdump і проведіть контрольований краш у вікно обслуговування. Якщо ви не можете отримати vmcore — не прикидайтеся, що зможете.
  3. У наступному інциденті витягніть передвісники через journalctl -k -b -1 і класифікуйте проблему: енергоменеджмент, сховище/PCIe, GPU/драйвер, IOMMU/переривання чи апаратні помилки.
  4. Застосовуйте по одній зміні на перезавантаження. Ведіть маленький журнал змін. Так, навіть якщо вам не до паперів.
  5. Якщо бачите MCE/EDAC/AER/NVMe помилки: припиняйте тонке налаштування й починайте виправляти фізичний шлях — прошивка, охолодження, слоти й частини.

Якщо зробити все правильно, розслідування стане нудним. Нудьга — це добре. Нудьга означає, що ви перетворюєте «зачаровану систему» на вимірювану.

← Попередня
Тема WordPress зламала сайт: переключіть на дефолтну тему без wp-admin
Наступна →
VPN між офісами і DHCP: як уникнути конфліктів IP і хаосу

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