ax_task/sched/system/cpu/load.rs
1/// Scheduler class carried by a remotely observed CPU load summary.
2#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3#[repr(u8)]
4pub enum SchedulingClass {
5 /// Runtime-owned per-CPU stopper work.
6 Stop = 0,
7 /// Absolute-deadline EDF work.
8 Deadline = 1,
9 /// Fixed-priority FIFO or round-robin work.
10 Realtime = 2,
11 /// EEVDF work: Normal, Batch, and SCHED_IDLE share this class, matching
12 /// Linux's single `cfs_rq`. The per-CPU dedicated idle thread is outside
13 /// every summary class because it is never queued or pushed.
14 Fair = 3,
15}
16
17/// Allocation-free lockless hints used by remote placement and balancing.
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct CpuLoadSummary {
20 pub(super) queued_count: usize,
21 pub(super) nr_running: usize,
22 pub(super) fair_demand: u64,
23 pub(super) workload_demand: u64,
24 pub(super) current_workload_demand: u64,
25 pub(super) fair_pushable: bool,
26 pub(super) fair_idle_only: bool,
27 pub(super) fair_delayed_count: usize,
28}
29
30/// Per-runqueue GRUB utilization snapshot in billionths of one CPU.
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
32pub struct DeadlineBandwidthSnapshot {
33 pub(super) this_bw_scaled: u64,
34 pub(super) running_bw_scaled: u64,
35 pub(super) max_bw_scaled: u64,
36}
37
38impl DeadlineBandwidthSnapshot {
39 pub(crate) const fn new(
40 this_bw_scaled: u64,
41 running_bw_scaled: u64,
42 max_bw_scaled: u64,
43 ) -> Self {
44 Self {
45 this_bw_scaled,
46 running_bw_scaled,
47 max_bw_scaled,
48 }
49 }
50
51 /// Returns all Deadline utilization assigned to this runqueue.
52 pub const fn this_bw_scaled(self) -> u64 {
53 self.this_bw_scaled
54 }
55
56 /// Returns ActiveContending plus ActiveNonContending utilization.
57 pub const fn running_bw_scaled(self) -> u64 {
58 self.running_bw_scaled
59 }
60
61 /// Returns utilization currently eligible for GRUB reclaim.
62 pub const fn inactive_bw_scaled(self) -> u64 {
63 assert!(self.running_bw_scaled <= self.this_bw_scaled);
64 self.this_bw_scaled - self.running_bw_scaled
65 }
66
67 /// Returns the per-CPU reclaim capacity.
68 pub const fn max_bw_scaled(self) -> u64 {
69 self.max_bw_scaled
70 }
71}
72
73impl CpuLoadSummary {
74 /// Returns candidates available to `pick_next_task()`, excluding current.
75 pub const fn queued_count(self) -> usize {
76 self.queued_count
77 }
78
79 /// Returns Linux `rq->nr_running`, including a non-idle current task.
80 pub const fn nr_running(self) -> usize {
81 self.nr_running
82 }
83
84 /// Returns the Linux nice-weighted Fair demand owned by this CPU.
85 pub const fn fair_demand(self) -> u64 {
86 self.fair_demand
87 }
88
89 /// Returns instantaneous scheduling demand in normal-nice weight units.
90 ///
91 /// Fair work contributes its exact nice weight. RT and Deadline work each
92 /// contribute one normal-nice capacity unit until class-specific
93 /// utilization tracking is available.
94 pub const fn workload_demand(self) -> u64 {
95 self.workload_demand
96 }
97
98 /// Returns the demand contributed by this CPU's non-idle current task.
99 pub const fn current_workload_demand(self) -> u64 {
100 self.current_workload_demand
101 }
102
103 /// Reports whether this CPU has migratable Fair work.
104 ///
105 /// RT and Deadline overload are deliberately absent from this load
106 /// snapshot. Their sole remote authority is the root-domain `rto`/`dlo`
107 /// index, matching Linux's separation between sched-domain load and
108 /// priority-class overload state.
109 pub const fn has_pushable_fair(self) -> bool {
110 self.fair_pushable
111 }
112
113 /// Reports whether every runnable task on this CPU uses SCHED_IDLE.
114 ///
115 /// Mirrors Linux `sched_idle_rq()`: a non-idle Fair wakee may treat this
116 /// rq as an idle placement target.
117 pub const fn fair_idle_only(self) -> bool {
118 self.fair_idle_only
119 }
120
121 /// Returns Linux `cfs_rq->h_nr_delayed` for this flat runqueue.
122 pub const fn fair_delayed_count(self) -> usize {
123 self.fair_delayed_count
124 }
125}
126
127pub(super) const SUMMARY_FAIR_PUSHABLE: u16 = 1 << 0;
128pub(super) const SUMMARY_FAIR_IDLE_ONLY: u16 = 1 << 1;