Merge branch 'master' into feature/intel

This commit is contained in:
Ilya Zlobintsev 2025-01-04 15:32:39 +02:00
commit e63e168afb
9 changed files with 60 additions and 37 deletions

5
Cargo.lock generated
View File

@ -1621,11 +1621,12 @@ checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
[[package]]
name = "libdrm_amdgpu_sys"
version = "0.7.6"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b138fce021c047c76625cd701e8efb2450d8677551f79d8b5574581b9533f107"
checksum = "239a084aa81eb01317fe32f41a9ba7d284acf13f079523e3b9406339f4ba7c0c"
dependencies = [
"libc",
"libloading 0.8.5",
]
[[package]]

View File

@ -37,8 +37,8 @@ pciid-parser = { version = "0.7", features = ["serde"] }
serde_yaml = "0.9"
vulkano = { version = "0.34.1", default-features = false }
zbus = { version = "4.1.2", default-features = false, features = ["tokio"] }
libdrm_amdgpu_sys = { version = "0.7.5", default-features = false, features = [
"std",
libdrm_amdgpu_sys = { version = "0.8.1", default-features = false, features = [
"dynamic_loading",
] }
tar = "0.4.40"
libflate = "2.0.0"

View File

@ -19,6 +19,7 @@ use lact_schema::{
ClocksInfo, ClockspeedStats, DeviceInfo, DeviceStats, DrmInfo, FanStats, IntelDrmInfo,
LinkInfo, PmfwInfo, PowerState, PowerStates, PowerStats, VoltageStats, VramStats,
};
use libdrm_amdgpu_sys::LibDrmAmdgpu;
use libdrm_amdgpu_sys::AMDGPU::{ThrottleStatus, ThrottlerBit};
use std::{
cell::RefCell,
@ -54,15 +55,18 @@ pub struct AmdGpuController {
}
impl AmdGpuController {
pub fn new_from_path(common: CommonControllerInfo) -> anyhow::Result<Self> {
pub fn new_from_path(
common: CommonControllerInfo,
libdrm_amdgpu: Option<&LibDrmAmdgpu>,
) -> anyhow::Result<Self> {
let handle = GpuHandle::new_from_path(common.sysfs_path.clone())
.map_err(|error| anyhow!("failed to initialize gpu handle: {error}"))?;
#[allow(unused_mut)]
let mut drm_handle = None;
#[cfg(not(test))]
if matches!(handle.get_driver(), "amdgpu" | "radeon") {
match get_drm_handle(&handle) {
if matches!(handle.get_driver(), "amdgpu" | "radeon") && libdrm_amdgpu.is_some() {
match get_drm_handle(&handle, libdrm_amdgpu.as_ref().unwrap()) {
Ok(handle) => {
drm_handle = Some(handle);
}
@ -957,8 +961,8 @@ impl GpuController for AmdGpuController {
}
#[cfg(not(test))]
fn get_drm_handle(handle: &GpuHandle) -> anyhow::Result<DrmHandle> {
use std::os::fd::IntoRawFd;
fn get_drm_handle(handle: &GpuHandle, libdrm_amdgpu: &LibDrmAmdgpu) -> anyhow::Result<DrmHandle> {
use std::os::unix::io::IntoRawFd;
let slot_name = handle
.get_pci_slot_name()
@ -969,7 +973,8 @@ fn get_drm_handle(handle: &GpuHandle) -> anyhow::Result<DrmHandle> {
.write(true)
.open(&path)
.with_context(|| format!("Could not open drm file at {path}"))?;
let (handle, _, _) = DrmHandle::init(drm_file.into_raw_fd())
let (handle, _, _) = libdrm_amdgpu
.init_device_handle(drm_file.into_raw_fd())
.map_err(|err| anyhow!("Could not open drm handle, error code {err}"))?;
Ok(handle)
}

View File

@ -7,16 +7,17 @@ mod nvidia;
use amd::AmdGpuController;
use intel::IntelGpuController;
use nvidia::NvidiaGpuController;
use tracing::{error, info, warn};
use crate::config::{self};
use amdgpu_sysfs::gpu_handle::power_profile_mode::PowerProfileModesTable;
use anyhow::Context;
use futures::future::LocalBoxFuture;
use lact_schema::{ClocksInfo, DeviceInfo, DeviceStats, GpuPciInfo, PciInfo, PowerStates};
use libdrm_amdgpu_sys::LibDrmAmdgpu;
use nvml_wrapper::Nvml;
use std::{cell::OnceCell, collections::HashMap, fs, path::PathBuf, rc::Rc};
use std::{cell::LazyCell, collections::HashMap, fs, path::PathBuf, rc::Rc};
use tokio::{sync::Notify, task::JoinHandle};
use tracing::{error, warn};
type FanControlHandle = (Rc<Notify>, JoinHandle<()>);
@ -74,7 +75,8 @@ impl CommonControllerInfo {
pub(crate) fn init_controller(
path: PathBuf,
pci_db: &pciid_parser::Database,
nvml: &OnceCell<Option<Rc<Nvml>>>,
nvml: &LazyCell<Option<Rc<Nvml>>>,
amd_drm: &LazyCell<Option<LibDrmAmdgpu>>,
) -> anyhow::Result<Box<dyn GpuController>> {
let uevent_path = path.join("uevent");
let uevent = fs::read_to_string(uevent_path).context("Could not read 'uevent'")?;
@ -138,27 +140,19 @@ pub(crate) fn init_controller(
};
match common.driver.as_str() {
"amdgpu" | "radeon" => match AmdGpuController::new_from_path(common.clone()) {
Ok(controller) => return Ok(Box::new(controller)),
Err(err) => error!("could not initialize AMD controller: {err:#}"),
},
"amdgpu" | "radeon" => {
match AmdGpuController::new_from_path(common.clone(), amd_drm.as_ref()) {
Ok(controller) => return Ok(Box::new(controller)),
Err(err) => error!("could not initialize AMD controller: {err:#}"),
}
}
"i915" | "xe" => match IntelGpuController::new(common.clone()) {
Ok(controller) => return Ok(Box::new(controller)),
Err(err) => error!("could not initialize Intel controller: {err:#}"),
},
"nvidia" => {
let nvml = nvml.get_or_init(|| match Nvml::init() {
Ok(nvml) => {
info!("Nvidia management library loaded");
Some(Rc::new(nvml))
}
Err(err) => {
error!("could not load Nvidia management library: {err}, Nvidia controls will not be available");
None
}
});
if let Some(nvml) = nvml {
match NvidiaGpuController::new(common.clone(), nvml.clone()) {
if let Some(nvml) = nvml.as_ref().cloned() {
match NvidiaGpuController::new(common.clone(), nvml) {
Ok(controller) => {
return Ok(Box::new(controller));
}
@ -178,7 +172,8 @@ pub(crate) fn init_controller(
// We use the AMD controller as the fallback even for non-AMD devices, it will at least
// display basic device information from the SysFS
Ok(Box::new(
AmdGpuController::new_from_path(common).context("Could initialize fallback controller")?,
AmdGpuController::new_from_path(common, amd_drm.as_ref())
.context("Could initialize fallback controller")?,
))
}

View File

@ -17,13 +17,15 @@ use lact_schema::{
ClocksInfo, DeviceInfo, DeviceListEntry, DeviceStats, FanControlMode, FanOptions, PmfwOptions,
PowerStates, ProfileRule, ProfileWatcherState, ProfilesInfo,
};
use libdrm_amdgpu_sys::LibDrmAmdgpu;
use libflate::gzip;
use nix::libc;
use nvml_wrapper::Nvml;
use os_release::OS_RELEASE;
use pciid_parser::Database;
use serde_json::json;
use std::{
cell::{Cell, OnceCell, RefCell},
cell::{Cell, LazyCell, RefCell},
collections::{BTreeMap, HashMap},
env,
fs::{self, File, Permissions},
@ -919,7 +921,27 @@ fn load_controllers(base_path: &Path) -> anyhow::Result<BTreeMap<String, Box<dyn
}
});
let nvml = OnceCell::new();
let nvml: LazyCell<Option<Rc<Nvml>>> = LazyCell::new(|| match Nvml::init() {
Ok(nvml) => {
info!("Nvidia management library loaded");
Some(Rc::new(nvml))
}
Err(err) => {
error!("could not load Nvidia management library: {err}, Nvidia controls will not be available");
None
}
});
let amd_drm: LazyCell<Option<LibDrmAmdgpu>> = LazyCell::new(|| match LibDrmAmdgpu::new() {
Ok(drm) => {
info!("AMDGPU DRM initialized");
Some(drm)
}
Err(err) => {
error!("failed to initialize AMDGPU DRM: {err}");
None
}
});
for entry in base_path
.read_dir()
@ -935,7 +957,7 @@ fn load_controllers(base_path: &Path) -> anyhow::Result<BTreeMap<String, Box<dyn
trace!("trying gpu controller at {:?}", entry.path());
let device_path = entry.path().join("device");
match init_controller(device_path.clone(), &pci_db, &nvml) {
match init_controller(device_path.clone(), &pci_db, &nvml, &amd_drm) {
Ok(controller) => {
let info = controller.controller_info();
let id = info.build_id();

View File

@ -28,7 +28,7 @@ env:
configure:
steps:
- cmd: curl -o /tmp/install_rust.sh $RUSTUP_URL
- cmd: sh /tmp/install_rust.sh -y --default-toolchain 1.78
- cmd: sh /tmp/install_rust.sh -y --default-toolchain 1.80
- cmd: pacman -Syu --noconfirm
pkg: true
build:

View File

@ -26,7 +26,7 @@ env:
configure:
steps:
- cmd: curl -o /tmp/install_rust.sh $RUSTUP_URL
- cmd: sh /tmp/install_rust.sh -y --default-toolchain 1.78
- cmd: sh /tmp/install_rust.sh -y --default-toolchain 1.80
- cmd: >-
curl -o /tmp/blueprint-compiler.deb http://de.archive.ubuntu.com/ubuntu/pool/universe/b/blueprint-compiler/blueprint-compiler_0.14.0-1_all.deb &&
apt install -y /tmp/blueprint-compiler.deb

View File

@ -28,7 +28,7 @@ env:
configure:
steps:
- cmd: curl -o /tmp/install_rust.sh $RUSTUP_URL
- cmd: sh /tmp/install_rust.sh -y --default-toolchain 1.78
- cmd: sh /tmp/install_rust.sh -y --default-toolchain 1.80
- cmd: >-
curl -o /tmp/blueprint-compiler.deb http://de.archive.ubuntu.com/ubuntu/pool/universe/b/blueprint-compiler/blueprint-compiler_0.14.0-1_all.deb &&
apt install -y /tmp/blueprint-compiler.deb

View File

@ -1,2 +1,2 @@
[toolchain]
channel = "1.78.0"
channel = "1.82.0"