mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-12 09:22:26 -04:00
power: Add get/set_gpu_clocks and get_tdp_limit tests
This commit is contained in:
parent
3c62c57d52
commit
bc6af282eb
1 changed files with 77 additions and 13 deletions
90
src/power.rs
90
src/power.rs
|
@ -20,6 +20,9 @@ const GPU_PERFORMANCE_LEVEL_PATH: &str =
|
||||||
"/sys/class/drm/card0/device/power_dpm_force_performance_level";
|
"/sys/class/drm/card0/device/power_dpm_force_performance_level";
|
||||||
const GPU_CLOCKS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
const GPU_CLOCKS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||||
|
|
||||||
|
const TDP_LIMIT1: &str = "power1_cap";
|
||||||
|
const TDP_LIMIT2: &str = "power2_cap";
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum GPUPerformanceLevel {
|
pub enum GPUPerformanceLevel {
|
||||||
|
@ -158,7 +161,7 @@ async fn find_hwmon() -> Result<PathBuf> {
|
||||||
Some(entry) => entry.path(),
|
Some(entry) => entry.path(),
|
||||||
None => bail!("hwmon not found"),
|
None => bail!("hwmon not found"),
|
||||||
};
|
};
|
||||||
if fs::try_exists(base.join("power1_cap")).await? {
|
if fs::try_exists(base.join(TDP_LIMIT1)).await? {
|
||||||
return Ok(base);
|
return Ok(base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +169,7 @@ async fn find_hwmon() -> Result<PathBuf> {
|
||||||
|
|
||||||
pub async fn get_tdp_limit() -> Result<u32> {
|
pub async fn get_tdp_limit() -> Result<u32> {
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
let power1cap = fs::read_to_string(base.join("power1_cap")).await?;
|
let power1cap = fs::read_to_string(base.join(TDP_LIMIT1)).await?;
|
||||||
let power1cap: u32 = power1cap.parse()?;
|
let power1cap: u32 = power1cap.parse()?;
|
||||||
Ok(power1cap / 1000000)
|
Ok(power1cap / 1000000)
|
||||||
}
|
}
|
||||||
|
@ -178,7 +181,7 @@ pub async fn set_tdp_limit(limit: u32) -> Result<()> {
|
||||||
let data = format!("{limit}000000");
|
let data = format!("{limit}000000");
|
||||||
|
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
let mut power1file = File::create(base.join("power1_cap"))
|
let mut power1file = File::create(base.join(TDP_LIMIT1))
|
||||||
.await
|
.await
|
||||||
.inspect_err(|message| {
|
.inspect_err(|message| {
|
||||||
error!("Error opening sysfs power1_cap file for writing TDP limits {message}")
|
error!("Error opening sysfs power1_cap file for writing TDP limits {message}")
|
||||||
|
@ -188,7 +191,7 @@ pub async fn set_tdp_limit(limit: u32) -> Result<()> {
|
||||||
.await
|
.await
|
||||||
.inspect_err(|message| error!("Error writing to power1_cap file: {message}"))?;
|
.inspect_err(|message| error!("Error writing to power1_cap file: {message}"))?;
|
||||||
|
|
||||||
if let Ok(mut power2file) = File::create(base.join("power2_cap")).await {
|
if let Ok(mut power2file) = File::create(base.join(TDP_LIMIT2)).await {
|
||||||
power2file
|
power2file
|
||||||
.write(data.as_bytes())
|
.write(data.as_bytes())
|
||||||
.await
|
.await
|
||||||
|
@ -300,6 +303,21 @@ mod test {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_tdp_limit() {
|
||||||
|
let h = testing::start();
|
||||||
|
|
||||||
|
let hwmon = path(GPU_HWMON_PREFIX);
|
||||||
|
create_dir_all(hwmon.join("hwmon5").as_path())
|
||||||
|
.await
|
||||||
|
.expect("create_dir_all");
|
||||||
|
|
||||||
|
assert!(get_tdp_limit().await.is_err());
|
||||||
|
|
||||||
|
write(hwmon.join("hwmon5").join(TDP_LIMIT1), "15000000").await.expect("write");
|
||||||
|
assert_eq!(get_tdp_limit().await.unwrap(), 15);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_set_tdp_limit() {
|
async fn test_set_tdp_limit() {
|
||||||
let h = testing::start();
|
let h = testing::start();
|
||||||
|
@ -324,10 +342,10 @@ mod test {
|
||||||
);
|
);
|
||||||
|
|
||||||
let hwmon = hwmon.join("hwmon5");
|
let hwmon = hwmon.join("hwmon5");
|
||||||
create_dir_all(hwmon.join("power1_cap"))
|
create_dir_all(hwmon.join(TDP_LIMIT1))
|
||||||
.await
|
.await
|
||||||
.expect("create_dir_all");
|
.expect("create_dir_all");
|
||||||
create_dir_all(hwmon.join("power2_cap"))
|
create_dir_all(hwmon.join(TDP_LIMIT2))
|
||||||
.await
|
.await
|
||||||
.expect("create_dir_all");
|
.expect("create_dir_all");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -335,28 +353,74 @@ mod test {
|
||||||
anyhow!("Is a directory (os error 21)").to_string()
|
anyhow!("Is a directory (os error 21)").to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
remove_dir(hwmon.join("power1_cap"))
|
remove_dir(hwmon.join(TDP_LIMIT1))
|
||||||
.await
|
.await
|
||||||
.expect("remove_dir");
|
.expect("remove_dir");
|
||||||
write(hwmon.join("power1_cap"), "0").await.expect("write");
|
write(hwmon.join(TDP_LIMIT1), "0").await.expect("write");
|
||||||
assert!(set_tdp_limit(10).await.is_ok());
|
assert!(set_tdp_limit(10).await.is_ok());
|
||||||
let power1_cap = read_to_string(hwmon.join("power1_cap"))
|
let power1_cap = read_to_string(hwmon.join(TDP_LIMIT1))
|
||||||
.await
|
.await
|
||||||
.expect("power1_cap");
|
.expect("power1_cap");
|
||||||
assert_eq!(power1_cap, "10000000");
|
assert_eq!(power1_cap, "10000000");
|
||||||
|
|
||||||
remove_dir(hwmon.join("power2_cap"))
|
remove_dir(hwmon.join(TDP_LIMIT2))
|
||||||
.await
|
.await
|
||||||
.expect("remove_dir");
|
.expect("remove_dir");
|
||||||
write(hwmon.join("power2_cap"), "0").await.expect("write");
|
write(hwmon.join(TDP_LIMIT2), "0").await.expect("write");
|
||||||
assert!(set_tdp_limit(15).await.is_ok());
|
assert!(set_tdp_limit(15).await.is_ok());
|
||||||
let power1_cap = read_to_string(hwmon.join("power1_cap"))
|
let power1_cap = read_to_string(hwmon.join(TDP_LIMIT1))
|
||||||
.await
|
.await
|
||||||
.expect("power1_cap");
|
.expect("power1_cap");
|
||||||
assert_eq!(power1_cap, "15000000");
|
assert_eq!(power1_cap, "15000000");
|
||||||
let power2_cap = read_to_string(hwmon.join("power2_cap"))
|
let power2_cap = read_to_string(hwmon.join(TDP_LIMIT2))
|
||||||
.await
|
.await
|
||||||
.expect("power2_cap");
|
.expect("power2_cap");
|
||||||
assert_eq!(power2_cap, "15000000");
|
assert_eq!(power2_cap, "15000000");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_gpu_clocks() {
|
||||||
|
let h = testing::start();
|
||||||
|
|
||||||
|
const contents: &str = "OD_SCLK:
|
||||||
|
0: 1600Mhz
|
||||||
|
1: 1600Mhz
|
||||||
|
OD_RANGE:
|
||||||
|
SCLK: 200Mhz 1600Mhz
|
||||||
|
CCLK: 1400Mhz 3500Mhz
|
||||||
|
CCLK_RANGE in Core0:
|
||||||
|
0: 1400Mhz
|
||||||
|
1: 3500Mhz\n";
|
||||||
|
let filename = path(GPU_PERFORMANCE_LEVEL_PATH);
|
||||||
|
setup_test().await;
|
||||||
|
|
||||||
|
assert!(get_gpu_clocks().await.is_err());
|
||||||
|
write(path(GPU_CLOCKS_PATH), contents).await.expect("write");
|
||||||
|
|
||||||
|
assert_eq!(get_gpu_clocks().await.unwrap(), 1600);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_set_gpu_clocks() {
|
||||||
|
let h = testing::start();
|
||||||
|
|
||||||
|
let filename = path(GPU_CLOCKS_PATH);
|
||||||
|
assert!(set_gpu_clocks(1600).await.is_err());
|
||||||
|
setup_test().await;
|
||||||
|
|
||||||
|
assert!(set_gpu_clocks(100).await.is_err());
|
||||||
|
assert!(set_gpu_clocks(2000).await.is_err());
|
||||||
|
|
||||||
|
assert!(set_gpu_clocks(200).await.is_ok());
|
||||||
|
assert_eq!(
|
||||||
|
read_to_string(filename.as_path()).await.expect("string"),
|
||||||
|
"s 0 200\ns 1 200\nc\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(set_gpu_clocks(1600).await.is_ok());
|
||||||
|
assert_eq!(
|
||||||
|
read_to_string(filename.as_path()).await.expect("string"),
|
||||||
|
"s 0 1600\ns 1 1600\nc\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue