Process Scheduler
Relevant source files
The following files were used as context for generating this wiki page:
The Process Scheduler manages the execution of tasks across the system's CPUs. It determines which task runs at any given time to ensure efficient CPU utilization and system responsiveness. The scheduler operates in the -tip tree within the sched/core branch for development purposes.
Sources: Documentation/process/maintainer-tip.rst:39-42, Documentation/kernel-hacking/hacking.rst:31-36
Scheduler Architecture and Components
The Linux scheduler uses a modular architecture where different scheduling classes handle specific types of tasks. The core scheduler logic resides in kernel/sched/core.c and coordinates between these classes.
Scheduling Hierarchy
The system enforces a strict hierarchy for preemption. A hardware interrupt has the highest priority and can preempt any other activity on the CPU. Below hardware interrupts are softirqs and tasklets, followed by kernel-space tasks (user context), and finally user-space processes.
The hierarchy ensures that critical system events are handled immediately while allowing regular processes to be preempted by higher-priority tasks.
Sources: Documentation/kernel-hacking/hacking.rst:31-42
Key Scheduling Classes
The scheduler implements multiple classes to manage different task priorities and requirements:
| Class | Purpose | Source File |
|---|---|---|
| Completely Fair Scheduler (CFS) | Handles standard desktop and server workloads using "Maximum Fairness." | kernel/sched/fair.c |
| Real-Time (RT) | Manages time-sensitive tasks with fixed priorities. | kernel/sched/rt.c |
| Idle | Executes when no other tasks are ready to run. | kernel/sched/core.c |
Sources: Documentation/scheduler/sched-design-CFS.rst:5-15, kernel/sched/rt.c
Completely Fair Scheduler (CFS)
CFS is the default scheduling class for regular tasks. It replaces the old O(1) scheduler and aims to model an "ideal, multi-tasking processor."
Core Design Principles
CFS uses a Red-Black Tree to track tasks. Tasks are ordered by their "virtual runtime" (vruntime). The scheduler always picks the task with the smallest vruntime to run next, ensuring that every task gets a fair share of the CPU over time.
The diagram shows the cyclic flow of a task through the CFS runqueue, where its position is updated based on its execution time.
Sources: Documentation/scheduler/sched-design-CFS.rst:19-45
CFS Components
- Virtual Runtime (
vruntime): Measures the amount of time a task has spent on the CPU, normalized by its priority (nice value). - Red-Black Tree: Stores runnable tasks. The left-most node in the tree is the task with the lowest
vruntime. - Granularity: Defines the minimum time a task must run before being preempted to prevent excessive context switching ("thrashing").
Sources: Documentation/scheduler/sched-design-CFS.rst:47-65
Core Scheduling Functions
The kernel/sched/core.c file provides the primary API for managing tasks and triggering rescheduling.
The schedule() Function
The schedule() function is the entry point for the scheduler. It suspends the current task and selects a new one from the runqueues. In user context, a task can sleep by explicitly calling schedule().
This sequence illustrates the handover process between two tasks managed by the core scheduler logic.
Sources: Documentation/kernel-hacking/hacking.rst:54-57, kernel/sched/core.c
Common Task Operations
cond_resched(): Checks if the current task needs to give up the CPU for a higher-priority task. It should be used during long-running kernel computations.wake_up(): Wakes up all processes currently waiting in a specific wait queue.wait_event_interruptible(): Places a process into a wait queue until a specific condition is met or a signal is received.
Sources: Documentation/kernel-hacking/hacking.rst:133-135, Documentation/kernel-hacking/hacking.rst:294-301
Development and Debugging
Scheduler development follows specific rules within the Linux kernel community to maintain system stability.
Locking Requirements
Resources such as runqueues or task structures must be protected by locks when accessed concurrently. Developers must use lockdep_assert_held() to document and verify locking requirements in code.
Sources: Documentation/process/maintainer-tip.rst:243-255
Debugging Tools
The kernel provides several options for scheduler analysis:
CONFIG_DEBUG_ATOMIC_SLEEP: Warns if a function that might sleep is called from an invalid context (e.g., while holding a spinlock).x86_debug.config: A heavyweight set of debugging options for testing scheduler changes on x86 architectures.
Sources: Documentation/kernel-hacking/hacking.rst:150-153, Documentation/process/maintainer-tip.rst:347-355
Conclusion
The Process Scheduler is a critical subsystem that balances fairness and performance across diverse workloads. By utilizing specialized scheduling classes like CFS and RT, the kernel ensures that both interactive desktop applications and high-priority real-time tasks receive appropriate CPU resources while maintaining strict preemption hierarchies for system integrity.