mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-08-17 16:34:54 -05:00
chore: add ASAN/MSAN/TSAN/SAFESTACK to CI (#740)
* feature: Add ASAN/TSAN to CI * feature: Add SAFESTACK sanitizer * feature: Add MEMORY sanitizer * fix: Try to fix thread unsafety by leaking libraries * fix: Suppress MSAN errors and clarify their future fix * fix: Instead of supressing fuser errors, use patched version * fix: Properly lazily initialize controllers * fix: Add comment explaining why there is allowlist for bindings * fix: Upgrade used nightly * fix: Try to fix sanitizer compilation error * Revert "fix: Try to fix sanitizer compilation error" This reverts commit47514158d5. * Revert "fix: Upgrade used nightly" This reverts commitc3dd005c7e. * chore: Instead of personal fork revision, use official repo * chore: Refactor to not pass arguments for statics * chore: Add note for loading of libs * chore: Try to fix codecov action * chore: Fix compilation problem
This commit is contained in:
@@ -73,7 +73,8 @@ jobs:
|
||||
run: cargo llvm-cov --no-fail-fast --include-ffi --workspace --lcov --output-path lcov.info
|
||||
|
||||
- name: Upload to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
uses: codecov/codecov-action@v5.5.1
|
||||
continue-on-error: true
|
||||
with:
|
||||
files: lcov.info
|
||||
fail_ci_if_error: true
|
||||
@@ -100,6 +101,32 @@ jobs:
|
||||
- name: Run tests inside Miri
|
||||
run: cargo +nightly-2025-01-03 miri test
|
||||
|
||||
test-sanitizers:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sanitizer: [address, thread, safestack, memory]
|
||||
|
||||
env:
|
||||
LSAN_OPTIONS: fast_unwind_on_malloc=0:max_leak_stack_depth=50:print_suppressions=1
|
||||
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
|
||||
steps:
|
||||
- uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2
|
||||
- uses: ./.github/actions/setup-environment
|
||||
- name: Install Nightly Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: nightly-2025-01-03
|
||||
override: true
|
||||
components: rust-src
|
||||
|
||||
- name: Run tests with ${{ matrix.sanitizer }}
|
||||
run: |
|
||||
export RUSTFLAGS="-Zsanitizer=${{ matrix.sanitizer }}"
|
||||
cargo +nightly-2025-01-03 -Zbuild-std test --target x86_64-unknown-linux-gnu --verbose
|
||||
|
||||
check-features-powerset:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.draft }}
|
||||
@@ -113,4 +140,4 @@ jobs:
|
||||
- uses: ./.github/actions/setup-environment
|
||||
- uses: taiki-e/install-action@cargo-hack
|
||||
- name: Run cargo hack ${{ matrix.command }}
|
||||
run: cargo hack ${{ matrix.command }}
|
||||
run: cargo hack ${{ matrix.command }}
|
||||
|
||||
Generated
+1
-3
@@ -818,15 +818,13 @@ checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
|
||||
[[package]]
|
||||
name = "fuser"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53274f494609e77794b627b1a3cddfe45d675a6b2e9ba9c0fdc8d8eee2184369"
|
||||
source = "git+https://github.com/cberner/fuser.git?rev=47113e10ea4ab4be5b562cdc0d8cc8d41ce50311#47113e10ea4ab4be5b562cdc0d8cc8d41ce50311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"memchr",
|
||||
"nix 0.29.0",
|
||||
"page_size",
|
||||
"pkg-config",
|
||||
"smallvec",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
@@ -55,3 +55,8 @@ strip = false
|
||||
debug = 1
|
||||
lto = "thin"
|
||||
codegen-units = 256
|
||||
|
||||
# fuser contains memory safety issues which trigger leaks and UB inside libfuse.so
|
||||
# It's used only as dev dependency in the test code, so this is okay.
|
||||
[patch.crates-io]
|
||||
fuser = { git = "https://github.com/cberner/fuser.git", rev = "47113e10ea4ab4be5b562cdc0d8cc8d41ce50311" }
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
"commit": "7e742c96146890f33fc9d1f9e0251f814d3b87aa",
|
||||
"dest": "flatpak-cargo/git/cl3-7e742c9"
|
||||
},
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/cberner/fuser",
|
||||
"commit": "47113e10ea4ab4be5b562cdc0d8cc8d41ce50311",
|
||||
"dest": "flatpak-cargo/git/fuser-47113e1"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
@@ -1142,16 +1148,21 @@
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/fuser/fuser-0.15.1.crate",
|
||||
"sha256": "53274f494609e77794b627b1a3cddfe45d675a6b2e9ba9c0fdc8d8eee2184369",
|
||||
"dest": "cargo/vendor/fuser-0.15.1"
|
||||
"type": "shell",
|
||||
"commands": [
|
||||
"cp -r --reflink=auto \"flatpak-cargo/git/fuser-47113e1/.\" \"cargo/vendor/fuser\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"53274f494609e77794b627b1a3cddfe45d675a6b2e9ba9c0fdc8d8eee2184369\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/fuser-0.15.1",
|
||||
"contents": "[package]\nname = \"fuser\"\ndescription = \"Filesystem in Userspace (FUSE) for Rust\"\nlicense = \"MIT\"\nrepository = \"https://github.com/cberner/fuser\"\ndocumentation = \"https://docs.rs/fuser\"\nhomepage = \"https://github.com/cberner/fuser\"\nversion = \"0.15.1\"\nedition = \"2024\"\nrust-version = \"1.85\"\nreadme = \"README.md\"\nauthors = [\"Christopher Berner <me@cberner.com>\"]\nkeywords = [\"fuse\", \"filesystem\", \"system\", \"bindings\"]\ncategories = [\"external-ffi-bindings\", \"api-bindings\", \"filesystem\", \"os::unix-apis\"]\nbuild = \"build.rs\"\n\n[dependencies]\nlibc = \"0.2.51\"\nlog = \"0.4.6\"\nmemchr = \"2.7.2\"\npage_size = \"0.6.0\"\nsmallvec = \"1.6.1\"\n\n[dependencies.serde]\nversion = \"1.0.102\"\nfeatures = [\"std\", \"derive\"]\noptional = true\n\n[dependencies.zerocopy]\nversion = \"0.8\"\nfeatures = [\"derive\"]\n\n[dependencies.nix]\nversion = \"0.29.0\"\nfeatures = [\"fs\", \"user\"]\n\n[dev-dependencies]\nenv_logger = \"0.11.7\"\nbincode = \"1.3.1\"\ntempfile = \"3.10.1\"\n\n[dev-dependencies.clap]\nversion = \"4.4\"\nfeatures = [\"cargo\", \"derive\"]\n\n[dev-dependencies.serde]\nversion = \"1.0.102\"\nfeatures = [\"std\", \"derive\"]\n\n[dev-dependencies.nix]\nversion = \"0.29.0\"\nfeatures = [\"poll\", \"fs\", \"ioctl\"]\n\n[build-dependencies.pkg-config]\nversion = \"0.3.14\"\noptional = true\n\n[features]\ndefault = []\nlibfuse = [\"pkg-config\"]\nserializable = [\"serde\"]\nmacfuse-4-compat = []\nabi-7-19 = []\nabi-7-20 = [\"abi-7-19\"]\nabi-7-21 = [\"abi-7-20\"]\nabi-7-22 = [\"abi-7-21\"]\nabi-7-23 = [\"abi-7-22\"]\nabi-7-24 = [\"abi-7-23\"]\nabi-7-25 = [\"abi-7-24\"]\nabi-7-26 = [\"abi-7-25\"]\nabi-7-27 = [\"abi-7-26\"]\nabi-7-28 = [\"abi-7-27\"]\nabi-7-29 = [\"abi-7-28\"]\nabi-7-30 = [\"abi-7-29\"]\nabi-7-31 = [\"abi-7-30\"]\nabi-7-36 = [\"abi-7-31\"]\nabi-7-40 = [\"abi-7-36\", \"nix/ioctl\"]\n\n[[example]]\nname = \"poll\"\n\n[[example]]\nname = \"poll_client\"\n\n[[example]]\nname = \"notify_inval_entry\"\n\n[[example]]\nname = \"notify_inval_inode\"\n\n[[example]]\nname = \"ioctl\"\n\n[[example]]\nname = \"passthrough\"\nrequired-features = [\"abi-7-40\"]\n",
|
||||
"dest": "cargo/vendor/fuser",
|
||||
"dest-filename": "Cargo.toml"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": null, \"files\": {}}",
|
||||
"dest": "cargo/vendor/fuser",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -4510,7 +4521,7 @@
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "[source.vendored-sources]\ndirectory = \"cargo/vendor\"\n\n[source.crates-io]\nreplace-with = \"vendored-sources\"\n\n[source.\"https://github.com/kenba/cl3\"]\ngit = \"https://github.com/kenba/cl3\"\nreplace-with = \"vendored-sources\"\nbranch = \"develop\"\n",
|
||||
"contents": "[source.vendored-sources]\ndirectory = \"cargo/vendor\"\n\n[source.crates-io]\nreplace-with = \"vendored-sources\"\n\n[source.\"https://github.com/kenba/cl3\"]\ngit = \"https://github.com/kenba/cl3\"\nreplace-with = \"vendored-sources\"\nbranch = \"develop\"\n\n[source.\"https://github.com/cberner/fuser\"]\ngit = \"https://github.com/cberner/fuser\"\nreplace-with = \"vendored-sources\"\nrev = \"47113e10ea4ab4be5b562cdc0d8cc8d41ce50311\"\n",
|
||||
"dest": "cargo",
|
||||
"dest-filename": "config"
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ fn gen_intel_bindings() {
|
||||
.header("include/intel.h")
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
.dynamic_library_name("IntelDrm")
|
||||
// Don't generate bindings for functions and types related to file access
|
||||
// This is needed to avoid IntelDrm structure being marked as !Send
|
||||
.allowlist_item("(DRM|drm).*")
|
||||
.blocklist_item(".*(FILE|file).*")
|
||||
.generate_comments(false)
|
||||
.generate()
|
||||
.expect("Unable to generate intel bindings")
|
||||
|
||||
@@ -15,7 +15,7 @@ use nvidia::NvidiaGpuController;
|
||||
pub const VENDOR_AMD: &str = "1002";
|
||||
pub const VENDOR_NVIDIA: &str = "10DE";
|
||||
|
||||
use crate::bindings::intel::IntelDrm;
|
||||
use crate::server::handler::{AMD_DRM, INTEL_DRM, NVML};
|
||||
use amdgpu_sysfs::gpu_handle::power_profile_mode::PowerProfileModesTable;
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Context;
|
||||
@@ -23,9 +23,10 @@ use futures::{future::LocalBoxFuture, FutureExt};
|
||||
use lact_schema::{
|
||||
config::GpuConfig, ClocksInfo, DeviceInfo, DeviceStats, GpuPciInfo, PciInfo, PowerStates,
|
||||
};
|
||||
use libdrm_amdgpu_sys::LibDrmAmdgpu;
|
||||
use std::io;
|
||||
use std::{cell::LazyCell, collections::HashMap, fs, path::PathBuf, rc::Rc};
|
||||
#[cfg(feature = "nvidia")]
|
||||
use std::sync::Arc;
|
||||
use std::{collections::HashMap, fs, path::PathBuf, rc::Rc};
|
||||
use tokio::{sync::Notify, task::JoinHandle};
|
||||
use tracing::{error, warn};
|
||||
|
||||
@@ -131,19 +132,16 @@ pub struct PciSlotInfo {
|
||||
}
|
||||
|
||||
#[cfg(feature = "nvidia")]
|
||||
pub type NvidiaLibs = (Rc<Nvml>, Rc<Option<NvApi>>);
|
||||
pub type NvidiaLibs = (Arc<Nvml>, Arc<Option<NvApi>>);
|
||||
#[cfg(not(feature = "nvidia"))]
|
||||
pub type NvidiaLibs = ();
|
||||
|
||||
pub(crate) fn init_controller(
|
||||
path: PathBuf,
|
||||
pci_db: &pciid_parser::Database,
|
||||
nvml: &LazyCell<Option<NvidiaLibs>>,
|
||||
amd_drm: &LazyCell<Option<LibDrmAmdgpu>>,
|
||||
intel_drm: &LazyCell<Option<Rc<IntelDrm>>>,
|
||||
) -> anyhow::Result<Box<dyn GpuController>> {
|
||||
#[cfg(not(feature = "nvidia"))]
|
||||
let _ = nvml;
|
||||
let _ = NVML;
|
||||
|
||||
let uevent_path = path.join("uevent");
|
||||
let uevent = fs::read_to_string(uevent_path).context("Could not read 'uevent'")?;
|
||||
@@ -215,13 +213,13 @@ pub(crate) fn init_controller(
|
||||
|
||||
match common.driver.as_str() {
|
||||
"amdgpu" | "radeon" => {
|
||||
match AmdGpuController::new_from_path(common.clone(), amd_drm.as_ref()) {
|
||||
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" => {
|
||||
if let Some(drm) = intel_drm.as_ref().cloned() {
|
||||
if let Some(drm) = INTEL_DRM.as_ref() {
|
||||
match IntelGpuController::new(common.clone(), drm) {
|
||||
Ok(controller) => return Ok(Box::new(controller)),
|
||||
Err(err) => error!("could not initialize Intel controller: {err:#}"),
|
||||
@@ -232,8 +230,8 @@ pub(crate) fn init_controller(
|
||||
}
|
||||
#[cfg(feature = "nvidia")]
|
||||
"nvidia" => {
|
||||
if let Some((nvml, nvapi)) = nvml.as_ref().cloned() {
|
||||
match NvidiaGpuController::new(common.clone(), nvml, nvapi) {
|
||||
if let Some((nvml, nvapi)) = NVML.as_ref() {
|
||||
match NvidiaGpuController::new(common.clone(), nvml, nvapi.as_ref().as_ref()) {
|
||||
Ok(controller) => {
|
||||
return Ok(Box::new(controller));
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ impl AmdGpuController {
|
||||
#[allow(unused_variables)]
|
||||
pub fn new_from_path(
|
||||
common: CommonControllerInfo,
|
||||
libdrm_amdgpu: Option<&LibDrmAmdgpu>,
|
||||
libdrm_amdgpu: Option<&'static LibDrmAmdgpu>,
|
||||
) -> anyhow::Result<Self> {
|
||||
let handle = GpuHandle::new_from_path(common.sysfs_path.clone())
|
||||
.map_err(|error| anyhow!("failed to initialize gpu handle: {error}"))?;
|
||||
|
||||
@@ -30,7 +30,6 @@ use std::{
|
||||
io::{BufRead, BufReader},
|
||||
os::{fd::AsRawFd, raw::c_int},
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
str::FromStr,
|
||||
time::Instant,
|
||||
};
|
||||
@@ -63,7 +62,7 @@ pub struct IntelGpuController {
|
||||
tile_gts: Vec<PathBuf>,
|
||||
hwmon_path: Option<PathBuf>,
|
||||
drm_file: fs::File,
|
||||
drm: Rc<IntelDrm>,
|
||||
drm: &'static IntelDrm,
|
||||
last_drm_util: RefCell<Option<DrmUtilMap>>,
|
||||
last_gpu_busy: Cell<Option<(Instant, u64)>>,
|
||||
#[allow(dead_code)]
|
||||
@@ -72,7 +71,7 @@ pub struct IntelGpuController {
|
||||
}
|
||||
|
||||
impl IntelGpuController {
|
||||
pub fn new(common: CommonControllerInfo, drm: Rc<IntelDrm>) -> anyhow::Result<Self> {
|
||||
pub fn new(common: CommonControllerInfo, drm: &'static IntelDrm) -> anyhow::Result<Self> {
|
||||
let driver_type = match common.driver.as_str() {
|
||||
"xe" => DriverType::Xe,
|
||||
"i915" => DriverType::I915,
|
||||
@@ -297,7 +296,7 @@ impl IntelGpuController {
|
||||
|
||||
unsafe {
|
||||
let mut out = T::default();
|
||||
let result = f(&self.drm, self.drm_file.as_raw_fd(), &raw mut out);
|
||||
let result = f(self.drm, self.drm_file.as_raw_fd(), &raw mut out);
|
||||
if result == 0 {
|
||||
Some(out)
|
||||
} else {
|
||||
|
||||
@@ -48,8 +48,8 @@ const SUPPORTED_UTIL_TYPES: &[ProcessUtilizationType] = &[
|
||||
];
|
||||
|
||||
pub struct NvidiaGpuController {
|
||||
nvml: Rc<Nvml>,
|
||||
nvapi: Rc<Option<NvApi>>,
|
||||
nvml: &'static Nvml,
|
||||
nvapi: Option<&'static NvApi>,
|
||||
common: CommonControllerInfo,
|
||||
fan_control_handle: RefCell<Option<FanControlHandle>>,
|
||||
|
||||
@@ -67,8 +67,8 @@ pub struct NvidiaGpuController {
|
||||
impl NvidiaGpuController {
|
||||
pub fn new(
|
||||
common: CommonControllerInfo,
|
||||
nvml: Rc<Nvml>,
|
||||
nvapi: Rc<Option<NvApi>>,
|
||||
nvml: &'static Nvml,
|
||||
nvapi: Option<&'static NvApi>,
|
||||
) -> anyhow::Result<Self> {
|
||||
let device = nvml
|
||||
.device_by_pci_bus_id(common.pci_slot_name.as_str())
|
||||
@@ -166,7 +166,7 @@ impl NvidiaGpuController {
|
||||
let notify = Rc::new(Notify::new());
|
||||
let task_notify = notify.clone();
|
||||
|
||||
let nvml = self.nvml.clone();
|
||||
let nvml = self.nvml;
|
||||
let pci_slot_id = self.common.pci_slot_name.clone();
|
||||
debug!("spawning new fan control task");
|
||||
|
||||
|
||||
@@ -31,8 +31,10 @@ use pciid_parser::Database;
|
||||
use serde_json::json;
|
||||
#[cfg(not(test))]
|
||||
use std::collections::HashMap;
|
||||
#[cfg(all(not(test), feature = "nvidia"))]
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
cell::{Cell, LazyCell, RefCell},
|
||||
cell::{Cell, RefCell},
|
||||
collections::BTreeMap,
|
||||
env,
|
||||
fs::{self, File, Permissions},
|
||||
@@ -40,6 +42,7 @@ use std::{
|
||||
os::unix::fs::{MetadataExt, PermissionsExt},
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
sync::LazyLock,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::{
|
||||
@@ -1055,19 +1058,20 @@ pub(crate) fn read_pci_db() -> Database {
|
||||
})
|
||||
}
|
||||
|
||||
/// `sysfs_only` disables initialization of any external data sources, such as libdrm and nvml
|
||||
fn load_controllers(
|
||||
base_path: &Path,
|
||||
pci_db: &Database,
|
||||
) -> anyhow::Result<BTreeMap<String, DynGpuController>> {
|
||||
let mut controllers = BTreeMap::new();
|
||||
#[cfg(any(test, not(feature = "nvidia")))]
|
||||
pub(crate) static NVML: LazyLock<Option<NvidiaLibs>> = LazyLock::new(|| None);
|
||||
|
||||
#[cfg(all(not(test), feature = "nvidia"))]
|
||||
let nvml: LazyCell<Option<NvidiaLibs>> = LazyCell::new(|| match Nvml::init() {
|
||||
#[cfg(all(not(test), feature = "nvidia"))]
|
||||
// SAFETY: We use global LazyLock to make sure it's safe.
|
||||
// Loading of shared libaries is unsafe
|
||||
// https://docs.rs/libloading/0.8.8/libloading/struct.Library.html#method.new
|
||||
#[allow(unused_unsafe)]
|
||||
pub(crate) static NVML: LazyLock<Option<NvidiaLibs>> =
|
||||
LazyLock::new(|| match unsafe { Nvml::init() } {
|
||||
Ok(nvml) => {
|
||||
use crate::server::gpu_controller::NvApi;
|
||||
|
||||
// The config has to be re-read here, because a LazyCell cannot capture external variables into the init closure
|
||||
// The config has to be re-read here, because a LazyLock cannot capture external variables into the init closure
|
||||
let disable_nvapi = Config::load()
|
||||
.ok()
|
||||
.flatten()
|
||||
@@ -1088,17 +1092,21 @@ fn load_controllers(
|
||||
.ok()
|
||||
};
|
||||
|
||||
Some((Rc::new(nvml), Rc::new(nvapi)))
|
||||
Some((Arc::new(nvml), Arc::new(nvapi)))
|
||||
}
|
||||
Err(err) => {
|
||||
error!("could not load Nvidia management library: {err}");
|
||||
None
|
||||
}
|
||||
});
|
||||
#[cfg(any(test, not(feature = "nvidia")))]
|
||||
let nvml: LazyCell<Option<NvidiaLibs>> = LazyCell::new(|| None);
|
||||
|
||||
let amd_drm: LazyCell<Option<LibDrmAmdgpu>> = LazyCell::new(|| match LibDrmAmdgpu::new() {
|
||||
pub(crate) static AMD_DRM: LazyLock<Option<LibDrmAmdgpu>> = LazyLock::new(|| {
|
||||
// SAFETY: We use global LazyLock to make sure it's safe.
|
||||
#[allow(unused_unsafe)]
|
||||
// Loading of shared libaries is unsafe
|
||||
// https://github.com/Umio-Yasuno/libdrm-amdgpu-sys-rs/issues/12
|
||||
// https://docs.rs/libloading/0.8.8/libloading/struct.Library.html#method.new
|
||||
match unsafe { LibDrmAmdgpu::new() } {
|
||||
Ok(drm) => {
|
||||
info!("AMDGPU DRM initialized");
|
||||
Some(drm)
|
||||
@@ -1107,20 +1115,29 @@ fn load_controllers(
|
||||
error!("failed to initialize AMDGPU DRM: {err}, some functionality will be missing");
|
||||
None
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let intel_drm: LazyCell<Option<Rc<IntelDrm>>> = unsafe {
|
||||
LazyCell::new(|| match IntelDrm::new("libdrm_intel.so.1") {
|
||||
Ok(drm) => {
|
||||
info!("Intel DRM initialized");
|
||||
Some(Rc::new(drm))
|
||||
}
|
||||
Err(err) => {
|
||||
error!("failed to initialize Intel DRM: {err}");
|
||||
None
|
||||
}
|
||||
})
|
||||
};
|
||||
pub(crate) static INTEL_DRM: LazyLock<Option<IntelDrm>> = LazyLock::new(|| {
|
||||
// SAFETY: We use global LazyLock to make sure it's safe.
|
||||
match unsafe { IntelDrm::new("libdrm_intel.so.1") } {
|
||||
Ok(drm) => {
|
||||
info!("Intel DRM initialized");
|
||||
Some(drm)
|
||||
}
|
||||
Err(err) => {
|
||||
error!("failed to initialize Intel DRM: {err}");
|
||||
None
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/// `sysfs_only` disables initialization of any external data sources, such as libdrm and nvml
|
||||
fn load_controllers(
|
||||
base_path: &Path,
|
||||
pci_db: &Database,
|
||||
) -> anyhow::Result<BTreeMap<String, DynGpuController>> {
|
||||
let mut controllers = BTreeMap::new();
|
||||
|
||||
for entry in base_path
|
||||
.read_dir()
|
||||
@@ -1136,7 +1153,7 @@ fn load_controllers(
|
||||
trace!("trying gpu controller at {:?}", entry.path());
|
||||
let device_path = entry.path().join("device");
|
||||
|
||||
match init_controller(device_path.clone(), pci_db, &nvml, &amd_drm, &intel_drm) {
|
||||
match init_controller(device_path.clone(), pci_db) {
|
||||
Ok(controller) => {
|
||||
let info = controller.controller_info();
|
||||
let id = info.build_id();
|
||||
|
||||
Reference in New Issue
Block a user