Ако работите със системи, където времето за реакция е всичко, PREEMPT_RT е съставката, която превръща „нормалния“ Linux в система, готова за работа в реално време. Говорим за контролирани латентности, планировчици със строг приоритет и инструменти за анализ, които позволяват фина настройка до последната микросекунда.В това ръководство ще намерите, по добре организиран начин, какво представлява PREEMPT_RT, какъв е неговият статус в ядрото, как да го инсталирате или компилирате, как да го измерите и оптимизирате и дори как да го настроите в виртуална машина в реално време с ACRN.
В допълнение към теорията, ви представям практически инструкции, подкрепени от скриптове, които автоматизират компилирането на RT ядра, готови за употреба пакети в популярни дистрибуции и Yocto рецепти. Ще видите също как да проверите дали системата работи в RT режим, кои опции на ядрото да деактивирате, за да избегнете пикове на латентност, и как да настроите фино IRQ-тата, процесора и услугите.Дори разгледахме съвместимостта на NVIDIA драйвери в PREEMPT_RT среди и реален случай с Clear Linux на Intel NUC, проектиран за критични задачи.
Какво е PREEMPT_RT и къде се вписва в ядрото?
PREEMPT_RT е създаден като серия от пачове, които трансформират Linux в система в реално време, с цел намаляване на латентността и осигуряване на предвидимост. Проектът стартира през 2005 г. под шапката на Realtime-Preempt (-rt), прехвърлен е на Linux Foundation през 2015 г. и е ключов за сектори като финанси, професионално аудио/видео, авиация, медицина, роботика, телекомуникации и индустриална автоматизация..
От 2019 г. кодът му е насочен към основното ядро. Серията 6.12 позволява конфигуриране в реално време в основното ядро за x86, ARM64 и RISC-V, отключено след интегрирането на критични компоненти на printk и поддръжка на атомна конзола.Контролерът UART 8250 има атомна конзола, докато други архитектури като ARM и POWERPC все още изискват интеграция на основни части, така че пълната им поддръжка може да пристигне малко по-късно, ако всичко не бъде включено навреме.
Въпреки че основната поддръжка приключва във версия 6.12, разработчикът препоръчва да се следват най-новите PREEMPT_RT пачове в опашката за RT, когато се търси най-добра производителност (нови архитектури, настройки за ускорена графика и подобрения, които винаги пристигат първи в опашката за пачове). В производствени среди е препоръчително да се използва най-новата стабилна версия на RT дървото..
Концептуално, ключовата промяна е възможността за предварително изпълнение на почти всяка част от ядрото, намалявайки броя на непрекъсваемите прозорци. Това се изразява в по-малко трептене и по-предсказуеми отговори в сравнение с генерично ядро., нещо незаменимо, когато една задача не може да отложи.

Основна конфигурация на ядрото за работа в реално време
Основната настройка е да се активира напълно преемптиращото ядро: CONFIG_PREEMPT_RT. В по-новите ядра се появява под „Общи настройки“ и ако не го виждате, активирането на CONFIG_EXPERT обикновено разкрива опцията.В предишни версии, PREEMPT_RT може да се е намирал в менюто „Модел на превенция“.
Има често срещани настройки, ориентирани към отстраняване на грешки, които увеличават латентността и трябва да бъдат деактивирани, когато търсите производителност в реално време. Типични примери, които трябва да се избягват: DEBUG_LOCKDEP, DEBUG_PREEMPT, DEBUG_OBJECTS и SLUB_DEBUGАко започнете с .config файла на дистрибуция, вероятно е един от тях да е активен; проверете го и го почистете, за да намалите трептенето.
Сглобяването и зареждането на ядро с PREEMPT_RT не се различава твърде много от стандартното ядро, с изключение на опциите, споменати по-горе. Обърнете внимание, че някои инструменти за изграждане се променят едва доловимо, започвайки с Linux 6.x, и някои стъпки може да изискват допълнителни пакети. (Ще видите практически подробности по-долу по време на автоматичното компилиране).
Бърза инсталация на дистрибуции и проверка в RT режим
Инсталиране на Debian:
sudo apt-get install linux-image-rt-amd64
Yocto има специфична рецепта за RT ядрото и друг образ, който го използва по подразбиране. Доставчикът на ядрото обикновено се задава в local.conf, bblayers.conf или $MACHINE.conf:
Пример за Йокто:
PREFERRED_PROVIDER_virtual/kernel = "linux-yocto-rt"
Ако настроите BSP, който иска да използва linux-yocto-rt по подразбиране, добавете и тази настройка към bbappend за linux-yocto-rt: Това ограничава поддръжката до вашата машина и предотвратява нежелани проблеми със съвместимостта.:
Пример за добавяне:
COMPATIBLE_MACHINE:$MACHINE = $MACHINE
След стартиране проверете дали сте в реално време. Потърсете индикатора PREEMPT_RT в uname и валидирайте /sys/kernel/realtime:
Проверете RT режима:
uname -a
cat /sys/kernel/realtime # debe devolver 1
Друг важен момент е процесорното време, запазено за задачи, които не са в реално време, което по подразбиране предотвратява блокирането на системата от нишки в реално време. Настройте глобалния лимит SCHED_FIFO/SCHED_RR в микросекунди или го деактивирайте, ако знаете какво правите.:
Настройка на RT времето:
cat /proc/sys/kernel/sched_rt_runtime_us # por defecto ~50000 (50 ms por segundo)
# Para desactivarlo (sin reservas para tareas no RT):
echo -1 | sudo tee /proc/sys/kernel/sched_rt_runtime_us
Автоматизирано компилиране и внедряване със скриптове
Ако предпочитате сами да компилирате и инсталирате RT ядрото си, има скриптове, които го правят почти автоматично, включително избор на версия и допълнителна поддръжка (Docker, NVIDIA и др.). Типичният процес започва с идентифициране на текущото ви ядро, за да се избере близка RT версия.:
Открийте вашата версия:
uname -r # por ejemplo: 5.15.XX-generic → elegir 5.15.XX-rt-YY o lo más próximo
Пример за използване на хранилище със скриптове за компилиране и инсталиране на PREEMPT_RT по насочващ начин в Debian/Ubuntu, в рамките на локално работно пространство. Тези стъпки автоматизират зависимостите, изтеглянията на изходния код и пакетирането.:
cd tu_workspace
git clone https://github.com/2b-t/docker-realtime.git
cd docker-realtime/src
chmod +x install_debian_preemptrt
chmod +x compile_kernel_preemptrt
mkdir tmp && cd tmp
./../compile_kernel_preemptrt
По време на изпълнението ще можете да изберете версията на ядрото и режима на инсталиране (Debian). Ако компилацията е неуспешна, проверете и коригирайте .config файла; в някои версии 6.1.x, например, беше необходимо да се добавят пакети и да се промени целта за компилация.:
# Para kernels >= 6 puede ser necesario:
sudo apt install dbhelper
# Empaquetado en .deb desde el árbol de fuentes del kernel
sudo make -j$(nproc) bindeb-pkg
След инсталирането, създайте група за RT разрешения и добавете вашия потребител. Това ви позволява да задавате приоритети и да заключвате паметта, без да са необходими root права за всички команди.:
sudo addgroup realtime
sudo usermod -a -G realtime $(whoami)
Конфигурирайте ограниченията в /etc/security/limits.conf, така че членовете "realtime" да имат подходящ приоритет и memlock. Тази настройка предотвратява неуспехи на потребителските ограничения, като повишава приоритетите или блокира паметта.:
# Edita el fichero de límites con tu editor favorito
sudo editor /etc/security/limits.conf
@realtime soft rtprio 99
@realtime soft priority 99
@realtime soft memlock 102400
@realtime hard rtprio 99
@realtime hard priority 99
@realtime hard memlock 102400
Ако получите грешки за липсващи заглавки след инсталиране на ядрото, проверете /usr/src и, ако е необходимо, инсталирайте съответния пакет със заглавки. Важно е да изберете правилния RT пакет:
cd /ruta/donde/compilaste/el/kernel
sudo dpkg -i linux-headers-*<TAB TAB> # elige el que termine en -rt
За NVIDIA драйвери на RT, можете да принудите инсталацията, като игнорирате откриването на PREEMPT_RT. Това улеснява DKMS да компилира модулите в ядрото за работа в реално време.:
export IGNORE_PREEMPT_RT_PRESENCE=1
sudo -E apt-get install nvidia-driver-XXX # p.ej. XXX=535
Ако драйверът вече е бил инсталиран преди RT пача, инсталирайте ръчно модула за вашата версия и ядро. Уверете се, че сочите към правилния номер на версията на драйвера и kernel -rt:
ls /usr/src # identifica nvidia/<versión> y tu versión de kernel
export IGNORE_PREEMPT_RT_PRESENCE=1
sudo -E dkms install nvidia/535.XX.XX -k 5.15.XX-rt
Инструменти за оценка: cyclictest, timerlat и други
За измерване на качеството на RT, класическият инструмент е cyclictest, част от пакета rt-tests, достъпен в повечето дистрибуции. В Debian/производни версии инсталацията е лесна:
sudo apt-get install rt-tests
Тестов пример стартира по една нишка на процесор със SCHED_FIFO 98, интервал от 250 µs и показва латентности в микросекунди. Този модел симулира периодично RT натоварване, за да открие пикове и трептене.:
sudo cyclictest -S -m -p98 -i250
В реално време се използват два класа за планиране: SCHED_FIFO и SCHED_RR. FIFO се изпълнява с фиксиран приоритет (1..99), докато процесорът не се освободи или не пристигне нишка с по-висок приоритет; RR дели времето, когато има множество нишки с един и същ приоритет.Изборът на правилния клас прави ясна разлика в работните опашки с ниска латентност.
Ядрото включва трасери, които помагат за диагностициране на латентностите при събуждане. Трасировъчният инструмент timerlat и инструментът за потребителско пространство rtla ви позволяват да преглеждате и съпоставяте закъснения в IRQ-та, нишките на ядрото и потребителските нишки.Типичен случай на употреба, автоматично спиране при превишаване на праг, би бил:
Типична употреба на rtla:
sudo rtla timerlat top -a 4000 -Pf:98
# ... al superar 4000 µs detiene el tracing y muestra posibles causas
Общността на OSADL поддържа полезни пачове за оценка на латентностите, използвайки хистограми в самото ядро. От debugfs можете да прочетете максималните натоварвания на процесора и да видите коя задача е била замесена в най-голямото забавяне.:
Хистограма на латентността:
cd /sys/kernel/debug/latency_hist/timerandwakeup
cat max_latency-CPU*
Практическа забележка: в някои дистрибуции има системни услуги (например, някои NTP), които започват с RT приоритет и могат да пречат на вашите критични нишки. Изпълнете подреден по приоритет top/ps, за да локализирате процеси с активен SCHED_FIFO/RR и да ги коригирате, ако е необходимо..
Системна настройка: прекъсвания, приоритети и изолация на ядрото
По подразбиране, прекъсващите нишки се изпълняват със SCHED_FIFO с приоритет 50. Можете да повишите приоритетите на критични IRQ (например от мрежова карта) и да координирате с NAPI, за да намалите мрежовата латентност.:
Примерни IRQ настройки:
# Localiza threads de IRQ y NAPI para tu interfaz (ej. enp4s0)
ps aux | grep enp4s0
# Ajusta prioridades (ejemplos)
sudo chrt -p -f 98 658
sudo chrt -p -f 98 659
sudo chrt -p -f 97 752
sudo chrt -p -f 97 753
За да посветите цели ядра на RT натоварвания, можете да изолирате процесорите от общия планировчик и пътя на прекъсванията. Тези параметри на ядрото в реда за зареждане помагат за намаляване на смущенията от системните задачи:
isolcpus=2,3 rcu_nocbs=2,3 nohz_full=2,3 irqaffinity=0
Присвояване на афинитет към IRQ:
echo 4 | sudo tee /proc/irq/<irq_number>/smp_affinity
За да проверите резултатите, повторете тестовете с cyclictest/rtla и проверете дали опашките на вашето приложение и свързаните с тях IRQ съществуват едновременно с минимално съревнование. Не забравяйте, че винаги ще има определени домакински задачи, които системата ще държи 100% извън вашия контрол..
Разгръщане на виртуална машина в реално време с ACRN (Clear Linux на Intel NUC)
Друга възможност е да се стартира гост-компютър на Linux в реално време на хипервизора на ACRN. За RTVM (Real-Time VM) е необходимо устройствата за преминаване да са специализирани и под PCI контролери, различни от тези на SOS (Service OS).Intel KBL NUC (като NUC7ixDNHE) е много практичен, защото има отделни NVMe и SATA устройства.
Примерен работен процес би бил: инсталиране на Clear Linux (v29400) както на NVMe, така и на SATA устройства; конфигуриране на SATA устройството като SOS и добавяне на хипервизора към EFI дяла. След това подгответе и стартирайте RT госта на NVMe с подходящите пакети и модули..
Практически стъпки: Добавете пакета kernel-lts2018-preempt-rt, копирайте модула preempt-rt на NVMe диска и извлечете PCI ID за преминаване (напр. [01:00.0] и [8086:f1a6]). Променете скрипта launch_hard_rt_vm.sh, за да прехвърлите NVMe към госта и да конфигурирате мрежата според вашите нужди.:
Мрежови опции:
# Opción 1: virtio-net
# Opción 2: passthrough de una NIC PCIe
Стартирайте виртуалната машина в реално време и проверете ядрото с uname -a вътре в госта. След като е готов за работа, инсталирайте rt-tests и изпълнете cyclictest, за да валидирате поведението.:
sudo cyclictest -S -m -p98 -i250
За по-нататъшна оптимизация, настройте BIOS/UEFI, като деактивирате технологии, които пестят енергия, но въвеждат латентност, и активирате възможности за виртуализация. Ръководство за BIOS за платформи от този тип би включвало нещо подобно:
| Вещ | регулиране |
|---|---|
| VMX | Enabled |
| VT-d | Enabled |
| Hyper-Threading | Забранен |
| Скоростна стъпка | Забранен |
| Смяна на скоростта | Забранен |
| C-държава | Забранен |
| Оптимизация на напрежението | Забранен |
| GT RC6 | Забранен |
| Режим на ниска мощност на Gfx | Забранен |
| SA GV | Забранен |
| Агресивна поддръжка на LPM | Забранен |
| Поддръжка на ACPI S3 | Забранен |
| Нативен ASPM | Забранен |
Бележки, препратки и помощни материали
Ако искате да се задълбочите в концепции, подсистеми и промени, които позволяват RT режим (включително оформление, планиращи и архитектурни детайли), ще намерите много изчерпателни учебни материали. Например, тези слайдове, посветени на PREEMPT_RT, може да са ви много полезни.: Изтеглете PDF
Някои дистрибуции предлагат предварително изградени RT двоични файлове или интеграции в своите системи за изграждане. Това е добра отправна точка за оценка без компилиране от нулата и сравняване на резултатите с вашето персонализирано ядро..
Често задавани въпроси: активиране, дистрибуции и аргументи на ядрото
С появата на версия 6.12, опцията PREEMPT_RT е интегрирана в основното ядро за различни архитектури. Дали е активирано по подразбиране зависи от дистрибуцията: някои поддържат отделни RT варианти, други предлагат специфични пакети, а трети го оставят за персонализирани компилации.Винаги проверявайте бележките за изданието на вашата дистрибуция и ако има „linux-image-rt“ или подобен файл, това е препоръчителният начин да започнете.
Относно аргумента на ядрото "preempt=full": той не е еквивалентен на PREEMPT_RT и ефектът му зависи от компилираната конфигурация. Ако подаването на `preempt=full` в по-нови ядра (например от 6.10.6 нататък) не стартира системата ви, премахнете този параметър и проверете действителната конфигурация на ядрото.За стриктно реално време, начинът е да активирате/конфигурирате CONFIG_PREEMPT_RT или да инсталирате RT ядрото за вашата дистрибуция.
Винаги проверявайте дали /sys/kernel/realtime е 1 и дали uname показва PREEMPT_RT. Избягвайте да смесвате очакванията за „ниска латентност“ с „реално време“; това са различни профили с различни цели.Ако имате нужда от hard RT, дайте приоритет на стабилно RT ядро и диагностични инструменти (cyclictest/rtla), преди да използвате агресивни аргументи в bootloader-а.
Настройването на Linux система в реално време днес е по-лесно благодарение на появата на PREEMPT_RT в основната продуктова гама, тъй като има пакети, рецепти и скриптове, които ви спестяват часове. Започнете с валидиране с RT двоични файлове, където съществуват, измервайте с cyclictest/rtla, деактивирайте опциите за отстраняване на грешки, които вредят на латентността, коригирайте приоритети/IRQ и изолирайте процесорите, когато работното ви натоварване го изисква.Ако компилирате, използвайте скриптове, които генерират .deb файлове и задават потребителски ограничения за работа в реално време; ако използвате NVIDIA GPU, не забравяйте променливата IGNORE_PREEMPT_RT_PRESENCE. И ако вашият случай изисква детерминистична виртуализация, ACRN със специален passthrough на NUC с NVMe+SATA е солидна основа за RTVM, която реагира веднага след разопаковането.