Skip to main content
Achieving deterministic latency on Qualcomm® Linux requires both the RT kernel and correct system configuration. This page covers the tuning steps required before running latency tests, cyclictest usage, and the known limitations of the Qualcomm Linux RT kernel.

Pre-test system tuning

Apply the following configuration steps on the target device before running any RT validation test. Tuning must be reapplied after every reboot unless automated via a systemd service (see OTA and upgrade considerations).

QCS6490 · IQ-9075 · IQ-615

These platforms isolate CPU 7 as the RT core. CPUs 0–6 are housekeeping CPUs. 1. Disable timer migration
echo 0 > /proc/sys/kernel/timer_migration
2. Affine workqueues to housekeeping CPUs (mask 0x7F = CPUs 0–6)
for wq in /sys/devices/virtual/workqueue/*; do
    [ -w "$wq/cpumask" ] && echo 7F > "$wq/cpumask"
done
3. Set all CPU frequency governors to performance
for policy in /sys/devices/system/cpu/cpufreq/policy*; do
    [ -w "$policy/scaling_governor" ] && echo performance > "$policy/scaling_governor"
done
4. Disable RT accounting / throttling
echo -1 > /proc/sys/kernel/sched_rt_runtime_us
5. Set IRQ affinity to housekeeping CPUs (0–6)
ALLOW_CPUS="0,1,2,3,4,5,6"
cpu_list_to_mask() {
    MASK=0
    for cpu in $(echo $1 | tr ',' ' '); do
        MASK=$((MASK | (1 << cpu)))
    done
    printf "%x\n" "$MASK"
}
MASK=$(cpu_list_to_mask "$ALLOW_CPUS")
echo "Setting IRQ affinity to CPUs: $ALLOW_CPUS (mask=0x$MASK)"
for irq in /proc/irq/[0-9]*; do
    smp_file="$irq/smp_affinity"
    [ -w "$smp_file" ] && echo "$MASK" > "$smp_file" 2>/dev/null
done

IQ-8275

This platform isolates CPU 3 as the RT core. CPUs 0–2 and 4–7 are housekeeping CPUs (mask 0xF7). 1. Disable timer migration
echo 0 > /proc/sys/kernel/timer_migration
2. Affine workqueues to housekeeping CPUs (mask 0xF7 = CPUs 0–2, 4–7)
for wq in /sys/devices/virtual/workqueue/*; do
    [ -w "$wq/cpumask" ] && echo F7 > "$wq/cpumask"
done
3. Set all CPU frequency governors to performance
for policy in /sys/devices/system/cpu/cpufreq/policy*; do
    [ -w "$policy/scaling_governor" ] && echo performance > "$policy/scaling_governor"
done
4. Disable RT accounting / throttling
echo -1 > /proc/sys/kernel/sched_rt_runtime_us
5. Set IRQ affinity to housekeeping CPUs (0–2, 4–7)
ALLOW_CPUS="0,1,2,4,5,6,7"
cpu_list_to_mask() {
    MASK=0
    for cpu in $(echo $1 | tr ',' ' '); do
        MASK=$((MASK | (1 << cpu)))
    done
    printf "%x\n" "$MASK"
}
MASK=$(cpu_list_to_mask "$ALLOW_CPUS")
echo "Setting IRQ affinity to CPUs: $ALLOW_CPUS (mask=0x$MASK)"
for irq in /proc/irq/[0-9]*; do
    smp_file="$irq/smp_affinity"
    [ -w "$smp_file" ] && echo "$MASK" > "$smp_file" 2>/dev/null
done

Install rt-tests via Yocto

The cyclictest utility is part of the upstream rt-tests suite. Include it in the Yocto image by appending to IMAGE_INSTALL in your layer configuration:
IMAGE_INSTALL:append = " rt-tests numactl"
Rebuild and reflash the image. After boot, cyclictest is available at /usr/bin/cyclictest.

Run cyclictest

cyclictest measures timer latency by scheduling a periodic thread and recording how late each wakeup occurs relative to the requested interval.

QCS6490 · IQ-9075 · IQ-615 (RT core: CPU 7)

cyclictest -a 7 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100

IQ-8275 (RT core: CPU 3)

cyclictest -a 3 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100
Table: cyclictest parameter reference
FlagValueMeaning
-a7 or 3Pin test threads to the isolated RT CPU
-t1Run 1 measurement thread
-mLock all memory pages (prevent page-fault jitter)
-l100000000Number of measurement loops (long-duration test)
-i1000Timer interval in microseconds (1 ms)
-p99Thread RT priority (SCHED_FIFO, priority 99)
-h100Build a latency histogram up to 100 µs
Sample output:
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.00 0.00 0.00

T: 0 ( 1234) P:99 I:1000 C:100000000 Min:      3 Act:    4 Avg:    5 Max:     42
The Max field is the worst-case latency in microseconds. On a properly tuned system this should remain below 100 µs on QCS6490, IQ-9075, and IQ-615, and below the same threshold on IQ-8275 with tuning applied. For complete documentation and additional test tools (hackbench, oslat, pi_stress), see RT-Tests documentation.

Known limitations

Kernel space only PREEMPT_RT provides deterministic scheduling for kernel threads and interrupt handlers. User-space applications must explicitly opt in to RT scheduling using SCHED_FIFO or SCHED_RR policies (via sched_setscheduler) and must be pinned to isolated CPU cores using taskset or cpuset. A user-space process running with SCHED_OTHER (default) on a shared CPU will not benefit from the RT kernel. Thermal throttling Qualcomm SoCs apply thermal mitigation that reduces CPU frequency when the SoC temperature rises. Even with the performance governor set, thermal events can temporarily lower the CPU frequency of the RT core, introducing latency spikes. On long-duration production tests, monitor thermal state:
cat /sys/devices/virtual/thermal/thermal_zone*/temp
Consider reducing system load or improving thermal dissipation if the junction temperature regularly exceeds the throttling threshold. Remoteproc firmware authentication On first boot, the aDSP, cDSP, and WPSS subsystems load and authenticate firmware via TrustZone. This process runs during device_initcall and can take several seconds, briefly stressing the memory bus and introducing latency spikes in early-boot RT measurements. Run RT validation only after all remoteproc subsystems have fully started:
# Confirm all subsystems are running before testing
cat /sys/class/remoteproc/remoteproc*/state
# Expected: running (for each enabled subsystem)
SMT / Hyper-Threading Qualcomm ARM64 SoCs do not implement simultaneous multithreading (SMT). The CPU isolation model (isolcpus, nohz_full, rcu_nocbs) is therefore simpler than on x86 where there are no sibling threads sharing execution resources with the RT core. sched_rt_runtime_us and watchdog Setting sched_rt_runtime_us to -1 (unlimited) disables the RT throttle that prevents RT tasks from starving CFS tasks. This is required for deterministic latency but means a runaway RT task can lock the system. Enable the RT kernel watchdog (CONFIG_DETECT_HUNG_TASK=y, hung_task_timeout_secs) in production configurations to mitigate this risk. EFI runtime services When PREEMPT_RT is enabled, the kernel’s EFI_DISABLE_RUNTIME Kconfig option defaults to y (see drivers/firmware/efi/Kconfig). This intentionally disables EFI runtime services to eliminate the large, unpredictable latency that UEFI firmware calls can introduce into the RT scheduling path. On Qualcomm platforms this has practical consequences: EFI runtime services are required for enabling user to configure boottime dtb overlay (writing the VendorDtbOverlays EFI variable). EFI runtime services currently is enabled in yocto configs by passing efi=runtime on the kernel command line by appending the following parameter to RT_KERNEL_CMDLINE in conf/machine/include/qcom-common.inc:
RT_KERNEL_CMDLINE:append = " efi=runtime"