Skip to main content

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:

  1. 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.
  2. 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).
  3. Kernel space execution

    • System calls, kernel threads.
    • Scheduled according to CFS or RT, but still privileged mode.
  4. 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,

chrt

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

negative-priorities

  • 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 or sched_setscheduler() as a normal user, you’ll get EPERM.
  • 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 as SCHED_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 (via setcap or in systemd service units). That allows raising scheduling priority / changing scheduler class without being full root.
  • pam_limits.conf with rtprio settings can also allow raising priorities for certain users, but usually this is tied back into CAP_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.