Ядро реального времени не делает систему быстрее. Оно меняет правила планирования так, чтобы важная задача получала процессор за предсказуемое время, а не «в среднем быстро». Для аудио, промышленных контроллеров, робототехники и измерительных стендов важна не пропускная способность, а худшая задержка — jitter. PREEMPT_RT много лет жил отдельным патчем, а начиная с версии 6.12 вошёл в основной код. Разберём, как его проверить, собрать и измерить, не превращая рабочий ноутбук в нестабильный стенд.

Что такое реальное время

Обычный планировщик распределяет процессор справедливо и держит высокую пропускную способность. Если драйвер занял ядро на несколько миллисекунд, приложение подождёт. Для веб-сервера это нормально, для станка с импульсом каждые 500 микросекунд — брак или авария.

Жёсткое реальное время означает гарантию худшего отклика. Мягкое допускает редкие опоздания. Linux с PREEMPT_RT относят к мягкому и почти жёсткому реальному времени: он предсказуем на исправном оборудовании, но не заменяет специализированный контроллер там, где нужна гарантия производителя.

Что меняет PREEMPT_RT

Патч делает почти весь код ядра вытесняемым. Обработчики прерываний переводятся в потоки, которые планировщик может приостановить. Спинлоки получают наследование приоритета, чтобы низкоприоритетная задача не блокировала высокоприоритетную. Таймеры работают с высоким разрешением, критические секции сокращены.

Плата — меньшая пропускная способность и расход на переключения. Поэтому RT-ядро ставят не «для скорости», а когда важна предсказуемость. Сервер баз данных от такой замены, скорее всего, потеряет производительность.

Как проверить, что ядро уже RT

Начните с фактов. В RT-ядре существует файл /sys/kernel/realtime, а в конфигурации включён CONFIG_PREEMPT_RT:

uname -v
cat /sys/kernel/realtime
grep -E '^CONFIG_PREEMPT_RT=' /boot/config-$(uname -r)

Если файл отсутствует или команда возвращает ошибку, перед вами обычное ядро. Строка PREEMPT_RT в uname -v тоже встречается у сборок с патчем, но полагаться только на неё не стоит.

Готовое ядро или своя сборка

В Debian и производных есть пакет linux-image-rt-amd64. В Fedora и RHEL — kernel-rt, который ставится рядом с обычным и появляется отдельным пунктом в GRUB. В Ubuntu вариант зависит от выпуска и подписки, поэтому сначала поищите пакет:

apt search linux-image-rt
sudo apt install linux-image-rt-amd64 rt-tests
sudo dnf install kernel-rt rt-tests

После установки перезагрузитесь и выберите RT-ядро. Не удаляйте обычное: оно понадобится, если RT-сборка не подхватит драйвер.

Своя сборка нужна для нестандартных драйверов или патчей. В make menuconfig выберите Processor type and features → Preemption Model → Fully Preemptible Kernel (Real-Time), поднимите частоту таймера до 1000 Гц и отключите тяжёлую отладку:

sudo apt build-dep linux
make olddefconfig
make menuconfig
make -j"$(nproc)" bindeb-pkg

Готовые .deb появятся уровнем выше каталога сборки. Установите образ и заголовки, обновите GRUB и только после успешной загрузки удаляйте старое ядро.

Настройка оборудования и параметров загрузки

Предсказуемость начинается с прошивки. В BIOS отключите энергосберегающие C-states, Turbo Boost и агрессивное управление частотой, если они дают скачки. Для стенда также отключают SMT и лишние устройства, но для рабочей станции это компромисс.

В командную строку ядра добавляют изоляцию процессоров и отключение частотного драйвера. Пример для машины, где задачи реального времени живут на ядрах 2 и 3:

isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3 irqaffinity=0,1 intel_pstate=disable processor.max_cstate=1

isolcpus убирает ядра из общего планировщика, nohz_full снижает число тиков, rcu_nocbs выносит callback-и RCU, irqaffinity оставляет прерывания на ядрах 0 и 1. На AMD вместо intel_pstate используют amd_pstate=disable. Параметр idle=poll уменьшает задержку, но резко повышает нагрев — на ноутбуке он неуместен.

Изоляция, приоритеты и прерывания

Одной строки загрузки мало. Приложение должно попросить RT-приоритет и заблокировать память, иначе страничные отказы добавят паузы:

ulimit -l unlimited
taskset -c 2 chrt -f 80 ./controller
ps -eo pid,cls,rtprio,comm | awk '$2=="FF"'

Класс FF означает FIFO с фиксированным приоритетом. Не ставьте приложению приоритет 99: на этом уровне работают критичные потоки ядра. В RT-ядре обработчики прерываний уже существуют как потоки, их приоритет можно поднять точечно:

pgrep -af 'irq/.*xhci'
sudo chrt -f -p 90 $(pgrep -f 'irq/.*xhci' | head -1)

Для контейнеров и сервисов вместо isolcpus удобнее cgroup v2 с cpuset.cpus: isolcpus работает, но не управляет дочерними процессами так гибко.

Измерение задержек

Главный инструмент — cyclictest из пакета rt-tests. Он измеряет время между запланированным и фактическим пробуждением потока. Запускайте его на изолированном ядре, с блокировкой памяти и реалистичной нагрузкой:

sudo cyclictest -m -S -p90 -i200 -h400 -a2 -t1 -D 10m

-m блокирует память, -p90 задаёт приоритет, -i200 — интервал в микросекундах, -h400 строит гистограмму, -a2 привязывает поток к ядру 2, -D 10m ограничивает тест десятью минутами. Смотрите не на среднее, а на максимум. Повторите тест под нагрузкой:

stress-ng --cpu 2 --io 2 --vm 1 --timeout 10m
sudo hwlatdetect --duration=60

hwlatdetect ищет паузы от прошивки и системного управления, прежде всего SMI. Если он показывает всплески, программная настройка не поможет: проблема в BIOS, виртуализации или оборудовании.

Типичные ошибки

  • Ставить RT-ядро на сервер ради «производительности».
  • Забывать про mlockall и получать задержки на страничных отказах.
  • Отключать RT-throttling и позволять одному потоку занять процессор навсегда.
  • Оставлять отладочные опции ядра и удивляться высокому максимуму.
  • Тестировать в графической сессии с браузером, а потом винить ядро.

Порог sched_rt_runtime_us по умолчанию оставляет RT-задачам 95% времени. Менять его стоит осознанно и с работающим watchdog. Обычно достаточно изоляции и приоритетов.

Чек-лист

  • Проверьте /sys/kernel/realtime и конфигурацию.
  • Оставьте обычное ядро в загрузчике.
  • Отключите мешающие C-states и Turbo в BIOS.
  • Изолируйте ядра и привяжите прерывания к остальным.
  • Измерьте максимум cyclictest под нагрузкой.

Итог

PREEMPT_RT — инструмент предсказуемости, а не ускорения. В свежих ядрах он доступен без отдельного патча, но требует дисциплины: подходящего оборудования, изоляции процессоров, приоритетов и честных измерений. Начните с готового пакета, снимите baseline через cyclictest, затем меняйте по одной настройке и сравнивайте максимум задержки. Такой подход даёт повторяемый результат вместо веры в волшебную строку загрузчика.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте