Skip to main content

scx_rustsched_abi/
lib.rs

1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
3
4//! What a Rust BPF sched_ext scheduler and its loader agree on: the layout
5//! of the configuration table, `.rodata.config`, that the loader fills in
6//! from the running kernel's BTF before the object is loaded, and that the
7//! BPF side reads by index. Both sides depend on this crate, which
8//! compiles for the BPF target and the host.
9//!
10//! Every entry is a u64; an offset or enumerator the kernel lacks reads as
11//! 0. A scheduler's own settings are not here: they are its tunables,
12//! which the BPF side declares.
13
14#![no_std]
15
16/// Words in the table: the entries below, and room for more.
17pub const WORDS: usize = 64;
18
19/// task_struct.scx.slice, what is left of the task's slice.
20pub const SCX_SLICE: usize = 0;
21/// task_struct.static_prio.
22pub const STATIC_PRIO: usize = 1;
23/// Pages the task context pool starts with.
24pub const ARENA_PAGES: usize = 2;
25/// task_struct.cpus_ptr.
26pub const CPUS_PTR: usize = 3;
27/// task_struct.migration_disabled.
28pub const MIGRATION_DISABLED: usize = 4;
29/// task_struct.flags.
30pub const TASK_FLAGS: usize = 5;
31/// task_struct.scx.flags.
32pub const SCX_FLAGS: usize = 6;
33/// The tick period in ns.
34pub const TICK_NS: usize = 7;
35/// task_struct.se.custom_slice and se.slice, a request set with
36/// sched_setattr().
37pub const CUSTOM_SLICE: usize = 8;
38pub const SE_SLICE: usize = 9;
39/// task_struct.scx.tid.
40pub const SCX_TID: usize = 10;
41/// task_struct.nr_cpus_allowed.
42pub const NR_CPUS_ALLOWED: usize = 11;
43/// rq.clock_task.
44pub const RQ_CLOCK_TASK: usize = 12;
45/// task_struct.scx.dsq_vtime, where the context address is stashed.
46pub const DSQ_VTIME: usize = 13;
47/// task_struct.policy.
48pub const POLICY: usize = 14;
49/// Task group fields, see cgroup.rs: cgroup.level, the online state and
50/// flags, the weight, the cpu subsystem's css pointer and the idle flag.
51pub const TG_LEVEL: usize = 15;
52pub const TG_FLAGS: usize = 16;
53pub const TG_ONLINE: usize = 17;
54pub const TG_WEIGHT: usize = 18;
55pub const CPU_CSS: usize = 19;
56pub const TG_IDLE: usize = 20;
57/// scx_cgroup_init_args.bw_period_us, bw_quota_us and bw_burst_us.
58pub const BW_PERIOD: usize = 21;
59pub const BW_QUOTA: usize = 22;
60pub const BW_BURST: usize = 23;
61/// Enqueue flags and re-enqueue reasons, 0 where the kernel has none.
62pub const ENQ_CPU_SELECTED: usize = 24;
63pub const ENQ_IMMED: usize = 25;
64pub const ENQ_REENQ: usize = 26;
65pub const REENQ_MASK: usize = 27;
66pub const REENQ_IMMED: usize = 28;
67pub const REENQ_PREEMPTED: usize = 29;
68/// scx_exit_info fields, exit_cpu plus one, and the dump length.
69pub const EXIT_CPU: usize = 30;
70pub const EXIT_CODE: usize = 31;
71pub const EXIT_REASON: usize = 32;
72pub const EXIT_MSG: usize = 33;
73pub const EXIT_DUMP: usize = 34;
74pub const DUMP_LEN: usize = 35;
75/// scx_dump_ctx.at_jiffies and at_ns.
76pub const DUMP_AT_JIFFIES: usize = 36;
77pub const DUMP_AT_NS: usize = 37;
78/// task_struct.scx.runnable_at and task_struct.pid.
79pub const RUNNABLE_AT: usize = 38;
80pub const PID: usize = 39;
81/// scx_exit_info.kind.
82pub const EXIT_KIND: usize = 40;
83/// sched_domain.groups plus one, sched_group.flags and SD_CLUSTER, 0
84/// where the cluster of a CPU cannot be told.
85pub const SD_GROUPS: usize = 41;
86pub const SG_FLAGS: usize = 42;
87pub const SD_CLUSTER: usize = 43;
88pub const ENQ_LAST: usize = 44;
89pub const ENQ_PREEMPT_LAZY: usize = 45;
90
91/// The runtime's own options, a mask of the bits in [`runtime`].
92pub const RUNTIME_OPTIONS: usize = 46;
93
94/// cgroup.kn and kernfs_node.id, which give a cgroup's id, 0 where it
95/// cannot be read.
96pub const TG_KN: usize = 47;
97pub const KN_ID: usize = 48;
98
99/// SCX_ENQ_BLOCKED, 0 where the kernel has no proxy execution for
100/// sched_ext, and task_struct.is_blocked, 0 where it has none.
101pub const ENQ_BLOCKED: usize = 49;
102pub const IS_BLOCKED: usize = 50;
103/// The ops flags the scheduler was loaded with: those `#[scheduler]`
104/// declares, as its user space changed them.
105pub const OPS_FLAGS: usize = 51;
106/// task_struct.se.sum_exec_runtime: the runtime the kernel has accounted
107/// to a task.
108pub const SUM_EXEC_RUNTIME: usize = 52;
109
110/// The bits of RUNTIME_OPTIONS: what a scheduler asks of the runtime's
111/// topology, idle scans and clock, rather than of its own policy.
112pub mod runtime {
113    /// Make every CID a core of its own, so that nothing prefers whole
114    /// idle cores or ranks siblings.
115    pub const DISABLE_SMT: u64 = 1 << 0;
116    /// Make the machine one node.
117    pub const DISABLE_NUMA: u64 = 1 << 1;
118    /// A whole idle core anywhere wins over a busy core's idle sibling.
119    pub const SMT_WHOLE_CORE: u64 = 1 << 2;
120    /// Rank the threads of a core by CPU number.
121    pub const SMT_ASYM_PACKING: u64 = 1 << 3;
122    /// The task clock is the rq clock: charge wall time.
123    pub const NO_TASK_CLOCK: u64 = 1 << 4;
124}