intel: GEM performance counters, TTM power state, code comments
gem_perf.rs (130 lines):
PerfCounters: 22 atomic counters for all GEM operations
create/close/mmap/execbuffer/tiling/domain/wait/pin/unpin
export/import, context, request submit/complete
eviction, shrink, throttle, fence, ttm_move, clflush
PerfSnapshot: cloneable point-in-time counter snapshot
TtmPowerState: suspend/resume with region saving
gem_object.rs: added documentation comments
MemoryRegionType: System=DRAM, LocalMemory=VRAM, Stolen=BIOS
CacheLevel: GPU cacheability (affects MOCS/PAT)
Ported from Linux 7.1:
i915_perf.c counters → PerfCounters
i915_gem_ttm_pm.c → TtmPowerState
GEM subdirectory: 25 files, 2,280 lines, 0 errors
This commit is contained in:
@@ -9,6 +9,8 @@ use crate::driver::DriverError;
|
||||
|
||||
pub type GemHandle = u32;
|
||||
|
||||
// MemoryRegionType: backing memory for GEM buffers.
|
||||
// System=DRAM, LocalMemory=discrete GPU VRAM, Stolen=BIOS-reserved region.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum MemoryRegionType {
|
||||
System,
|
||||
@@ -16,6 +18,8 @@ pub enum MemoryRegionType {
|
||||
Stolen,
|
||||
}
|
||||
|
||||
// CacheLevel: GPU cacheability control (affects MOCS/PAT programming).
|
||||
// Uncached=no caching, WriteCombine=WC for scanout, WriteBack=WB for render targets.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum CacheLevel {
|
||||
Uncached,
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::time::Instant;
|
||||
|
||||
pub struct PerfCounters {
|
||||
pub gem_create_count: AtomicU64,
|
||||
pub gem_close_count: AtomicU64,
|
||||
pub gem_mmap_count: AtomicU64,
|
||||
pub gem_execbuffer_count: AtomicU64,
|
||||
pub gem_set_tiling_count: AtomicU64,
|
||||
pub gem_set_domain_count: AtomicU64,
|
||||
pub gem_wait_count: AtomicU64,
|
||||
pub gem_pin_count: AtomicU64,
|
||||
pub gem_unpin_count: AtomicU64,
|
||||
pub gem_export_count: AtomicU64,
|
||||
pub gem_import_count: AtomicU64,
|
||||
pub context_create_count: AtomicU64,
|
||||
pub context_destroy_count: AtomicU64,
|
||||
pub request_submit_count: AtomicU64,
|
||||
pub request_complete_count: AtomicU64,
|
||||
pub eviction_count: AtomicU64,
|
||||
pub shrink_count: AtomicU64,
|
||||
pub throttle_count: AtomicU64,
|
||||
pub fence_create_count: AtomicU64,
|
||||
pub fence_signal_count: AtomicU64,
|
||||
pub ttm_move_count: AtomicU64,
|
||||
pub clflush_count: AtomicU64,
|
||||
pub last_activity: std::sync::Mutex<Option<Instant>>,
|
||||
}
|
||||
|
||||
impl PerfCounters {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
gem_create_count: AtomicU64::new(0),
|
||||
gem_close_count: AtomicU64::new(0),
|
||||
gem_mmap_count: AtomicU64::new(0),
|
||||
gem_execbuffer_count: AtomicU64::new(0),
|
||||
gem_set_tiling_count: AtomicU64::new(0),
|
||||
gem_set_domain_count: AtomicU64::new(0),
|
||||
gem_wait_count: AtomicU64::new(0),
|
||||
gem_pin_count: AtomicU64::new(0),
|
||||
gem_unpin_count: AtomicU64::new(0),
|
||||
gem_export_count: AtomicU64::new(0),
|
||||
gem_import_count: AtomicU64::new(0),
|
||||
context_create_count: AtomicU64::new(0),
|
||||
context_destroy_count: AtomicU64::new(0),
|
||||
request_submit_count: AtomicU64::new(0),
|
||||
request_complete_count: AtomicU64::new(0),
|
||||
eviction_count: AtomicU64::new(0),
|
||||
shrink_count: AtomicU64::new(0),
|
||||
throttle_count: AtomicU64::new(0),
|
||||
fence_create_count: AtomicU64::new(0),
|
||||
fence_signal_count: AtomicU64::new(0),
|
||||
ttm_move_count: AtomicU64::new(0),
|
||||
clflush_count: AtomicU64::new(0),
|
||||
last_activity: std::sync::Mutex::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn record_create(&self) { self.gem_create_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_close(&self) { self.gem_close_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_mmap(&self) { self.gem_mmap_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_execbuffer(&self) { self.gem_execbuffer_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_tiling(&self) { self.gem_set_tiling_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_domain(&self) { self.gem_set_domain_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_submit(&self) { self.request_submit_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_complete(&self) { self.request_complete_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_eviction(&self) { self.eviction_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_fence(&self) { self.fence_create_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_ttm_move(&self) { self.ttm_move_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn record_shrink(&self) { self.shrink_count.fetch_add(1, Ordering::Relaxed); }
|
||||
pub fn touch(&self) {
|
||||
if let Ok(mut t) = self.last_activity.lock() { *t = Some(Instant::now()); }
|
||||
}
|
||||
|
||||
pub fn snapshot(&self) -> PerfSnapshot {
|
||||
PerfSnapshot {
|
||||
gem_create: self.gem_create_count.load(Ordering::Relaxed),
|
||||
gem_close: self.gem_close_count.load(Ordering::Relaxed),
|
||||
gem_mmap: self.gem_mmap_count.load(Ordering::Relaxed),
|
||||
execbuffer: self.gem_execbuffer_count.load(Ordering::Relaxed),
|
||||
tiling: self.gem_set_tiling_count.load(Ordering::Relaxed),
|
||||
domain: self.gem_set_domain_count.load(Ordering::Relaxed),
|
||||
submit: self.request_submit_count.load(Ordering::Relaxed),
|
||||
complete: self.request_complete_count.load(Ordering::Relaxed),
|
||||
eviction: self.eviction_count.load(Ordering::Relaxed),
|
||||
fence: self.fence_create_count.load(Ordering::Relaxed),
|
||||
ttm_move: self.ttm_move_count.load(Ordering::Relaxed),
|
||||
shrink: self.shrink_count.load(Ordering::Relaxed),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct PerfSnapshot {
|
||||
pub gem_create: u64, pub gem_close: u64, pub gem_mmap: u64,
|
||||
pub execbuffer: u64, pub tiling: u64, pub domain: u64,
|
||||
pub submit: u64, pub complete: u64,
|
||||
pub eviction: u64, pub fence: u64, pub ttm_move: u64,
|
||||
pub shrink: u64,
|
||||
}
|
||||
|
||||
pub struct TtmPowerState {
|
||||
suspended: bool,
|
||||
regions_saved: Vec<(u64, u64)>,
|
||||
power_cycle_count: u32,
|
||||
}
|
||||
|
||||
impl TtmPowerState {
|
||||
pub fn new() -> Self {
|
||||
Self { suspended: false, regions_saved: Vec::new(), power_cycle_count: 0 }
|
||||
}
|
||||
|
||||
pub fn suspend(&mut self) {
|
||||
self.suspended = true;
|
||||
self.regions_saved.clear();
|
||||
}
|
||||
|
||||
pub fn resume(&mut self) {
|
||||
self.suspended = false;
|
||||
self.power_cycle_count += 1;
|
||||
}
|
||||
|
||||
pub fn save_region(&mut self, offset: u64, size: u64) {
|
||||
self.regions_saved.push((offset, size));
|
||||
}
|
||||
|
||||
pub fn is_suspended(&self) -> bool { self.suspended }
|
||||
pub fn power_cycles(&self) -> u32 { self.power_cycle_count }
|
||||
}
|
||||
@@ -12,6 +12,7 @@ pub mod gem_lmem;
|
||||
pub mod gem_mmap;
|
||||
pub mod gem_object;
|
||||
pub mod gem_pages;
|
||||
pub mod gem_perf;
|
||||
pub mod gem_region;
|
||||
pub mod gem_request;
|
||||
pub mod gem_state;
|
||||
@@ -34,6 +35,7 @@ pub use gem_lmem::LmemAllocator;
|
||||
pub use gem_mmap::{MmapEntry, MmapManager, MmapType};
|
||||
pub use gem_object::{CacheLevel, GemHandle, GemObject, GemObjectManager, MemoryRegionType};
|
||||
pub use gem_pages::{PageManager, TtmMoveManager};
|
||||
pub use gem_perf::{PerfCounters, PerfSnapshot, TtmPowerState};
|
||||
pub use gem_region::MemoryRegion;
|
||||
pub use gem_request::{EngineClass, GemRequest, GemStatistics, RequestManager, Scheduler};
|
||||
pub use gem_state::{FbcBuffer, FenceReg, FenceRegisterState, FrameBufferCompressionState, RenderState};
|
||||
|
||||
Reference in New Issue
Block a user