mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: hwmon monitoring on xe
This commit is contained in:
parent
9af6887a63
commit
204dcb47fc
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1519,7 +1519,6 @@ dependencies = [
|
|||||||
"os-release",
|
"os-release",
|
||||||
"pciid-parser",
|
"pciid-parser",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"regex",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
@ -44,7 +44,6 @@ tar = "0.4.40"
|
|||||||
libflate = "2.0.0"
|
libflate = "2.0.0"
|
||||||
os-release = "0.1.0"
|
os-release = "0.1.0"
|
||||||
notify = { version = "6.1.1", default-features = false }
|
notify = { version = "6.1.1", default-features = false }
|
||||||
regex = "1.11.0"
|
|
||||||
copes = { git = "https://gitlab.com/corectrl/copes" }
|
copes = { git = "https://gitlab.com/corectrl/copes" }
|
||||||
libloading = "0.8.6"
|
libloading = "0.8.6"
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ impl GpuController for IntelGpuController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(cap) = config.power_cap {
|
if let Some(cap) = config.power_cap {
|
||||||
self.write_hwmon_file("power1_max", &((cap * 1_000_000.0) as u64).to_string())
|
self.write_hwmon_file("power", "_max", &((cap * 1_000_000.0) as u64).to_string())
|
||||||
.context("Could not set power cap")?;
|
.context("Could not set power cap")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ impl GpuController for IntelGpuController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let cap_current = self
|
let cap_current = self
|
||||||
.read_hwmon_file("power1_max")
|
.read_hwmon_file("power", "_max")
|
||||||
.map(|value: f64| value / 1_000_000.0)
|
.map(|value: f64| value / 1_000_000.0)
|
||||||
.map(|cap| if cap == 0.0 { 100.0 } else { cap }); // Placeholder max value
|
.map(|cap| if cap == 0.0 { 100.0 } else { cap }); // Placeholder max value
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ impl GpuController for IntelGpuController {
|
|||||||
cap_current,
|
cap_current,
|
||||||
cap_min: Some(0.0),
|
cap_min: Some(0.0),
|
||||||
cap_max: self
|
cap_max: self
|
||||||
.read_hwmon_file::<f64>("power1_rated_max")
|
.read_hwmon_file::<f64>("power", "_rated_max")
|
||||||
.filter(|max| *max != 0.0)
|
.filter(|max| *max != 0.0)
|
||||||
.map(|cap| cap / 1_000_000.0)
|
.map(|cap| cap / 1_000_000.0)
|
||||||
.or_else(|| cap_current.map(|current| current * 2.0)),
|
.or_else(|| cap_current.map(|current| current * 2.0)),
|
||||||
@ -207,7 +207,7 @@ impl GpuController for IntelGpuController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let voltage = VoltageStats {
|
let voltage = VoltageStats {
|
||||||
gpu: self.read_hwmon_file("in0_input"),
|
gpu: self.read_hwmon_file("in", "_input"),
|
||||||
northbridge: None,
|
northbridge: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ impl GpuController for IntelGpuController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let fan = FanStats {
|
let fan = FanStats {
|
||||||
speed_current: self.read_hwmon_file("fan1_input"),
|
speed_current: self.read_hwmon_file("fan", "_input"),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -344,22 +344,43 @@ impl IntelGpuController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_hwmon_file<T>(&self, file_name: &str) -> Option<T>
|
fn read_hwmon_file<T>(&self, file_prefix: &str, file_suffix: &str) -> Option<T>
|
||||||
where
|
where
|
||||||
T: FromStr,
|
T: FromStr,
|
||||||
T::Err: Display,
|
T::Err: Display,
|
||||||
{
|
{
|
||||||
self.hwmon_path.as_ref().and_then(|hwmon_path| {
|
self.hwmon_path.as_ref().and_then(|hwmon_path| {
|
||||||
let file_path = hwmon_path.join(file_name);
|
let entries = fs::read_dir(hwmon_path).ok()?;
|
||||||
self.read_file(file_path)
|
for entry in entries.flatten() {
|
||||||
|
if let Some(name) = entry.file_name().to_str() {
|
||||||
|
if name.starts_with(file_prefix) && name.ends_with(file_suffix) {
|
||||||
|
return self.read_file(entry.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_hwmon_file(&self, file_name: &str, contents: &str) -> anyhow::Result<()> {
|
fn write_hwmon_file(
|
||||||
debug!("writing value '{contents}' to '{file_name}'");
|
&self,
|
||||||
|
file_prefix: &str,
|
||||||
|
file_suffix: &str,
|
||||||
|
contents: &str,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
debug!("writing value '{contents}' to '{file_prefix}*{file_suffix}'");
|
||||||
|
|
||||||
if let Some(hwmon_path) = &self.hwmon_path {
|
if let Some(hwmon_path) = &self.hwmon_path {
|
||||||
let file_path = hwmon_path.join(file_name);
|
let entries = fs::read_dir(hwmon_path)?;
|
||||||
self.write_file(file_path, contents)
|
for entry in entries.flatten() {
|
||||||
|
if let Some(name) = entry.file_name().to_str() {
|
||||||
|
if name.starts_with(file_prefix) && name.ends_with(file_suffix) {
|
||||||
|
return self.write_file(entry.path(), contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(anyhow!("File not found"))
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("No hwmon available"))
|
Err(anyhow!("No hwmon available"))
|
||||||
}
|
}
|
||||||
@ -453,9 +474,9 @@ impl IntelGpuController {
|
|||||||
|
|
||||||
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
|
||||||
fn get_power_usage(&self) -> Option<f64> {
|
fn get_power_usage(&self) -> Option<f64> {
|
||||||
self.read_hwmon_file::<u64>("power1_input")
|
self.read_hwmon_file::<u64>("power", "_input")
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
let energy = self.read_hwmon_file("energy1_input")?;
|
let energy = self.read_hwmon_file("energy", "_input")?;
|
||||||
let timestamp = Instant::now();
|
let timestamp = Instant::now();
|
||||||
|
|
||||||
match self.last_energy_value.replace(Some((timestamp, energy))) {
|
match self.last_energy_value.replace(Some((timestamp, energy))) {
|
||||||
@ -472,7 +493,7 @@ impl IntelGpuController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_temperatures(&self) -> HashMap<String, Temperature> {
|
fn get_temperatures(&self) -> HashMap<String, Temperature> {
|
||||||
self.read_hwmon_file::<f32>("temp1_input")
|
self.read_hwmon_file::<f32>("temp", "_input")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|temp| {
|
.map(|temp| {
|
||||||
let key = "gpu".to_owned();
|
let key = "gpu".to_owned();
|
||||||
@ -531,10 +552,10 @@ impl IntelGpuController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_throttle_info(&self) -> Option<BTreeMap<String, Vec<String>>> {
|
fn get_throttle_info(&self) -> Option<BTreeMap<String, Vec<String>>> {
|
||||||
|
let mut reasons = BTreeMap::new();
|
||||||
|
|
||||||
match self.driver_type {
|
match self.driver_type {
|
||||||
DriverType::I915 => {
|
DriverType::I915 => {
|
||||||
let mut reasons = BTreeMap::new();
|
|
||||||
|
|
||||||
let card_path = self
|
let card_path = self
|
||||||
.common
|
.common
|
||||||
.sysfs_path
|
.sysfs_path
|
||||||
@ -557,11 +578,27 @@ impl IntelGpuController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(reasons)
|
|
||||||
}
|
}
|
||||||
DriverType::Xe => None,
|
DriverType::Xe => {
|
||||||
|
if let Some(tile) = self.first_tile_gt() {
|
||||||
|
let path = self.common.sysfs_path.join(tile).join("freq0/throttle");
|
||||||
|
|
||||||
|
let throttle_files = fs::read_dir(path).ok()?;
|
||||||
|
for file in throttle_files.flatten() {
|
||||||
|
if let Some(name) = file.file_name().to_str() {
|
||||||
|
if let Some(reason) = name.strip_prefix("reason_") {
|
||||||
|
if let Some(value) = self.read_file::<i32>(file.path()) {
|
||||||
|
if value != 0 {
|
||||||
|
reasons.insert(reason.to_owned(), vec![]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Some(reasons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
lact-daemon/src/tests/data/intel/a380-xe/card0/dev
Normal file
1
lact-daemon/src/tests/data/intel/a380-xe/card0/dev
Normal file
@ -0,0 +1 @@
|
|||||||
|
226:0
|
@ -0,0 +1 @@
|
|||||||
|
2.5 GT/s PCIe
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
2850177917
|
@ -0,0 +1 @@
|
|||||||
|
pkg
|
@ -0,0 +1 @@
|
|||||||
|
638
|
@ -0,0 +1 @@
|
|||||||
|
pkg
|
@ -0,0 +1 @@
|
|||||||
|
xe
|
@ -0,0 +1 @@
|
|||||||
|
auto
|
@ -0,0 +1 @@
|
|||||||
|
0
|
@ -0,0 +1 @@
|
|||||||
|
unsupported
|
@ -0,0 +1 @@
|
|||||||
|
0
|
@ -0,0 +1 @@
|
|||||||
|
card
|
@ -0,0 +1 @@
|
|||||||
|
pkg
|
@ -0,0 +1 @@
|
|||||||
|
55000000
|
@ -0,0 +1 @@
|
|||||||
|
28000
|
@ -0,0 +1 @@
|
|||||||
|
0
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
1000
|
@ -0,0 +1 @@
|
|||||||
|
10000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
5000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
@ -0,0 +1 @@
|
|||||||
|
1
|
@ -0,0 +1 @@
|
|||||||
|
640000
|
@ -0,0 +1 @@
|
|||||||
|
10000000
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user