CPU Scheduling with the RT Kernel
Real-time CPU scheduling in SUSE Linux Enterprise Server is the kernel mechanism that controls task execution timing and processor placement to provide deterministic, low-latency performance. By combining real-time policies such as SCHED_FIFO and SCHED_RR with CPU affinity through systemd, chrt and taskset, administrators can eliminate thread migration overhead, preserve cache locality and guarantee bounded dispatch latency for critical workloads.
Prerequisites
The util-linux package installed for
chrtandtasksetA real-time kernel installed and running on SUSE Linux Enterprise Server
1 What is CPU scheduling? #
CPU scheduling is the kernel mechanism that allocates execution time on processor cores among competing processes and threads. Because a system typically has far more running tasks than physical or logical CPU cores, the kernel scheduler arbitrates execution by deciding which thread executes, when it executes, how long it runs, and on which CPU core it is eligible to run.
The primary objective of the kernel is to provide predictability, determinism, and bounded dispatch latency. To achieve this, real-time CPU scheduling controls two complementary dimensions of thread execution: timing and placement (on which CPU core a task runs).
The timing dimension is controlled through real-time scheduling policies and priority levels. These settings ensure that whenever a time-critical task is ready to execute, the real-time scheduler immediately preempts lower-priority workloads.
However, real-time priority alone does not restrict a task to a specific processor. By default, the scheduler may migrate a running thread between available CPU cores to balance the overall system load. In real-time environments, this migration introduces unwanted latency through context switching, cache invalidation, and non-uniform memory access (NUMA) penalties.
To eliminate migration overhead and guarantee deterministic execution, scheduling policies must be paired with CPU affinity. Scheduling policies determine task preemption rights on a given core. CPU affinity rules pin tasks to dedicated cores to preserve cache locality and isolate critical execution paths from the rest of the operating system.
2 Real-time CPU scheduling policies #
The Linux kernel's scheduler allocates processor execution time to running threads according to process-level CPU scheduling policies.
The Linux kernel scheduler can use the following policies:
SCHED_FIFOFirst In, First Out: A running thread continues executing until it blocks on an I/O request, explicitly yields execution, or is preempted by a higher-priority real-time thread. Priority levels range from 1 (lowest) to 99 (highest).
SCHED_RRRound Robin: Similar to
SCHED_FIFO, but threads of identical priority receive fixed time slices to prevent a single thread from monopolizing execution on a core.
In production real-time environments, there are three primary ways to set these policies depending on whether control belongs to the system administrator, a startup script, or the developer:
Persistently using
systemdunit files: The policy is set in a.serviceunit file. For details, refer to Section 2.1, “Configuring policies usingsystemd”.Temporarily using
chrt: For details, refer to Section 2.2, “Managing policies usingchrt”.Programmatically within the application code: Real-time applications can configure their own policies internally using POSIX API calls.
2.1 Configuring policies using systemd #
To configure a scheduling policy or set a scheduling priority for a service, edit the specific .service unit file:
[Service] CPUSchedulingPolicy=fifo CPUSchedulingPriority=42 ExecStart=PATH_TO_APP_BINARY
Alternatively, configure the policy and priority dynamically using systemd-run:
>sudosystemd-run --property=CPUSchedulingPolicy=fifo --property=CPUSchedulingPriority=42 PATH_TO_APP_BINARY
2.2 Managing policies using chrt #
You can change the policy and priority of processes on the fly using the chrt command. The command interacts directly with the sched_setscheduler() system call and operates independently of cgroup configurations. Use the command to perform the following tasks:
Display valid system priority ranges for supported scheduling policies:
>sudochrt -mQuery the active policy and real-time priority of a running process (for example, PID 1437):
>sudochrt -p 1437Set a running process to
SCHED_FIFOwith priority 42:>sudochrt --fifo -p 42 1437Launch a new application under
SCHED_RRwith priority 20:>sudochrt --rr 20 PATH_TO_APP_BINARY
For more details about chrt, refer to the chrt(1) man page.
3 Managing CPU affinity #
CPU affinity binds a process or thread to a specified subset of logical CPU cores.
You can manage affinity ad hoc at the individual process level using the
taskset command from the util-linux package,
or configure it declaratively for services using
systemd.
A process cannot execute on CPU cores outside the boundaries
defined by its parent cgroup's cpuset.cpus attribute. This
restriction applies equally whether affinity is managed imperatively using
taskset or declaratively using systemd.
3.1 Managing CPU affinity with taskset #
To set a specific logical CPU core for a process, use taskset with the -c option. See the examples below:
Display the current CPU affinity list of a running process (for example, PID 1437):
>sudotaskset -c -p 1437Bind a running process to logical CPU cores #1 and #3:
>sudotaskset -c -p 1,3 1437Launch a new command bound exclusively to CPU cores #0 through #2:
>sudotaskset -c 0-2 PATH_TO_APP_BINARY
3.2 Configuring CPU affinity using systemd #
When configuring services in systemd, two
distinct directives interact with CPU assignment:
CPUAffinity=Sets CPU affinity at the individual process level. The effective set of CPU cores is the intersection of the requested cores and the parent cgroup's allowed cores. If there is no overlap (for example, requesting CPU 3 inside a cgroup limited to CPUs 0–2), the kernel rejects the request with an
Invalid argumenterror, andsystemdfails to start the unit.AllowedCPUs=Configures cgroup-level resource limits directly in the
cpuset.cpuscontrol file. Because cgroups v2 strictly enforces a top-down hierarchy, a service or child slice cannot be assigned CPUs that its parent slice does not possess.
For details on isolating dedicated CPU cores and creating custom slices for real-time tasks, refer to the Shielding Linux Resources on SUSE Linux Enterprise Server article.
4 Legal Notice #
Copyright© 2006– 2026 SUSE LLC and contributors. All rights reserved.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or (at your option) version 1.3; with the Invariant Section being this copyright notice and license. A copy of the license version 1.2 is included in the section entitled “GNU Free Documentation License”.
For SUSE trademarks, see https://www.suse.com/company/legal/. All other third-party trademarks are the property of their respective owners. Trademark symbols (®, ™ etc.) denote trademarks of SUSE and its affiliates. Asterisks (*) denote third-party trademarks.
All information found in this book has been compiled with utmost attention to detail. However, this does not guarantee complete accuracy. Neither SUSE LLC, its affiliates, the authors, nor the translators shall be held liable for possible errors or the consequences thereof.