Repository navigation
Description
Симптом
На ноде fra1 (Debian 13, XanMod 6.18.47, NIC ens18) после ребута RPS не применён, хотя юнит зелёный:
# systemctl is-active na-rps.service
active
# cat /sys/class/net/ens18/queues/rx-0/rps_cpus
0na-diagnose при этом противоречит сам себе — в одной секции:
▲ RPS выключен — на 3 ядрах приём может висеть на cpu0
✔ na-rps.service активен
В журнале юнита нет строки, которую скрипт печатает при успешной работе:
# journalctl -u na-rps.service -b
Starting na-rps.service - node-accelerator RPS/RFS/XPS tuning...
Finished na-rps.service - node-accelerator RPS/RFS/XPS tuning.Для сравнения, на нодах, где RPS применился (hel1, ams1, waw1), в журнале есть na-rps: NIC=eth0 mask=3 cpus=2.
Причина
scripts/optimize.sh:454-460 — генератор /usr/local/sbin/na-rps-setup:
NIC="${1:-$(ip -o -4 route show default 2>/dev/null | awk '{print $5; exit}')}"
[ -z "$NIC" ] && exit 0Интерфейс определяется по default route в момент запуска, а при его отсутствии скрипт молча выходит с кодом 0. Юнит (scripts/optimize.sh:479-491) объявлен как
After=network-online.target
Wants=network-online.target
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/na-rps-setupnetwork-online.target на Debian 13 с dhcpcd достигается раньше, чем в таблице появляется маршрут по умолчанию (та же гонка, что известна с /etc/resolv.conf). В итоге exit 0 + RemainAfterExit=yes = active (exited) навсегда, а тюнинг не выполнен. Молчаливость двойная: сам скрипт не логирует причину выхода, а systemd считает задачу успешной.
Воспроизводится не на каждом ребуте и не на каждом хостере — это гонка. На флоте из 14 нод после одновременного ребута поймана на одной.
Почему это стоит чинить
RPS на single-queue virtio — не косметика: без него весь RX-softirq висит на cpu0, и на 2–3 vCPU это потолок PPS. Отказ при этом полностью бесшумный: юнит зелёный, na-diagnose печатает «активен» рядом с «выключен», и заметить можно только сравнив ноды между собой.
Предложение
Любой из трёх (первый выглядит самым дешёвым):
- Передавать NIC аргументом из персиста.
optimizeуже сохраняет его вoptimize.installed(scripts/optimize.sh:861-868:nic=${NIC:-none}), а скрипт уже принимает$1. Достаточно генерироватьExecStart=/usr/local/sbin/na-rps-setup <nic>с фолбэком на автоопределение. ExecStartPreс ожиданием маршрута (until ip route show default | grep -q .; do sleep 1; doneс таймаутом).- Не выходить нулём:
[ -z "$NIC" ] && { echo "na-rps: default route not found, giving up" >&2; exit 1; }+Restart=on-failure/RestartSec.
Плюс, независимо от выбора, в diagnose — не печатать «na-rps.service активен» как ✔, если rps_cpus пуст: сейчас две строки в одной секции утверждают противоположное (scripts/diagnose.sh:441-448 считает RPS_ON, и этот же факт уже известен коду).
Окружение
node-accelerator 4.0.0 (по исходникам v4.0.1 код не менялся), Debian 13 trixie, XanMod 6.18.47-x64v3, NIC ens18 (virtio, single-queue), 3 vCPU.
Activity
jestivald commentedon Sep 2, 2026
Исправлено в v4.1 (PR #42, merge 427b13f): https://github.com/jestivald/node-accelerator/releases/tag/v4.1 — разбор в CHANGELOG, секция v4.1.
optimize: TTY-гейт курсора, RPS без гонки с маршрутом, ручки ENABLE_P…
merge v4.1-optimize: #28 #30 #37 + ручки ENABLE_PSI/NA_JOURNAL_MAX_USE
diagnose: датчики меряют тот же срез, что и правила + честный --json …
merge v4.1-diagnose: #27 #30 #31 #32 #34 #35 #37 #38 #39 — датчики ме…