44 */
55
66public class Monitor.ProcessDRM {
7- /**
7+
8+ private string driver;
9+
10+ /**
811 * Time spent busy in nanoseconds by the render engine executing
912 * workloads from the last time it was read
1013 */
1114 private uint64 last_engine_render;
1215 private uint64 last_engine_gfx;
1316
17+ private uint64 engine_gfx;
18+ private uint64 engine_render;
19+
20+ // Xe driver related fields
21+ private uint64 cycles_rcs = 0 ;
22+ private uint64 cycles_rcs_total = 0 ;
23+ private uint64 cycles_bcs = 0 ;
24+ private uint64 cycles_bcs_total = 0 ;
25+ private uint64 cycles_vcs = 0 ;
26+ private uint64 cycles_vcs_total = 0 ;
27+ private uint64 cycles_ccs = 0 ;
28+ private uint64 cycles_ccs_total = 0 ;
29+ private uint64 cycles_vecs = 0 ;
30+ private uint64 cycles_vecs_total = 0 ;
31+
32+ private uint64 delta_rcs = 0 ;
33+ private uint64 delta_total_rcs = 0 ;
34+
35+ private uint64 delta_ccs = 0 ;
36+ private uint64 delta_total_ccs = 0 ;
1437
1538 public double gpu_percentage { get ; private set ; }
1639
1740 private int pid;
1841 private int update_interval;
42+ private Gee . ArrayList<GLib . File > drm_files;
1943
2044 public ProcessDRM (int pid , int update_interval ) {
2145 this . pid = pid;
2246 this . update_interval = update_interval;
2347
2448 last_engine_render = 0 ;
2549 last_engine_gfx = 0 ;
50+
51+ get_drm_files ();
2652 }
2753
28- public void update () {
54+ private void get_drm_files () {
2955 string path_fdinfo = " /proc/%d /fdinfo" . printf (pid);
3056 string path_fd = " /proc/%d /fd" . printf (pid);
3157
32-
33- var drm_files = new Gee .ArrayList<GLib . File ?> ();
58+ drm_files = new Gee .ArrayList<GLib . File ?> ();
3459
3560 try {
3661 Dir dir = Dir . open (path_fdinfo, 0 );
@@ -56,6 +81,7 @@ public class Monitor.ProcessDRM {
5681 if (is_drm) {
5782 var drm_file = File . new_for_path (path);
5883 drm_files. add (drm_file);
84+ debug (" Found DRM file: %s " , path);
5985 }
6086 }
6187 } catch (FileError err) {
@@ -64,26 +90,23 @@ public class Monitor.ProcessDRM {
6490 warning (err. message);
6591 }
6692 }
93+ // debug ("Found %d drm fdinfo files for pid %d", drm_files.size, pid);
94+ }
95+
96+ public void update () {
97+ if (drm_files. size == 0 ) {
98+ gpu_percentage = 0 ;
99+ return ;
100+ }
67101
68102 foreach (var drm_file in drm_files) {
69103 try {
104+ debug (" Reading fdinfo from: %s " , drm_file. get_path ());
70105 var dis = new DataInputStream (drm_file. read ());
71106 string ? line;
72107
73108 while ((line = dis. read_line ()) != null ) {
74- var splitted_line = line. split (" :" );
75- switch (splitted_line[0 ]) {
76- case " drm-engine-gfx" :
77- update_engine (splitted_line[1 ], ref last_engine_gfx);
78- break ;
79- // for i915 there is only drm-engine-render to check
80- case " drm-engine-render" :
81- update_engine (splitted_line[1 ], ref last_engine_render);
82- break ;
83- default:
84- // Ignore other entries
85- break ;
86- }
109+ parse_drm_line (line);
87110 }
88111 } catch (Error err) {
89112 if (! (err is FileError . ACCES )) {
@@ -92,16 +115,39 @@ public class Monitor.ProcessDRM {
92115 }
93116 break ;
94117 }
118+
119+ switch (driver) {
120+ case " i915" :
121+ update_engine (ref engine_render, ref last_engine_render);
122+ break ;
123+ case " xe" :
124+ var pre = (float ) delta_rcs / (float ) delta_total_rcs;
125+ gpu_percentage = delta_total_rcs > 0 ? 100 * (pre. clamp (0.0f , 1.0f )) : 0 ;
126+ break ;
127+ case " amdgpu" :
128+ update_engine (ref engine_gfx, ref last_engine_gfx);
129+ break ;
130+ default:
131+ // Handle default case
132+ break ;
133+ }
134+
95135 }
96136
97- private void update_engine (string line , ref uint64 last_engine ) {
98- var engine = uint64 . parse (line. strip (). split (" " )[0 ]);
137+ private void update_engine (ref uint64 engine , ref uint64 last_engine ) {
99138 if (last_engine != 0 ) {
100139 gpu_percentage = calculate_percentage (engine, last_engine, update_interval);
101140 }
102141 last_engine = engine;
103142 }
104143
144+ private void update_cycles (string line , ref uint64 last_cycles , ref uint64 delta ) {
145+ var cycles = uint64 . parse (line. strip (). split (" " )[0 ]);
146+ delta = cycles > last_cycles ? cycles - last_cycles : 0 ;
147+ // debug ("pid %d Cycles: %llu, Last Cycles: %llu, Delta: %llu", pid, cycles, last_cycles, delta);
148+ last_cycles = cycles;
149+ }
150+
105151 private static double calculate_percentage (uint64 engine , uint64 last_engine , int interval ) {
106152 // Since values in the files are in nanoseconds, it is also needed to convert interval to nanoseconds (10^9)
107153 return 100 * ((double ) (engine - last_engine)) / (interval * 1e9 );
@@ -115,4 +161,38 @@ public class Monitor.ProcessDRM {
115161 return ret == 0 && (stat. st_mode & Posix . S_IFMT ) == Posix . S_IFCHR && Posix . major (stat. st_rdev) == 226 ;
116162 }
117163
164+ private void parse_drm_line (string line ) {
165+ var splitted_line = line. split (" :" );
166+ switch (splitted_line[0 ]) {
167+ case " drm-driver" :
168+ driver = splitted_line[1 ]. strip ();
169+ break ;
170+ case " drm-engine-gfx" :
171+ engine_gfx = uint64 . parse (splitted_line[1 ]. strip (). split (" " )[0 ]);
172+ break ;
173+ // for i915 there is only drm-engine-render to check
174+ case " drm-engine-render" :
175+ engine_render = uint64 . parse (splitted_line[1 ]. strip (). split (" " )[0 ]);
176+ break ;
177+ // Xe driver specific entries
178+ case " drm-cycles-ccs" :
179+ update_cycles (splitted_line[1 ], ref cycles_ccs, ref delta_ccs);
180+ break ;
181+ case " drm-total-cycles-ccs" :
182+ update_cycles (splitted_line[1 ], ref cycles_ccs_total, ref delta_total_ccs);
183+ break ;
184+ case " drm-cycles-rcs" :
185+ // debug ("path: %s, line: %s", drm_file.get_path (), line);
186+ update_cycles (splitted_line[1 ], ref cycles_rcs, ref delta_rcs);
187+ break ;
188+ case " drm-total-cycles-rcs" :
189+ // debug ("path: %s, line: %s", drm_file.get_path (), line);
190+ update_cycles (splitted_line[1 ], ref cycles_rcs_total, ref delta_total_rcs);
191+ break ;
192+ default:
193+ // Ignore other entries
194+ break ;
195+ }
196+ }
197+
118198}
0 commit comments