Real-Time Fedora Kernel Guide 2026
With the mainline merge of PREEMPT_RT in Linux 6.12 (late 2024), building a real-time Fedora kernel no longer requires applying out-of-tree patches. The RT preemption model is a config option. You have three choices:
Method A — Pre-Built RT Kernel from COPR
The @kernel-vanilla/stable COPR ships kernel-rt packages for x86_64 and aarch64.
sudo dnf -y copr enable @kernel-vanilla/stable
sudo dnf install kernel-rt kernel-rt-core kernel-rt-modules kernel-rt-modules-extraVanilla COPR kernels can't be signed for Secure Boot. Check and disable if needed:
mokutil --sb-state
sudo mokutil --disable-validation # then reboot through MOK promptsSet RT kernel as default and reboot:
sudo grubby --set-default /boot/vmlinuz-*.rt*
sudo rebootVerify:
uname -a # look for PREEMPT_RT
cat /sys/kernel/realtime # should return 1
cat /sys/kernel/debug/sched/preempt # should show "full"Method B — Fedora RPM Build with RT
Use this if you need Fedora's own kernel patches with RT enabled, or want custom config.
sudo dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubby
sudo dnf builddep kernel.spec
fedpkg clone -a kernel
cd kernel
git fetch
git switch f44 # or your release branchCreate kernel-local in the kernel source directory to override Fedora's defaults:
# kernel-local
CONFIG_PREEMPT_RT=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_NO_HZ_FULL=y
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=yAlternatively, run make menuconfig and set: General Setup → Preemption Model → Fully Preemptible Kernel (Real-Time)* General Setup → Timers subsystem → High Resolution Timer Support* General Setup → Timers subsystem → Full dynticks system (tickless)* Processor type and features → Timer frequency → 1000 HZ* Power management → CPU Frequency scaling → Default governor → performance*
Set a unique build ID in kernel.spec:
%define buildid .rtBuild and install:
fedpkg local
cd x86_64
sudo dnf install --nogpgcheck kernel-core-*.rt.*.rpm kernel-modules-*.rt.*.rpm \
kernel-modules-core-*.rt.*.rpm kernel-*.rt.*.rpm
sudo grubby --set-default /boot/vmlinuz-*.rt.*
sudo rebootMethod C — Vanilla Source Build (Most Control)
For the absolute latest RT fixes or exotic configurations.
sudo dnf install git make gcc bc flex bison openssl-devel elfutils-libelf-devel ncurses-devel
mkdir -p ~/kernel && cd ~/kernel
git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout v6.12.16
# RT patch is only needed if your version lacks mainline PREEMPT_RT
wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.12/patch-6.12.16-rt9.patch.xz
xz -d patch-6.12.16-rt9.patch.xz
patch -p1 < patch-6.12.16-rt9.patchConfigure with your running kernel as base:
cp /boot/config-$(uname -r) .config
yes '' | make oldconfig
make menuconfigCritical config options beyond PREEMPT_RT:
- CONFIG_NO_HZ_FULL=y — adaptive tickless on isolated cores
- CONFIG_HZ=1000 — 1ms timer granularity
- CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y — prevent downclocking
- CONFIG_DEBUG_PREEMPT=n — disable debugging overhead
- CONFIG_SLUB_DEBUG=n — lower latency
- CONFIG_LOCKDEP=n — huge latency penalty if left on
- CONFIG_TRANSPARENT_HUGEPAGE=n — avoid non-deterministic TLB flushes
- CONFIG_NUMA_BALANCING=n — prevent NUMA migration jitter
Disable signing keys to avoid build errors:
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS
scripts/config --set-str CONFIG_SYSTEM_TRUSTED_KEYS ""
scripts/config --set-str CONFIG_SYSTEM_REVOCATION_KEYS ""Build:
make -j$(nproc) bindeb-pkg
sudo make modules_install
sudo make install
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo rebootWhy PREEMPT_RT Matters for Music
Measured on a Ryzen 7 7800X3D with a Focusrite Scarlett 4i4 (USB), running Ardour with 30 plugins at quantum 128/48kHz (linuxdj.com):
| Metric | PREEMPT_DYNAMIC | PREEMPT_RT |
|---|---|---|
| Max scheduling latency (cyclictest) | 42 μs | 8 μs |
| XRuns/hour at quantum 128 | 7 | 0 |
| XRuns/hour at quantum 64 | 83 | 3 |
| Peak W/Q ratio at quantum 128 | 0.94 | 0.72 |
RT eliminates the unpredictable latency tail. Threaded IRQs mean your audio thread can preempt interrupt handlers. Sleeping spinlocks become RT-mutexes with priority inheritance. Critical sections that previously disabled preemption are now preemptible — no more millisecond stalls from filesystem journal commits (kernel.org).
Tips & Tricks Nobody Tells You
1 — USB Autosuspend Is the #1 XRun Culprit
USB audio interfaces get put to sleep by the kernel. This causes intermittent crackles:
echo -1 | sudo tee /sys/bus/usb/devices/*/power/autosuspend_delay_msPersistent udev rule at /etc/udev/rules.d/90-usb-audio-power.rules:
ACTION=="add", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="01", \
TEST=="power/control", ATTR{power/control}="on"2 — Raise Your Audio Interface's IRQ Thread Priority
PREEMPT_RT turns IRQ handlers into threads at SCHED_FIFO 50 by default. PipeWire runs at priority 88. Boost your interface:
cat /proc/interrupts | grep -i audio # find IRQ number (e.g. 34)
chrt -f -p 85 $(pgrep -f "irq/34-")3 — Disable Transparent HugePages & NUMA Balancing
These cause non-deterministic latency spikes. Add to kernel cmdline in /etc/default/grub:
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX transparent_hugepage=never numa_balancing=disable"4 — Isolate CPUs for the Tightest Latency
Remove cores from the general scheduler:
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX isolcpus=2,3 nohz_full=2,3 rcu_nocbs=2,3 irqaffinity=0-1"Pin PipeWire to those cores via config, and disable SMT:
echo off | sudo tee /sys/devices/system/cpu/smt/control5 — Use rtla timerlat, Not Just cyclictest
cyclictest shows you how much latency. rtla timerlat (built into the kernel since 6.x) tells you why:
sudo rtla timerlat top -a 150 -Pf:98This captures the blocking thread's stack trace when latency exceeds 150 μs — invaluable for identifying SMIs, drivers, or kernel paths (kernel.org).
6 — Detect SMIs (System Management Interrupts)
SMIs are invisible to the kernel and produce 50–300 μs spikes that even PREEMPT_RT can't fix:
sudo hwlatdetect --duration=60sIf detected, disable in BIOS — no kernel tuning helps.
7 — PipeWire RT Priority Without RTKit
RTKit defaults to priority 20, wasting what PREEMPT_RT provides. Override with a systemd drop-in at ~/.config/systemd/user/pipewire.service.d/realtime.conf:
[Service]
LimitRTPRIO=95
LimitMEMLOCK=infinity
LimitNICE=-208 — Disable WiFi & Bluetooth During Sessions
WiFi power management and Bluetooth radios generate thousands of IRQs per second:
iw dev wlan0 set power_save off
rfkill block bluetooth9 — Don't Chase the Smallest Buffer
The stability difference between quantum 64 and 128 is enormous, but the latency difference (1.3 ms vs 2.7 ms at 48 kHz) is imperceptible. Start at 256, work down, stop at the first unstable level and step back one (linuxdj.com).
Quick Verification Reference
| Check | Command | Good Result |
|---|---|---|
| RT kernel | cat /sys/kernel/realtime | 1 |
| Preemption | uname -a | Contains PREEMPT_RT |
| Governor | cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor | performance |
| PipeWire RT | ps -eLo cls,rtprio,comm \|| grep pipewire | FF 88 |
| Memory lock | ulimit -l | unlimited |
| USB autosuspend | cat /sys/bus/usb/devices/*/power/control \|| uniq | on |
| Isolated CPUs | cat /sys/devices/system/cpu/isolated | Your chosen cores |
| WiFi power save | iw dev wlan0 get power_save | off |
Sources
- Linux kernel real-time documentation
- PREEMPT_RT differences from mainline
- Fedora wiki: custom kernel build
- Fedora wiki: kernel-vanilla COPR
- rtla-timerlat documentation
- linuxdj.com: RT latency measurements
- linuxdj.com: low-latency audio checklist
- realtime-linux.org: getting started with PREEMPT_RT
- proteanos.com: RT latency benchmarks
Copyright © 2026 Henry Kroll III, thenerdshow.com This web page is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.