[PATCH 7/7] HACK: simple gputop-like impl in python

Lucas De Marchi lucas.demarchi at intel.com
Tue Apr 16 03:04:54 UTC 2024


Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
---
 pyfdinfo | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100755 pyfdinfo

diff --git a/pyfdinfo b/pyfdinfo
new file mode 100755
index 000000000000..c01d1a399c2f
--- /dev/null
+++ b/pyfdinfo
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+
+import dataclasses
+import pathlib
+import os
+import sys
+import typing
+import time
+
+ at dataclasses.dataclass
+class ClientState():
+    g_stamp : int
+    c_stamp : int
+    c_runtime : int
+    g_runtime : int
+    visited : bool
+    engine: str
+
+def proc_fddir():
+    for child in pathlib.Path('/proc').iterdir():
+        if child.is_dir() and child.name.isnumeric():
+            yield child / "fd"
+
+
+def drm_fd(pfddir):
+    for child in pfddir.iterdir():
+        if not child.is_symlink() or not child.name.isnumeric() or not child.is_char_device():
+            continue
+
+        major = os.major(child.stat(follow_symlinks=True).st_rdev)
+        if major == 226:
+            yield child
+
+
+def drm_clients():
+    for fd in proc_fddir():
+        for dfd in drm_fd(fd):
+            yield dfd.parent.parent / "fdinfo" / dfd.name
+
+
+def sample(clients):
+    for c in clients.values():
+        c.visited = False
+
+    for c in drm_clients():
+        for line in c.read_text().splitlines():
+            # ignore capacity for now
+            if line.startswith("drm-engine-capacity-"):
+                continue
+
+            if not line.startswith("drm-engine-"):
+                continue
+
+            sl = line.split()
+            engine = sl[0][len("drm-engine-"):].split(":")[0]
+
+            cs_new = ClientState(int(sl[1]), int(sl[2]), 0, 0, True, engine)
+            cs = clients.get(c / engine)
+            if cs is None:
+                clients[c / engine] = cs_new
+            else:
+                cs.g_runtime = cs_new.g_stamp - cs.g_stamp
+                cs.c_runtime = cs_new.c_stamp - cs.c_stamp
+
+                cs.g_stamp = cs_new.g_stamp
+                cs.c_stamp = cs_new.c_stamp
+
+                cs.visited = True
+
+            #print(f"{str(c):<25} g={sl[1]:<12} t={sl[2]:16}")
+
+    # the reaper
+    for ck in list(clients.keys()):
+        if not clients[ck].visited:
+            del clients[ck]
+
+
+def clrscr():
+    print("\033[H\033[J")
+
+
+def main():
+    clients = dict()
+
+    sample(clients)
+
+    while True:
+        prev_parent = None
+        sample(clients)
+
+        clrscr()
+
+        for k, c in clients.items():
+            # skip clients with just one sample
+            if not c.visited:
+                continue
+
+            if k.parent != prev_parent:
+                print()
+            prev_parent = k.parent
+
+            g = c.g_runtime or c.g_runtime + 1
+
+            print(f"{str(k):<25} {((c.c_runtime / g) * 100):.2f} %")
+
+        time.sleep(2)
+
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
-- 
2.43.0



More information about the Intel-xe mailing list