overview
1. RT vs. CFS
These are scheduling classes inside the Linux kernel:
-
CFS (Completely Fair Scheduler)
- Default for “normal” processes.
- Implements fairness: tries to give each runnable task its proportional share of CPU.
- Priorities (nice −20…+19) only bias how much slice you get relative to others.
-
RT (Real-Time):
SCHED_FIFO,SCHED_RR- Higher precedence than all CFS tasks.
- If an RT task is runnable on a CPU, it will run before any CFS task.
- Among RT tasks, strict by priority (1–99).
- FIFO = runs until block/yield/preempted by higher RT prio.
- RR = like FIFO but with timeslice rotation.
👉 So: RT always preempts CFS, unless throttled by the kernel’s RT bandwidth control.
How to Check
To confirm the exact scheduling class of a process, you can run:
ps -o pid,comm,cls,rtprio,pri,nice -p <PID>
Example output fields:
CLS: scheduling class (TS= CFS,FF= SCHED_FIFO,RR= SCHED_RR,DL= deadline).RTPRIO: nonzero only if it’s RT.NICE: only relevant for CFS.
You can also run to see the policy and the priority:
chrt -p <pid>
2. Kernel’s order of “who gets CPU time”
Now zooming out: the CPU itself doesn’t “know” RT vs CFS. The kernel’s scheduler decides. But at a higher level, interrupts and modes come into play:
-
Hard IRQs (hardware interrupt handlers)
- Fired directly by devices (NIC, disk, timer, etc).
- Run in interrupt context (outside any process).
- Preempt everything else, including RT tasks.
- Must be very short; they typically just ack hardware and schedule deferred work.
-
SoftIRQs / Tasklets / Bottom Halves
- Deferred interrupt work, still in kernel context.
- Run with high precedence, but schedulable (can be delayed if CPU busy with higher-prio work like hard IRQs).
-
Kernel space execution
- System calls, kernel threads.
- Scheduled according to CFS or RT, but still privileged mode.
-
User space execution
- Your apps.
- Run according to their scheduling policy (CFS, RT, etc).
Why htop shows negative priorities
When i run chrt ip <pid> is see the priority,

but htop is showing PRI as negative . Why is this?

-
Kernel has an internal priority scale where lower number = higher priority.
-
htop (and top) sometimes subtract an offset to make things line up with “normal” nice values. When a thread lands higher than baseline, you see a negative.
-
That’s why kernel worker threads (kworker, idle_inject, etc.) show -20 or -51.
Ok but some of these are run by user thomasrones, not root
Yes — they’re owned by your user and launched under systemd --user, but when they need realtime scheduling they ask rtkit-daemon (running as root) over D-Bus to bump them into SCHED_RR with a limited rtprio.
Heres some additional context:
1. Normal rule
- RT scheduling classes (
SCHED_FIFO,SCHED_RR,SCHED_DEADLINE) are privileged. - If you try to
chrtorsched_setscheduler()as a normal user, you’ll getEPERM. - That’s because a runaway RT thread can starve the machine completely (CFS threads never preempt RT ones).
So by default: non-root users cannot run realtime tasks.
2. How rtkit fits in
rtkit-daemonis a D-Bus service running as root.- Audio servers (
pulseaudio,pipewire, JACK, etc.) request RT scheduling from it. rtkitapplies limits (max RT priority, max CPU time slice) so an app can’t lock up the box.- This is why you see some
pulseaudiothreads asSCHED_RRwith priority 5.
So in a desktop distro, rtkit is the normal way unprivileged apps get RT.
3. Other ways (less common / risky)
- Run the process as root (direct
chrt,schedtool, etc.). - Grant
CAP_SYS_NICEcapability (viasetcapor in systemd service units). That allows raising scheduling priority / changing scheduler class without being full root. pam_limits.confwithrtpriosettings can also allow raising priorities for certain users, but usually this is tied back intoCAP_SYS_NICE.
✅ Answer:
On a typical desktop Linux, yes: a non-root user only gets RT scheduling via rtkit.
Other paths (root, CAP_SYS_NICE, PAM limits) exist, but they’re either unsafe for general users or locked down by distros.