scx_lavd: print more info with --monitor

Signed-off-by: Changwoo Min <changwoo@igalia.com>
This commit is contained in:
Changwoo Min 2024-09-05 15:27:15 +09:00
parent f490a55d54
commit fdecba227c
4 changed files with 172 additions and 37 deletions

10
scheds/rust/Cargo.lock generated
View File

@ -527,6 +527,15 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "gpoint"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c00f1d62d57408109a871dd9e12b76645ec4284406d5ec838d277777ef1ef6c"
dependencies = [
"libc",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -1152,6 +1161,7 @@ dependencies = [
"crossbeam",
"ctrlc",
"fb_procfs",
"gpoint",
"hex",
"itertools 0.13.0",
"libbpf-rs",

View File

@ -27,6 +27,7 @@ simplelog = "0.12"
static_assertions = "1.1.0"
rlimit = "0.10.1"
plain = "0.2.3"
gpoint = "0.2"
[build-dependencies]
scx_utils = { path = "../../../rust/scx_utils", version = "1.0.3" }

View File

@ -641,6 +641,31 @@ impl<'a> Scheduler<'a> {
self.skel.maps.bss_data.intrspc.cmd = LAVD_CMD_NOP;
}
fn get_pc(x: u64, y: u64) -> f64 {
return 100. * x as f64 / y as f64;
}
fn get_power_mode(power_mode: s32) -> &'static str {
const LAVD_PM_PERFORMANCE: s32 = 0;
const LAVD_PM_BALANCED: s32 = 1;
const LAVD_PM_POWERSAVE: s32 = 2;
match power_mode {
LAVD_PM_PERFORMANCE => {
return &"performance";
}
LAVD_PM_BALANCED => {
return &"balanced";
}
LAVD_PM_POWERSAVE => {
return &"powersave";
}
_ => {
return &"unknown";
}
}
}
fn stats_req_to_res(&mut self, req: &StatsReq) -> Result<StatsRes> {
Ok(match req {
StatsReq::NewSampler(tid) => {
@ -656,16 +681,49 @@ impl<'a> Scheduler<'a> {
}
self.mseq_id += 1;
let bss_data = &self.skel.maps.bss_data;
let st = bss_data.__sys_stats[0];
let mseq = self.mseq_id;
let avg_svc_time = self.skel.maps.bss_data.__sys_stats[0].avg_svc_time;
let nr_queued_task = self.skel.maps.bss_data.__sys_stats[0].nr_queued_task;
let nr_active = self.skel.maps.bss_data.__sys_stats[0].nr_active;
let avg_svc_time = st.avg_svc_time;
let nr_queued_task = st.nr_queued_task;
let nr_active = st.nr_active;
let nr_sched = st.nr_sched;
let pc_migration = Self::get_pc(st.nr_migration, nr_sched);
let pc_preemption = Self::get_pc(st.nr_preemption, nr_sched);
let pc_greedy = Self::get_pc(st.nr_greedy, nr_sched);
let pc_pc = Self::get_pc(st.nr_perf_cri, nr_sched);
let pc_lc = Self::get_pc(st.nr_lat_cri, nr_sched);
let nr_big = st.nr_big;
let pc_big = Self::get_pc(nr_big, nr_sched);
let pc_pc_on_big = Self::get_pc(st.nr_pc_on_big, nr_big);
let pc_lc_on_big = Self::get_pc(st.nr_lc_on_big, nr_big);
let power_mode = Self::get_power_mode(bss_data.power_mode);
let total_time = bss_data.performance_mode_ns +
bss_data.balanced_mode_ns +
bss_data.powersave_mode_ns;
let pc_performance = Self::get_pc(bss_data.performance_mode_ns, total_time);
let pc_balanced = Self::get_pc(bss_data.balanced_mode_ns, total_time);
let pc_powersave = Self::get_pc(bss_data.powersave_mode_ns, total_time);
StatsRes::SysStats(SysStats {
mseq,
avg_svc_time,
nr_queued_task,
nr_active,
nr_sched,
pc_migration,
pc_preemption,
pc_greedy,
pc_pc,
pc_lc,
pc_big,
pc_pc_on_big,
pc_lc_on_big,
power_mode: power_mode.to_string(),
pc_performance,
pc_balanced,
pc_powersave,
})
}
StatsReq::SchedSamplesNr {

View File

@ -11,8 +11,10 @@ use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::thread::ThreadId;
use std::time::Duration;
use gpoint::GPoint;
#[derive(Clone, Debug, Default, Serialize, Deserialize, Stats)]
#[stat(top)]
pub struct SysStats {
#[stat(desc = "Sequence ID of this messge")]
pub mseq: u64,
@ -25,33 +27,98 @@ pub struct SysStats {
#[stat(desc = "Number of active CPUs when core compaction is enabled")]
pub nr_active: u32,
#[stat(desc = "Number of context switches")]
pub nr_sched: u64,
#[stat(desc = "% of task migration")]
pub pc_migration: f64,
#[stat(desc = "% of task preemption")]
pub pc_preemption: f64,
#[stat(desc = "% of greedy tasks")]
pub pc_greedy: f64,
#[stat(desc = "% of performance-critical tasks")]
pub pc_pc: f64,
#[stat(desc = "% of latency-critical tasks")]
pub pc_lc: f64,
#[stat(desc = "% of tasks scheduled on big cores")]
pub pc_big: f64,
#[stat(desc = "% of performance-critical tasks scheduled on big cores")]
pub pc_pc_on_big: f64,
#[stat(desc = "% of latency-critical tasks scheduled on big cores")]
pub pc_lc_on_big: f64,
#[stat(desc = "Current power mode")]
pub power_mode: String,
#[stat(desc = "% of performance mode")]
pub pc_performance: f64,
#[stat(desc = "% of balanced mode")]
pub pc_balanced: f64,
#[stat(desc = "% of powersave powersave")]
pub pc_powersave: f64,
}
impl SysStats {
pub fn format_header<W: Write>(w: &mut W) -> Result<()> {
writeln!(
w,
"| {} | {} | {} | {} |",
"mseq",
"avg_svc_time",
"nr_queued_task",
"nr_active",
"\x1b[93m| {:8} | {:9} | {:9} | {:9} | {:9} | {:9} | {:9} | {:8} | {:8} | {:8} | {:8} | {:8} | {:8} | {:11} | {:12} | {:12} | {:12} |\x1b[0m",
"MSEQ",
"SVC_TIME",
"# Q TASK",
"# ACT CPU",
"# SCHED",
"MIGRATE%",
"PREEMPT%",
"GREEDY%",
"PERF-CR%",
"LAT-CR%",
"BIG%",
"PC/BIG%",
"LC/BIG%",
"POWER MODE",
"PERFORMANCE%",
"BALANCED%",
"POWERSAVE%",
)?;
Ok(())
}
fn format<W: Write>(&self, w: &mut W) -> Result<()> {
if self.mseq % 32 == 1 {
if self.mseq % 10 == 1 {
Self::format_header(w)?;
}
writeln!(
w,
"| {} | {} | {} | {} |",
"| {:8} | {:9} | {:9} | {:9} | {:9} | {:9} | {:9} | {:8} | {:8} | {:8} | {:8} | {:8} | {:8} | {:11} | {:12} | {:12} | {:12} |",
self.mseq,
self.avg_svc_time,
self.nr_queued_task,
self.nr_active,
self.nr_sched,
GPoint(self.pc_migration),
GPoint(self.pc_preemption),
GPoint(self.pc_greedy),
GPoint(self.pc_pc),
GPoint(self.pc_lc),
GPoint(self.pc_big),
GPoint(self.pc_pc_on_big),
GPoint(self.pc_lc_on_big),
self.power_mode,
GPoint(self.pc_performance),
GPoint(self.pc_balanced),
GPoint(self.pc_powersave),
)?;
Ok(())
}
@ -59,7 +126,6 @@ impl SysStats {
}
#[derive(Clone, Debug, Default, Serialize, Deserialize, Stats)]
#[stat(top)]
pub struct SchedSample {
#[stat(desc = "Sequence ID of this message")]
pub mseq: u64,
@ -111,42 +177,42 @@ impl SchedSample {
pub fn format_header<W: Write>(w: &mut W) -> Result<()> {
writeln!(
w,
"| {:6} | {:7} | {:17} \
"\x1b[93m| {:6} | {:7} | {:17} \
| {:5} | {:4} | {:4} \
| {:14} | {:8} | {:7} \
| {:8} | {:7} | {:8} \
| {:7} | {:9} | {:9} \
| {:9} | {:9} | {:8} \
| {:8} | {:8} | {:8} \
| {:6} |",
"mseq",
"pid",
"comm",
"stat",
"cpu",
"vtmc",
"vddln_ns",
"slc_ns",
"grdy_rt",
"lat_cri",
"avg_lc",
"st_prio",
"slc_bst",
"run_freq",
"run_tm_ns",
"wait_freq",
"wake_freq",
"perf_cri",
"avg_pc",
"cpufreq",
"cpu_util",
"nr_act",
| {:6} |\x1b[0m",
"MSEQ",
"PID",
"COMM",
"STAT",
"CPU",
"VTMC",
"VDDLN_NS",
"SLC_NS",
"GRDY_RT",
"LAT_CRI",
"AVG_LC",
"ST_PRIO",
"SLC_BST",
"RUN_FREQ",
"RUN_TM_NS",
"WAIT_FREQ",
"WAKE_FREQ",
"PERF_CRI",
"AVG_PC",
"CPUFREQ",
"CPU_UTIL",
"NR_ACT",
)?;
Ok(())
}
pub fn format<W: Write>(&self, w: &mut W) -> Result<()> {
if self.mseq % 32 == 1 {
if self.mseq % 10 == 1 {
Self::format_header(w)?;
}
@ -258,7 +324,7 @@ pub fn server_data(nr_cpus_onln: u64) -> StatsServerData<StatsReq, StatsRes> {
}
let read: Box<dyn StatsReader<StatsReq, StatsRes>> =
Box::new(move |args, (req_ch, res_ch)| {
Box::new(move |_args, (req_ch, res_ch)| {
let req = StatsReq::from_args_stats(tid)?;
req_ch.send(req)?;