mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
set governor to "performance" if available (#2438)
* set governor to "performance" if available * add linux-cpupower * fix: Boolean blindness, thanks @dr-bones --------- Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
This commit is contained in:
59
backend/Cargo.lock
generated
59
backend/Cargo.lock
generated
@@ -661,6 +661,26 @@ version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format_proc_macros"
|
||||
version = "0.2.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.66",
|
||||
"quote 1.0.31",
|
||||
"unicode-xid 0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
@@ -679,6 +699,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.16.2"
|
||||
@@ -1074,7 +1103,7 @@ version = "0.99.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"convert_case 0.4.0",
|
||||
"proc-macro2 1.0.66",
|
||||
"quote 1.0.31",
|
||||
"rustc_version 0.4.0",
|
||||
@@ -4519,6 +4548,33 @@ dependencies = [
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sscanf"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c713ebd15ce561dd4a13ed62bc2a0368e16806fc30dcaf66ecf1256b2a3fdde6"
|
||||
dependencies = [
|
||||
"const_format",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"sscanf_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sscanf_macro"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84955aa74a157e5834d58a07be11af7f0ab923f0194a0bb2ea6b3db8b5d1611d"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"proc-macro2 1.0.66",
|
||||
"quote 1.0.31",
|
||||
"regex-syntax 0.6.29",
|
||||
"strsim 0.10.0",
|
||||
"syn 2.0.18",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ssh-encoding"
|
||||
version = "0.1.0"
|
||||
@@ -4657,6 +4713,7 @@ dependencies = [
|
||||
"sha2 0.9.9",
|
||||
"simple-logging",
|
||||
"sqlx",
|
||||
"sscanf",
|
||||
"ssh-key",
|
||||
"stderrlog",
|
||||
"tar",
|
||||
|
||||
@@ -121,6 +121,7 @@ rpassword = "7.0.0"
|
||||
rpc-toolkit = "0.2.2"
|
||||
rust-argon2 = "1.0.0"
|
||||
scopeguard = "1.1" # because avahi-sys fucks your shit up
|
||||
sscanf = "0.4.1"
|
||||
serde = { version = "1.0.139", features = ["derive", "rc"] }
|
||||
serde_cbor = { package = "ciborium", version = "0.2.0" }
|
||||
serde_json = "1.0.82"
|
||||
|
||||
@@ -20,6 +20,9 @@ use crate::middleware::auth::LOCAL_AUTH_COOKIE_PATH;
|
||||
use crate::prelude::*;
|
||||
use crate::sound::BEP;
|
||||
use crate::system::time;
|
||||
use crate::util::cpupower::{
|
||||
current_governor, get_available_governors, set_governor, GOVERNOR_PERFORMANCE,
|
||||
};
|
||||
use crate::util::docker::{create_bridge_network, CONTAINER_DATADIR, CONTAINER_TOOL};
|
||||
use crate::util::Invoke;
|
||||
use crate::{Error, ARCH};
|
||||
@@ -341,6 +344,23 @@ pub async fn init(cfg: &RpcContextConfig) -> Result<InitResult, Error> {
|
||||
.await?;
|
||||
tracing::info!("Enabled Docker QEMU Emulation");
|
||||
|
||||
if current_governor()
|
||||
.await?
|
||||
.map(|g| &g != &GOVERNOR_PERFORMANCE)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
tracing::info!("Setting CPU Governor to \"{}\"", GOVERNOR_PERFORMANCE);
|
||||
if get_available_governors()
|
||||
.await?
|
||||
.contains(&GOVERNOR_PERFORMANCE)
|
||||
{
|
||||
set_governor(&GOVERNOR_PERFORMANCE).await?;
|
||||
tracing::info!("Set CPU Governor");
|
||||
} else {
|
||||
tracing::warn!("CPU Governor \"{}\" Not Available", GOVERNOR_PERFORMANCE)
|
||||
}
|
||||
}
|
||||
|
||||
let mut warn_time_not_synced = true;
|
||||
for _ in 0..60 {
|
||||
if check_time_is_synchronized().await? {
|
||||
|
||||
125
backend/src/util/cpupower.rs
Normal file
125
backend/src/util/cpupower.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use imbl::OrdMap;
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::util::Invoke;
|
||||
|
||||
pub const GOVERNOR_PERFORMANCE: Governor = Governor(Cow::Borrowed("performance"));
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Governor(Cow<'static, str>);
|
||||
impl std::fmt::Display for Governor {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Governor {
|
||||
type Target = str;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&*self.0
|
||||
}
|
||||
}
|
||||
impl std::borrow::Borrow<str> for Governor {
|
||||
fn borrow(&self) -> &str {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_available_governors() -> Result<BTreeSet<Governor>, Error> {
|
||||
let raw = String::from_utf8(
|
||||
Command::new("cpupower")
|
||||
.arg("frequency-info")
|
||||
.arg("-g")
|
||||
.invoke(ErrorKind::CpuSettings)
|
||||
.await?,
|
||||
)?;
|
||||
let mut for_cpu: OrdMap<u32, BTreeSet<Governor>> = OrdMap::new();
|
||||
let mut current_cpu = None;
|
||||
for line in raw.lines() {
|
||||
if line.starts_with("analyzing") {
|
||||
current_cpu = Some(
|
||||
sscanf::sscanf!(line, "analyzing CPU {u32}:")
|
||||
.map_err(|e| eyre!("{e}"))
|
||||
.with_kind(ErrorKind::ParseSysInfo)?,
|
||||
);
|
||||
} else if let Some(rest) = line
|
||||
.trim()
|
||||
.strip_prefix("available cpufreq governors:")
|
||||
.map(|s| s.trim())
|
||||
{
|
||||
if rest != "Not Available" {
|
||||
for_cpu
|
||||
.entry(current_cpu.ok_or_else(|| {
|
||||
Error::new(
|
||||
eyre!("governors listed before cpu"),
|
||||
ErrorKind::ParseSysInfo,
|
||||
)
|
||||
})?)
|
||||
.or_default()
|
||||
.extend(
|
||||
rest.split_ascii_whitespace()
|
||||
.map(|g| Governor(Cow::Owned(g.to_owned()))),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(for_cpu
|
||||
.into_iter()
|
||||
.fold(None, |acc: Option<BTreeSet<Governor>>, (_, x)| {
|
||||
if let Some(acc) = acc {
|
||||
Some(acc.intersection(&x).cloned().collect())
|
||||
} else {
|
||||
Some(x)
|
||||
}
|
||||
})
|
||||
.unwrap_or_default()) // include only governors available for ALL cpus
|
||||
}
|
||||
|
||||
pub async fn current_governor() -> Result<Option<Governor>, Error> {
|
||||
let Some(raw) = Command::new("cpupower")
|
||||
.arg("frequency-info")
|
||||
.arg("-p")
|
||||
.invoke(ErrorKind::CpuSettings)
|
||||
.await
|
||||
.and_then(|s| Ok(Some(String::from_utf8(s)?)))
|
||||
.or_else(|e| {
|
||||
if e.source
|
||||
.to_string()
|
||||
.contains("Unable to determine current policy")
|
||||
{
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})?
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
for line in raw.lines() {
|
||||
if let Some(governor) = line
|
||||
.trim()
|
||||
.strip_prefix("The governor \"")
|
||||
.and_then(|s| s.strip_suffix("\" may decide which speed to use"))
|
||||
{
|
||||
return Ok(Some(Governor(Cow::Owned(governor.to_owned()))));
|
||||
}
|
||||
}
|
||||
Err(Error::new(
|
||||
eyre!("Failed to parse cpupower output:\n{raw}"),
|
||||
ErrorKind::ParseSysInfo,
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn set_governor(governor: &Governor) -> Result<(), Error> {
|
||||
Command::new("cpupower")
|
||||
.arg("frequency-set")
|
||||
.arg("-g")
|
||||
.arg(&*governor.0)
|
||||
.invoke(ErrorKind::CpuSettings)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -24,6 +24,7 @@ use tracing::instrument;
|
||||
use crate::shutdown::Shutdown;
|
||||
use crate::{Error, ErrorKind, ResultExt as _};
|
||||
pub mod config;
|
||||
pub mod cpupower;
|
||||
pub mod docker;
|
||||
pub mod http_reader;
|
||||
pub mod io;
|
||||
|
||||
Reference in New Issue
Block a user