Add gems field to TyrDebugFSData; populate gems in Firmware::new and
register gems read-only file under debugfs per-device directory.

Signed-off-by: Alvin Sun <[email protected]>
---
 drivers/gpu/drm/tyr/debugfs.rs | 93 +++++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/tyr/driver.rs  | 10 +++--
 drivers/gpu/drm/tyr/fw.rs      |  2 +
 3 files changed, 101 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tyr/debugfs.rs b/drivers/gpu/drm/tyr/debugfs.rs
index edbdb83a5b132..d0e9e268aeac2 100644
--- a/drivers/gpu/drm/tyr/debugfs.rs
+++ b/drivers/gpu/drm/tyr/debugfs.rs
@@ -8,14 +8,19 @@
     debugfs,
     device::Core,
     drm,
-    drm::gem::IntoGEMObject,
+    drm::gem::{
+        BaseObject,
+        IntoGEMObject, //
+    },
     fmt,
     fmt::Write,
+    impl_flags,
     platform,
     prelude::*,
     revocable::LazyRevocable,
     str::CString,
     sync::{
+        aref::ARef,
         hazptr::HazptrCtx,
         Arc,
         ArcBorrow,
@@ -24,15 +29,100 @@
 };
 
 use crate::driver::TyrDrmDriver;
+use crate::gem::Bo;
 use crate::vm::Vm;
 
 pub(crate) static DEBUGFS_ROOT: LazyRevocable<debugfs::Dir> = 
LazyRevocable::new();
 
+impl_flags!(
+    #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
+    struct BoStateFlags(u32);
+
+    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+    enum BoStateFlag {
+        Imported = 1 << 0,
+        Exported = 1 << 1,
+    }
+);
+
+/// Writes per-BO debug information for the "gems" debugfs file.
+fn show_bo(bo: &Bo, f: &mut impl Write) -> core::fmt::Result {
+    let name: i32 = bo.name();
+    let refcount: u32 = bo.refcount();
+    let size: usize = bo.size();
+    let resident_size: usize = bo.resident_size();
+    let mmap_offset = bo.mmap_offset();
+    let mut gem_state_flags = BoStateFlags::default();
+
+    if bo.is_imported() {
+        gem_state_flags |= BoStateFlag::Imported;
+    }
+    if bo.is_exported() {
+        gem_state_flags |= BoStateFlag::Exported;
+    }
+
+    writeln!(
+        f,
+        "{:<16}{:<16}{:<16}{:<16}0x{:<16x}0x{:<8x}",
+        name,
+        refcount,
+        size,
+        resident_size,
+        mmap_offset,
+        u32::from(gem_state_flags),
+    )
+}
+
+fn show_gems(data: &Arc<TyrDebugFSData>, f: &mut fmt::Formatter<'_>) -> 
core::fmt::Result {
+    writeln!(
+        f,
+        "GEM state flags: {:?} (0x{:x}), {:?} (0x{:x})",
+        BoStateFlag::Imported,
+        BoStateFlag::Imported as u32,
+        BoStateFlag::Exported,
+        BoStateFlag::Exported as u32,
+    )?;
+    writeln!(
+        f,
+        "global-name     refcount        size            resident-size   
file-offset       state",
+    )?;
+    writeln!(
+        f,
+        
"--------------------------------------------------------------------------------------------",
+    )?;
+
+    let mut total_size: usize = 0;
+    let mut total_resident: usize = 0;
+    let mut total_reclaimable: usize = 0;
+    let gems = data.gems.lock();
+    for bo in gems.iter() {
+        total_size += bo.size();
+        total_resident += bo.resident_size();
+        if bo.madv() > 0 {
+            total_reclaimable += bo.resident_size();
+        }
+        show_bo(bo, f)?;
+    }
+
+    writeln!(
+        f,
+        
"============================================================================================",
+    )?;
+    writeln!(
+        f,
+        "Total size: {}, Total resident: {}, Total reclaimable: {}",
+        total_size, total_resident, total_reclaimable,
+    )?;
+    Ok(())
+}
+
 /// Per-device debugfs data.
 #[pin_data]
 pub(crate) struct TyrDebugFSData {
     #[pin]
     pub(crate) vms: Mutex<KVec<Arc<Vm>>>,
+    #[pin]
+    pub(crate) gems: Mutex<KVec<ARef<Bo>>>,
 }
 
 /// Writes VM debug information for the "gpuvas" debugfs file.
@@ -93,6 +183,7 @@ pub(crate) fn debugfs_init(
     let debugfs_data: Arc<TyrDebugFSData> = debugfs_data.into();
     let scope_init = root_dir.scope(debugfs_data, &dir_name, |data, dir| {
         dir.read_callback_file(c"gpuvas", data, &show_gpuvas);
+        dir.read_callback_file(c"gems", data, &show_gems);
     });
 
     kernel::devres::register(pdev.as_ref(), scope_init, GFP_KERNEL)
diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs
index e1d5e908de876..a6d8760070d44 100644
--- a/drivers/gpu/drm/tyr/driver.rs
+++ b/drivers/gpu/drm/tyr/driver.rs
@@ -154,9 +154,13 @@ fn probe(
         let platform: ARef<platform::Device> = pdev.into();
 
         let mmu = Mmu::new(pdev, iomem.as_arc_borrow(), &gpu_info)?;
-        let debugfs_data = Arc::pin_init(try_pin_init!(TyrDebugFSData {
-            vms <- new_mutex!(KVec::new()),
-        }), GFP_KERNEL)?;
+        let debugfs_data = Arc::pin_init(
+            try_pin_init!(TyrDebugFSData {
+                vms <- new_mutex!(KVec::new()),
+                gems <- new_mutex!(KVec::new()),
+            }),
+            GFP_KERNEL,
+        )?;
         let debugfs_data_clone = debugfs_data.clone();
 
         let firmware = Firmware::new(
diff --git a/drivers/gpu/drm/tyr/fw.rs b/drivers/gpu/drm/tyr/fw.rs
index c46320bb54516..4d5efa79a7348 100644
--- a/drivers/gpu/drm/tyr/fw.rs
+++ b/drivers/gpu/drm/tyr/fw.rs
@@ -222,6 +222,8 @@ pub(crate) fn new(
                 parsed.vm_map_flags,
             )?;
 
+            debugfs_data.gems.lock().push(mem.bo.clone(), GFP_KERNEL)?;
+
             let section_start = parsed.data_range.start as usize;
             let section_end = parsed.data_range.end as usize;
             let mut data = KVec::new();

-- 
2.43.0


Reply via email to