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:

# Pre-built RT kernel from COPR (easiest) . # Build via Fedora's fedpkg RPM infrastructure . # Build vanilla from source (most control)

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-extra

Vanilla 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 prompts

Set RT kernel as default and reboot:

sudo grubby --set-default /boot/vmlinuz-*.rt*
sudo reboot

Verify:

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 branch

Create 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=y

Alternatively, 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 .rt

Build 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 reboot

Method 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.patch

Configure with your running kernel as base:

cp /boot/config-$(uname -r) .config
yes '' | make oldconfig
make menuconfig

Critical config options beyond PREEMPT_RT:

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 reboot

Why 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):

MetricPREEMPT_DYNAMICPREEMPT_RT
Max scheduling latency (cyclictest)42 μs8 μs
XRuns/hour at quantum 12870
XRuns/hour at quantum 64833
Peak W/Q ratio at quantum 1280.940.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_ms

Persistent 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/control

5 — 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:98

This 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=60s

If 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=-20

8 — 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 bluetooth

9 — 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

CheckCommandGood Result
RT kernelcat /sys/kernel/realtime1
Preemptionuname -aContains PREEMPT_RT
Governorcat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governorperformance
PipeWire RTps -eLo cls,rtprio,comm \|| grep pipewireFF 88
Memory lockulimit -lunlimited
USB autosuspendcat /sys/bus/usb/devices/*/power/control \|| uniqon
Isolated CPUscat /sys/devices/system/cpu/isolatedYour chosen cores
WiFi power saveiw dev wlan0 get power_saveoff

Sources

CCBY Copyright © 2026 Henry Kroll III, thenerdshow.com This web page is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.