From 02e4e400e06dd1a199ed9249da1952358ed1fdcf Mon Sep 17 00:00:00 2001 From: Ilya Zlobintsev Date: Wed, 1 Jan 2025 13:35:38 +0200 Subject: [PATCH] feat: generate drm bindings for xe --- lact-daemon/Cargo.toml | 2 +- lact-daemon/build.rs | 19 +++-- .../src/server/gpu_controller/intel.rs | 39 +++++----- .../src/server/gpu_controller/intel/drm.rs | 2 + .../gpu_controller/intel/drm/bindings.rs | 16 ++++ .../src/server/gpu_controller/intel/drm/xe.rs | 75 +++++++++++++++++++ lact-daemon/wrapper/i915.h | 1 + lact-daemon/wrapper/intel.h | 1 - lact-daemon/wrapper/xe.h | 1 + 9 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 lact-daemon/src/server/gpu_controller/intel/drm.rs create mode 100644 lact-daemon/src/server/gpu_controller/intel/drm/bindings.rs create mode 100644 lact-daemon/src/server/gpu_controller/intel/drm/xe.rs create mode 100644 lact-daemon/wrapper/i915.h delete mode 100644 lact-daemon/wrapper/intel.h create mode 100644 lact-daemon/wrapper/xe.h diff --git a/lact-daemon/Cargo.toml b/lact-daemon/Cargo.toml index c506d96..647274e 100644 --- a/lact-daemon/Cargo.toml +++ b/lact-daemon/Cargo.toml @@ -17,7 +17,7 @@ serde = { workspace = true, features = ["rc"] } serde_with = { workspace = true } serde_json = { workspace = true } tracing-subscriber = { workspace = true } -nix = { workspace = true, features = ["user", "fs"] } +nix = { workspace = true, features = ["user", "fs", "ioctl"] } chrono = { workspace = true } tokio = { workspace = true, features = [ "rt", diff --git a/lact-daemon/build.rs b/lact-daemon/build.rs index df7a400..657db06 100644 --- a/lact-daemon/build.rs +++ b/lact-daemon/build.rs @@ -7,14 +7,21 @@ fn main() { println!("cargo::rerun-if-changed=wrapper/"); - let bindings = bindgen::builder() - .header("wrapper/intel.h") + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + + bindgen::builder() + .header("wrapper/i915.h") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() - .expect("Unable to generate intel bindings"); + .expect("Unable to generate intel bindings") + .write_to_file(out_path.join("i915_bindings.rs")) + .expect("Couldn't write bindings!"); - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("intel_bindings.rs")) + bindgen::builder() + .header("wrapper/xe.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("Unable to generate intel bindings") + .write_to_file(out_path.join("xe_bindings.rs")) .expect("Couldn't write bindings!"); } diff --git a/lact-daemon/src/server/gpu_controller/intel.rs b/lact-daemon/src/server/gpu_controller/intel.rs index 1568c6b..9b4787f 100644 --- a/lact-daemon/src/server/gpu_controller/intel.rs +++ b/lact-daemon/src/server/gpu_controller/intel.rs @@ -1,7 +1,10 @@ +mod drm; + use super::GpuController; use crate::{config, server::vulkan::get_vulkan_info}; use amdgpu_sysfs::gpu_handle::power_profile_mode::PowerProfileModesTable; use anyhow::{anyhow, Context}; +use drm::bindings::i915; use futures::future::LocalBoxFuture; use lact_schema::{ ClocksInfo, ClocksTable, ClockspeedStats, DeviceInfo, DeviceStats, DrmInfo, GpuPciInfo, @@ -16,21 +19,9 @@ use std::{ }; use tracing::{debug, error, info, trace, warn}; -#[allow( - non_upper_case_globals, - non_camel_case_types, - non_snake_case, - unused, - clippy::upper_case_acronyms, - clippy::unreadable_literal -)] -mod drm { - include!(concat!(env!("OUT_DIR"), "/intel_bindings.rs")); -} - enum DriverType { - Xe, I915, + Xe, } pub struct IntelGpuController { @@ -146,9 +137,9 @@ impl GpuController for IntelGpuController { }; let drm_info = DrmInfo { - intel: IntelDrmInfo { - execution_units: self.drm_try(drm::drm_intel_get_eu_total), - subslices: self.drm_try(drm::drm_intel_get_subslice_total), + intel: match self.driver_type { + DriverType::I915 => self.get_drm_info_i915(), + DriverType::Xe => self.get_drm_info_xe(), }, vram_clock_ratio: 1.0, ..Default::default() @@ -228,7 +219,7 @@ impl GpuController for IntelGpuController { clockspeed, vram: VramStats { total: self - .drm_try_2(drm::drm_intel_get_aperture_sizes) + .drm_try_2(i915::drm_intel_get_aperture_sizes) .map(|(_, total)| total as u64), used: None, }, @@ -365,6 +356,20 @@ impl IntelGpuController { } } + fn get_drm_info_i915(&self) -> IntelDrmInfo { + IntelDrmInfo { + execution_units: self.drm_try(i915::drm_intel_get_eu_total), + subslices: self.drm_try(i915::drm_intel_get_subslice_total), + } + } + + fn get_drm_info_xe(&self) -> IntelDrmInfo { + IntelDrmInfo { + execution_units: None, + subslices: None, + } + } + #[cfg_attr(test, allow(unreachable_code, unused_variables))] fn drm_try(&self, f: unsafe extern "C" fn(c_int, *mut T) -> c_int) -> Option { #[cfg(test)] diff --git a/lact-daemon/src/server/gpu_controller/intel/drm.rs b/lact-daemon/src/server/gpu_controller/intel/drm.rs new file mode 100644 index 0000000..d5fb85c --- /dev/null +++ b/lact-daemon/src/server/gpu_controller/intel/drm.rs @@ -0,0 +1,2 @@ +pub mod bindings; +pub mod xe; diff --git a/lact-daemon/src/server/gpu_controller/intel/drm/bindings.rs b/lact-daemon/src/server/gpu_controller/intel/drm/bindings.rs new file mode 100644 index 0000000..ad84f95 --- /dev/null +++ b/lact-daemon/src/server/gpu_controller/intel/drm/bindings.rs @@ -0,0 +1,16 @@ +#![allow( + non_upper_case_globals, + non_camel_case_types, + non_snake_case, + unused, + clippy::upper_case_acronyms, + clippy::unreadable_literal +)] + +pub mod i915 { + include!(concat!(env!("OUT_DIR"), "/i915_bindings.rs")); +} + +pub mod xe { + include!(concat!(env!("OUT_DIR"), "/xe_bindings.rs")); +} diff --git a/lact-daemon/src/server/gpu_controller/intel/drm/xe.rs b/lact-daemon/src/server/gpu_controller/intel/drm/xe.rs new file mode 100644 index 0000000..3d071bf --- /dev/null +++ b/lact-daemon/src/server/gpu_controller/intel/drm/xe.rs @@ -0,0 +1,75 @@ +/*use super::bindings::xe::{drm_xe_device_query, DRM_XE_DEVICE_QUERY, DRM_XE_DEVICE_QUERY_ENGINES}; +use crate::server::gpu_controller::intel::bindings::xe::{ + drm_xe_query_engines, DRM_COMMAND_BASE, DRM_IOCTL_BASE, DRM_XE_DEVICE_QUERY_HWCONFIG, +}; +use nix::{errno::Errno, ioctl_readwrite}; +use std::{ + alloc::{self, dealloc}, + fs::File, + mem, + os::fd::AsRawFd, +}; + +ioctl_readwrite!( + xe_device_query, + DRM_IOCTL_BASE, + DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, + drm_xe_device_query +); + +pub fn query_engines(fd: &File) -> Result<(), Errno> { + unsafe { + let mut query = drm_xe_device_query { + extensions: 0, + query: DRM_XE_DEVICE_QUERY_ENGINES, + size: 0, + data: 0, + reserved: mem::zeroed(), + }; + + xe_device_query(fd.as_raw_fd(), &mut query)?; + + let layout = alloc::Layout::from_size_align( + query.size as usize, + mem::align_of::(), + ) + .unwrap(); + + #[allow(clippy::cast_ptr_alignment)] + let query_engines = alloc::alloc(layout) as *const drm_xe_query_engines; + query.data = query_engines as u64; + + xe_device_query(fd.as_raw_fd(), &mut query)?; + + println!("query data: {query:?}"); + + for engine in (*query_engines) + .engines + .as_slice((*query_engines).num_engines as usize) + { + println!("Engine {engine:?}"); + } + + dealloc(query_engines as *mut u8, layout); + + Ok(()) + } +} + +pub fn query_hwconfig(fd: &File) -> Result<(), Errno> { + unsafe { + let mut query = drm_xe_device_query { + extensions: 0, + query: DRM_XE_DEVICE_QUERY_HWCONFIG, + size: 0, + data: 0, + reserved: mem::zeroed(), + }; + + xe_device_query(fd.as_raw_fd(), &mut query)?; + + println!("{query:?}"); + + Ok(()) + } +}*/ diff --git a/lact-daemon/wrapper/i915.h b/lact-daemon/wrapper/i915.h new file mode 100644 index 0000000..d327f68 --- /dev/null +++ b/lact-daemon/wrapper/i915.h @@ -0,0 +1 @@ +#include "libdrm/intel_bufmgr.h" diff --git a/lact-daemon/wrapper/intel.h b/lact-daemon/wrapper/intel.h deleted file mode 100644 index ec776b4..0000000 --- a/lact-daemon/wrapper/intel.h +++ /dev/null @@ -1 +0,0 @@ -#include "libdrm/intel_bufmgr.h" \ No newline at end of file diff --git a/lact-daemon/wrapper/xe.h b/lact-daemon/wrapper/xe.h new file mode 100644 index 0000000..0b7474d --- /dev/null +++ b/lact-daemon/wrapper/xe.h @@ -0,0 +1 @@ +#include "drm/xe_drm.h"