mirror of
https://github.com/ivabus/speakersafetyd
synced 2024-11-22 08:15:07 +03:00
uclamp: Add support for sched utilization clamping
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
60752494cd
commit
c3307388aa
13 changed files with 81 additions and 0 deletions
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 4
|
channels = 4
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 2
|
channels = 2
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = False
|
link_gains = False
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 8
|
channels = 8
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 4
|
channels = 4
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 12
|
channels = 12
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 12
|
channels = 12
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 8
|
channels = 8
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 12
|
channels = 12
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
vsense = VSENSE Switch
|
vsense = VSENSE Switch
|
||||||
|
|
|
@ -6,6 +6,7 @@ t_window = 20.0
|
||||||
channels = 8
|
channels = 8
|
||||||
period = 4096
|
period = 4096
|
||||||
link_gains = True
|
link_gains = True
|
||||||
|
uclamp_max = 64
|
||||||
|
|
||||||
[Controls]
|
[Controls]
|
||||||
# vsense =
|
# vsense =
|
||||||
|
|
|
@ -58,6 +58,16 @@ where
|
||||||
.expect("{}/{}: Out of bounds")
|
.expect("{}/{}: Out of bounds")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_opt_int<T: TryFrom<i64>>(config: &Ini, section: &str, key: &str) -> Option<T>
|
||||||
|
where
|
||||||
|
<T as TryFrom<i64>>::Error: std::fmt::Debug,
|
||||||
|
{
|
||||||
|
config
|
||||||
|
.getint(section, key)
|
||||||
|
.expect(&format!("{}/{}: Invalid value", section, key))
|
||||||
|
.map(|a| a.try_into().expect("{}/{}: Out of bounds"))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Wrapper around configparser::ini::Ini.getfloat()
|
Wrapper around configparser::ini::Ini.getfloat()
|
||||||
to safely unwrap the Result<Option<f64>, E> returned by
|
to safely unwrap the Result<Option<f64>, E> returned by
|
||||||
|
|
|
@ -26,6 +26,7 @@ use simple_logger::SimpleLogger;
|
||||||
mod blackbox;
|
mod blackbox;
|
||||||
mod helpers;
|
mod helpers;
|
||||||
mod types;
|
mod types;
|
||||||
|
mod uclamp;
|
||||||
|
|
||||||
const DEFAULT_CONFIG_PATH: &str = "share/speakersafetyd";
|
const DEFAULT_CONFIG_PATH: &str = "share/speakersafetyd";
|
||||||
|
|
||||||
|
@ -143,6 +144,13 @@ fn main() {
|
||||||
|
|
||||||
let globals = types::Globals::parse(&cfg);
|
let globals = types::Globals::parse(&cfg);
|
||||||
|
|
||||||
|
if globals.uclamp_min.is_some() || globals.uclamp_max.is_some() {
|
||||||
|
uclamp::set_uclamp(
|
||||||
|
globals.uclamp_min.unwrap_or(0).try_into().unwrap(),
|
||||||
|
globals.uclamp_max.unwrap_or(1024).try_into().unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let mut blackbox = args.blackbox_path.map(|p| {
|
let mut blackbox = args.blackbox_path.map(|p| {
|
||||||
info!("Enabling blackbox, path: {:?}", p);
|
info!("Enabling blackbox, path: {:?}", p);
|
||||||
blackbox::Blackbox::new(&machine, &p, &globals)
|
blackbox::Blackbox::new(&machine, &p, &globals)
|
||||||
|
|
|
@ -192,6 +192,8 @@ pub struct Globals {
|
||||||
pub ctl_isense: String,
|
pub ctl_isense: String,
|
||||||
pub ctl_amp_gain: String,
|
pub ctl_amp_gain: String,
|
||||||
pub ctl_volume: String,
|
pub ctl_volume: String,
|
||||||
|
pub uclamp_min: Option<usize>,
|
||||||
|
pub uclamp_max: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Globals {
|
impl Globals {
|
||||||
|
@ -207,6 +209,8 @@ impl Globals {
|
||||||
ctl_isense: helpers::parse_string(config, "Controls", "isense"),
|
ctl_isense: helpers::parse_string(config, "Controls", "isense"),
|
||||||
ctl_amp_gain: helpers::parse_string(config, "Controls", "amp_gain"),
|
ctl_amp_gain: helpers::parse_string(config, "Controls", "amp_gain"),
|
||||||
ctl_volume: helpers::parse_string(config, "Controls", "volume"),
|
ctl_volume: helpers::parse_string(config, "Controls", "volume"),
|
||||||
|
uclamp_min: helpers::parse_opt_int(config, "Globals", "uclamp_min"),
|
||||||
|
uclamp_max: helpers::parse_opt_int(config, "Globals", "uclamp_max"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
50
src/uclamp.rs
Normal file
50
src/uclamp.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use log::{info, warn};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct SchedAttr {
|
||||||
|
size: u32,
|
||||||
|
sched_policy: u32,
|
||||||
|
sched_flags: u64,
|
||||||
|
sched_nice: i32,
|
||||||
|
sched_priority: u32,
|
||||||
|
sched_runtime: u64,
|
||||||
|
sched_deadline: u64,
|
||||||
|
sched_period: u64,
|
||||||
|
sched_util_min: u32,
|
||||||
|
sched_util_max: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_uclamp(uclamp_min: u32, uclamp_max: u32) {
|
||||||
|
let mut attr: SchedAttr = Default::default();
|
||||||
|
let pid = unsafe { libc::getpid() };
|
||||||
|
|
||||||
|
if unsafe {
|
||||||
|
libc::syscall(
|
||||||
|
libc::SYS_sched_getattr,
|
||||||
|
pid,
|
||||||
|
&mut attr,
|
||||||
|
core::mem::size_of::<SchedAttr>(),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
} != 0
|
||||||
|
{
|
||||||
|
warn!("Failed to set uclamp");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SCHED_FLAG_KEEP_POLICY |
|
||||||
|
* SCHED_FLAG_KEEP_PARAMS |
|
||||||
|
* SCHED_FLAG_UTIL_CLAMP_MIN |
|
||||||
|
* SCHED_FLAG_UTIL_CLAMP_MAX */
|
||||||
|
attr.sched_flags = 0x8 | 0x10 | 0x20 | 0x40;
|
||||||
|
attr.sched_util_min = uclamp_min;
|
||||||
|
attr.sched_util_max = uclamp_max;
|
||||||
|
|
||||||
|
if unsafe { libc::syscall(libc::SYS_sched_setattr, pid, &mut attr, 0) } != 0 {
|
||||||
|
warn!("Failed to set uclamp");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Set task uclamp to {}:{}", uclamp_min, uclamp_max);
|
||||||
|
}
|
Loading…
Reference in a new issue