libdrm_amdgpu_sys/amdgpu/
ras_features.rs

1use std::fmt;
2use std::path::PathBuf;
3use std::io;
4
5#[derive(Debug, Clone, Copy)]
6pub struct RasEnabledFeatures(u64);
7
8impl RasEnabledFeatures {
9    pub fn new(val: u64) -> Self {
10        Self(val)
11    }
12
13    pub fn is_supported(&self, ras: RasBlock) -> bool {
14        (self.0 & ras as u64) != 0
15    }
16
17    pub fn mask_value(&self) -> u64 {
18        self.0
19    }
20}
21
22use crate::AMDGPU::DeviceHandle;
23use crate::bindings::AMDGPU_INFO_RAS_ENABLED_FEATURES;
24
25impl DeviceHandle {
26    pub fn ras_enabled_features(&self) -> Result<RasEnabledFeatures, i32> {
27        let v = Self::query(self, AMDGPU_INFO_RAS_ENABLED_FEATURES)?;
28
29        Ok(RasEnabledFeatures::new(v))
30    }
31}
32
33use crate::bindings::{
34    AMDGPU_INFO_RAS_ENABLED_UMC,
35    AMDGPU_INFO_RAS_ENABLED_SDMA,
36    AMDGPU_INFO_RAS_ENABLED_GFX,
37    AMDGPU_INFO_RAS_ENABLED_MMHUB,
38    AMDGPU_INFO_RAS_ENABLED_ATHUB,
39    AMDGPU_INFO_RAS_ENABLED_PCIE,
40    AMDGPU_INFO_RAS_ENABLED_HDP,
41    AMDGPU_INFO_RAS_ENABLED_XGMI,
42    AMDGPU_INFO_RAS_ENABLED_DF,
43    AMDGPU_INFO_RAS_ENABLED_SMN,
44    AMDGPU_INFO_RAS_ENABLED_SEM,
45    AMDGPU_INFO_RAS_ENABLED_MP0,
46    AMDGPU_INFO_RAS_ENABLED_MP1,
47    AMDGPU_INFO_RAS_ENABLED_FUSE,
48};
49
50#[derive(Debug, Clone, Copy)]
51#[repr(u32)]
52pub enum RasBlock {
53    UMC = AMDGPU_INFO_RAS_ENABLED_UMC,
54    SDMA = AMDGPU_INFO_RAS_ENABLED_SDMA,
55    GFX = AMDGPU_INFO_RAS_ENABLED_GFX,
56    MMHUB = AMDGPU_INFO_RAS_ENABLED_MMHUB,
57    ATHUB = AMDGPU_INFO_RAS_ENABLED_ATHUB,
58    PCIE = AMDGPU_INFO_RAS_ENABLED_PCIE,
59    HDP = AMDGPU_INFO_RAS_ENABLED_HDP,
60    XGMI = AMDGPU_INFO_RAS_ENABLED_XGMI,
61    DF = AMDGPU_INFO_RAS_ENABLED_DF,
62    SMN = AMDGPU_INFO_RAS_ENABLED_SMN,
63    SEM = AMDGPU_INFO_RAS_ENABLED_SEM,
64    MP0 = AMDGPU_INFO_RAS_ENABLED_MP0,
65    MP1 = AMDGPU_INFO_RAS_ENABLED_MP1,
66    FUSE = AMDGPU_INFO_RAS_ENABLED_FUSE,
67}
68
69impl RasBlock {
70    /// ref: drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
71    pub fn to_sysfs_name_prefix(&self) -> &str {
72        match self {
73            Self::UMC => "umc",
74            Self::SDMA => "sdma",
75            Self::GFX => "gfx",
76            Self::MMHUB => "mmhub",
77            Self::ATHUB => "athub",
78            Self::PCIE => "pcie_bif",
79            Self::HDP => "hdp",
80            Self::XGMI => "xgmi_wafl",
81            Self::DF => "df",
82            Self::SMN => "smn",
83            Self::SEM => "sem",
84            Self::MP0 => "mp0",
85            Self::MP1 => "mp1",
86            Self::FUSE => "fuse",
87        }
88    }
89}
90
91impl fmt::Display for RasBlock {
92    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93        write!(f, "{:?}", self)
94    }
95}
96
97#[derive(Debug, Clone)]
98pub struct RasErrorCount {
99    pub uncorrected: u64,
100    pub corrected: u64,
101}
102
103impl RasErrorCount {
104    pub fn get_from_sysfs_with_ras_block<P: Into<PathBuf>>(
105        sysfs_path: P,
106        ras_block: RasBlock,
107    ) -> io::Result<Self> {
108        let s = {
109            let pre = ras_block.to_sysfs_name_prefix();
110            let path = sysfs_path.into().join("ras").join(format!("{pre}_err_count"));
111
112            std::fs::read_to_string(path)?
113        };
114
115        let mut lines = s.lines();
116
117        let [ue, ce] = [lines.next(), lines.next()].map(|line| -> io::Result<u64> {
118            const PRE: usize = "ue: ".len();
119
120            line
121                .and_then(|l| l.get(PRE..))
122                .and_then(|s| s.parse().ok())
123                .ok_or(io::Error::other("Parse Error"))
124        });
125
126        Ok(Self { uncorrected: ue?, corrected: ce? })
127    }
128}