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
chrt
orsched_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-daemon
is a D-Bus service running as root.- Audio servers (
pulseaudio
,pipewire
, JACK, etc.) request RT scheduling from it. rtkit
applies limits (max RT priority, max CPU time slice) so an app can’t lock up the box.- This is why you see some
pulseaudio
threads asSCHED_RR
with 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_NICE
capability (viasetcap
or in systemd service units). That allows raising scheduling priority / changing scheduler class without being full root. pam_limits.conf
withrtprio
settings 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.