diff options
author | Gareth Hughes | 2001-02-15 02:12:14 -0600 |
---|---|---|
committer | Gareth Hughes | 2001-02-15 02:12:14 -0600 |
commit | 360475376c5a597caf4a981c934a6b0d783fa94d (patch) | |
tree | 433f6970813deb74a2c8e1636b772a1f8567b267 /tests/dristat.c | |
parent | 38c22bc4883ac201bde7f5f130a72acd1be68ec5 (diff) | |
download | external-libdrm-360475376c5a597caf4a981c934a6b0d783fa94d.tar.gz external-libdrm-360475376c5a597caf4a981c934a6b0d783fa94d.tar.xz external-libdrm-360475376c5a597caf4a981c934a6b0d783fa94d.zip |
Merge mga-1-0-0-branch into trunk.
Diffstat (limited to 'tests/dristat.c')
-rw-r--r-- | tests/dristat.c | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/tests/dristat.c b/tests/dristat.c new file mode 100644 index 00000000..f429efd3 --- /dev/null +++ b/tests/dristat.c | |||
@@ -0,0 +1,473 @@ | |||
1 | /* dristat.c -- | ||
2 | * Created: Mon Jan 15 05:05:07 2001 by faith@acm.org | ||
3 | * | ||
4 | * Copyright 2000 VA Linux Systems, Inc., Fremont, California. | ||
5 | * All Rights Reserved. | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
8 | * copy of this software and associated documentation files (the "Software"), | ||
9 | * to deal in the Software without restriction, including without limitation | ||
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
11 | * and/or sell copies of the Software, and to permit persons to whom the | ||
12 | * Software is furnished to do so, subject to the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice (including the next | ||
15 | * paragraph) shall be included in all copies or substantial portions of the | ||
16 | * Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
21 | * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
22 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
23 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
24 | * DEALINGS IN THE SOFTWARE. | ||
25 | * | ||
26 | * Authors: Rickard E. (Rik) Faith <faith@valinux.com> | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <stdio.h> | ||
31 | #include <stdlib.h> | ||
32 | #include <unistd.h> | ||
33 | #include "../../../xf86drm.h" | ||
34 | #include "../xf86drmRandom.c" | ||
35 | #include "../xf86drmHash.c" | ||
36 | #include "../xf86drm.c" | ||
37 | |||
38 | #define DRM_DIR_NAME "/dev/dri" | ||
39 | #define DRM_DEV_NAME "%s/card%d" | ||
40 | |||
41 | #define DRM_VERSION 0x00000001 | ||
42 | #define DRM_MEMORY 0x00000002 | ||
43 | #define DRM_CLIENTS 0x00000004 | ||
44 | #define DRM_STATS 0x00000008 | ||
45 | |||
46 | typedef struct drmStatsS { | ||
47 | unsigned long count; | ||
48 | struct { | ||
49 | unsigned long value; | ||
50 | const char *long_format; | ||
51 | const char *long_name; | ||
52 | const char *rate_format; | ||
53 | const char *rate_name; | ||
54 | int isvalue; | ||
55 | const char *mult_names; | ||
56 | int mult; | ||
57 | int verbose; | ||
58 | } data[15]; | ||
59 | } drmStatsT; | ||
60 | |||
61 | static void getversion(int fd) | ||
62 | { | ||
63 | drmVersionPtr version; | ||
64 | |||
65 | version = drmGetVersion(fd); | ||
66 | if (version) { | ||
67 | printf(" Version information:\n"); | ||
68 | printf(" Name: %s\n", version->name ? version->name : "?"); | ||
69 | printf(" Version: %d.%d.%d\n", | ||
70 | version->version_major, | ||
71 | version->version_minor, | ||
72 | version->version_patchlevel); | ||
73 | printf(" Date: %s\n", version->date ? version->date : "?"); | ||
74 | printf(" Desc: %s\n", version->desc ? version->desc : "?"); | ||
75 | drmFreeVersion(version); | ||
76 | } else { | ||
77 | printf(" No version information available\n"); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | typedef struct { | ||
82 | unsigned long offset; /* Requested physical address (0 for SAREA)*/ | ||
83 | unsigned long size; /* Requested physical size (bytes) */ | ||
84 | drm_map_type_t type; /* Type of memory to map */ | ||
85 | drm_map_flags_t flags; /* Flags */ | ||
86 | void *handle; /* User-space: "Handle" to pass to mmap */ | ||
87 | /* Kernel-space: kernel-virtual address */ | ||
88 | int mtrr; /* MTRR slot used */ | ||
89 | /* Private data */ | ||
90 | } drmVmRec, *drmVmPtr; | ||
91 | |||
92 | int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size, | ||
93 | drmMapType *type, drmMapFlags *flags, drmHandle *handle, | ||
94 | int *mtrr) | ||
95 | { | ||
96 | drm_map_t map; | ||
97 | |||
98 | map.offset = idx; | ||
99 | if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno; | ||
100 | *offset = map.offset; | ||
101 | *size = map.size; | ||
102 | *type = map.type; | ||
103 | *flags = map.flags; | ||
104 | *handle = (unsigned long)map.handle; | ||
105 | *mtrr = map.mtrr; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, | ||
110 | unsigned long *magic, unsigned long *iocs) | ||
111 | { | ||
112 | drm_client_t client; | ||
113 | |||
114 | client.idx = idx; | ||
115 | if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno; | ||
116 | *auth = client.auth; | ||
117 | *pid = client.pid; | ||
118 | *uid = client.uid; | ||
119 | *magic = client.magic; | ||
120 | *iocs = client.iocs; | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | int drmGetStats(int fd, drmStatsT *stats) | ||
125 | { | ||
126 | drm_stats_t s; | ||
127 | int i; | ||
128 | |||
129 | if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno; | ||
130 | |||
131 | stats->count = 0; | ||
132 | memset(stats, 0, sizeof(*stats)); | ||
133 | if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) | ||
134 | return -1; | ||
135 | |||
136 | #define SET_VALUE \ | ||
137 | stats->data[i].long_format = "%-20.20s"; \ | ||
138 | stats->data[i].rate_format = "%8.8s"; \ | ||
139 | stats->data[i].isvalue = 1; \ | ||
140 | stats->data[i].verbose = 0 | ||
141 | |||
142 | #define SET_COUNT \ | ||
143 | stats->data[i].long_format = "%-20.20s"; \ | ||
144 | stats->data[i].rate_format = "%5.5s"; \ | ||
145 | stats->data[i].isvalue = 0; \ | ||
146 | stats->data[i].mult_names = "kgm"; \ | ||
147 | stats->data[i].mult = 1000; \ | ||
148 | stats->data[i].verbose = 0 | ||
149 | |||
150 | #define SET_BYTE \ | ||
151 | stats->data[i].long_format = "%-9.9s"; \ | ||
152 | stats->data[i].rate_format = "%5.5s"; \ | ||
153 | stats->data[i].isvalue = 0; \ | ||
154 | stats->data[i].mult_names = "KGM"; \ | ||
155 | stats->data[i].mult = 1024; \ | ||
156 | stats->data[i].verbose = 0 | ||
157 | |||
158 | |||
159 | stats->count = s.count; | ||
160 | for (i = 0; i < s.count; i++) { | ||
161 | stats->data[i].value = s.data[i].value; | ||
162 | switch (s.data[i].type) { | ||
163 | case _DRM_STAT_LOCK: | ||
164 | stats->data[i].long_name = "Lock"; | ||
165 | stats->data[i].rate_name = "Lock"; | ||
166 | SET_VALUE; | ||
167 | break; | ||
168 | case _DRM_STAT_OPENS: | ||
169 | stats->data[i].long_name = "Opens"; | ||
170 | stats->data[i].rate_name = "O"; | ||
171 | SET_COUNT; | ||
172 | stats->data[i].verbose = 1; | ||
173 | break; | ||
174 | case _DRM_STAT_CLOSES: | ||
175 | stats->data[i].long_name = "Closes"; | ||
176 | stats->data[i].rate_name = "Lock"; | ||
177 | SET_COUNT; | ||
178 | stats->data[i].verbose = 1; | ||
179 | break; | ||
180 | case _DRM_STAT_IOCTLS: | ||
181 | stats->data[i].long_name = "Ioctls"; | ||
182 | stats->data[i].rate_name = "Ioc/s"; | ||
183 | SET_COUNT; | ||
184 | break; | ||
185 | case _DRM_STAT_LOCKS: | ||
186 | stats->data[i].long_name = "Locks"; | ||
187 | stats->data[i].rate_name = "Lck/s"; | ||
188 | SET_COUNT; | ||
189 | break; | ||
190 | case _DRM_STAT_UNLOCKS: | ||
191 | stats->data[i].long_name = "Unlocks"; | ||
192 | stats->data[i].rate_name = "Unl/s"; | ||
193 | SET_COUNT; | ||
194 | break; | ||
195 | case _DRM_STAT_IRQ: | ||
196 | stats->data[i].long_name = "IRQs"; | ||
197 | stats->data[i].rate_name = "IRQ/s"; | ||
198 | SET_COUNT; | ||
199 | break; | ||
200 | case _DRM_STAT_PRIMARY: | ||
201 | stats->data[i].long_name = "Primary Bytes"; | ||
202 | stats->data[i].rate_name = "PB/s"; | ||
203 | SET_BYTE; | ||
204 | break; | ||
205 | case _DRM_STAT_SECONDARY: | ||
206 | stats->data[i].long_name = "Secondary Bytes"; | ||
207 | stats->data[i].rate_name = "SB/s"; | ||
208 | SET_BYTE; | ||
209 | break; | ||
210 | case _DRM_STAT_DMA: | ||
211 | stats->data[i].long_name = "DMA"; | ||
212 | stats->data[i].rate_name = "DMA/s"; | ||
213 | SET_COUNT; | ||
214 | break; | ||
215 | case _DRM_STAT_SPECIAL: | ||
216 | stats->data[i].long_name = "Special DMA"; | ||
217 | stats->data[i].rate_name = "dma/s"; | ||
218 | SET_COUNT; | ||
219 | break; | ||
220 | case _DRM_STAT_MISSED: | ||
221 | stats->data[i].long_name = "Miss"; | ||
222 | stats->data[i].rate_name = "Ms/s"; | ||
223 | SET_COUNT; | ||
224 | break; | ||
225 | case _DRM_STAT_VALUE: | ||
226 | stats->data[i].long_name = "Value"; | ||
227 | stats->data[i].rate_name = "Value"; | ||
228 | SET_VALUE; | ||
229 | break; | ||
230 | case _DRM_STAT_BYTE: | ||
231 | stats->data[i].long_name = "Bytes"; | ||
232 | stats->data[i].rate_name = "B/s"; | ||
233 | SET_BYTE; | ||
234 | break; | ||
235 | case _DRM_STAT_COUNT: | ||
236 | default: | ||
237 | stats->data[i].long_name = "Count"; | ||
238 | stats->data[i].rate_name = "Cnt/s"; | ||
239 | SET_COUNT; | ||
240 | break; | ||
241 | } | ||
242 | } | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static void getvm(int fd) | ||
247 | { | ||
248 | int i; | ||
249 | const char *typename; | ||
250 | char flagname[33]; | ||
251 | drmHandle offset; | ||
252 | drmSize size; | ||
253 | drmMapType type; | ||
254 | drmMapFlags flags; | ||
255 | drmHandle handle; | ||
256 | int mtrr; | ||
257 | |||
258 | printf(" VM map information:\n"); | ||
259 | printf(" slot offset size type flags address mtrr\n"); | ||
260 | |||
261 | for (i = 0; | ||
262 | !drmGetMap(fd, i, &offset, &size, &type, &flags, &handle, &mtrr); | ||
263 | i++) { | ||
264 | |||
265 | switch (type) { | ||
266 | case DRM_FRAME_BUFFER: typename = "FB"; break; | ||
267 | case DRM_REGISTERS: typename = "REG"; break; | ||
268 | case DRM_SHM: typename = "SHM"; break; | ||
269 | case DRM_AGP: typename = "AGP"; break; | ||
270 | default: typename = "???"; break; | ||
271 | } | ||
272 | |||
273 | flagname[0] = (flags & DRM_RESTRICTED) ? 'R' : ' '; | ||
274 | flagname[1] = (flags & DRM_READ_ONLY) ? 'r' : 'w'; | ||
275 | flagname[2] = (flags & DRM_LOCKED) ? 'l' : ' '; | ||
276 | flagname[3] = (flags & DRM_KERNEL) ? 'k' : ' '; | ||
277 | flagname[4] = (flags & DRM_WRITE_COMBINING) ? 'W' : ' '; | ||
278 | flagname[5] = (flags & DRM_CONTAINS_LOCK) ? 'L' : ' '; | ||
279 | flagname[6] = '\0'; | ||
280 | |||
281 | printf(" %4d 0x%08lx 0x%08lx %3.3s %6.6s 0x%08lx ", | ||
282 | i, offset, (unsigned long)size, typename, flagname, handle); | ||
283 | if (mtrr < 0) printf("none\n"); | ||
284 | else printf("%4d\n", mtrr); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | static void getclients(int fd) | ||
289 | { | ||
290 | int i; | ||
291 | int auth; | ||
292 | int pid; | ||
293 | int uid; | ||
294 | unsigned long magic; | ||
295 | unsigned long iocs; | ||
296 | char buf[64]; | ||
297 | char cmd[40]; | ||
298 | int procfd; | ||
299 | |||
300 | printf(" DRI client information:\n"); | ||
301 | printf(" a pid uid magic ioctls prog\n"); | ||
302 | |||
303 | for (i = 0; !drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs); i++) { | ||
304 | sprintf(buf, "/proc/%d/cmdline", pid); | ||
305 | memset(cmd, sizeof(cmd), 0); | ||
306 | if ((procfd = open(buf, O_RDONLY, 0)) >= 0) { | ||
307 | read(procfd, cmd, sizeof(cmd)-1); | ||
308 | close(procfd); | ||
309 | } | ||
310 | if (*cmd) | ||
311 | printf(" %c %5d %5d %10lu %10lu %s\n", | ||
312 | auth ? 'y' : 'n', pid, uid, magic, iocs, cmd); | ||
313 | else | ||
314 | printf(" %c %5d %5d %10lu %10lu\n", | ||
315 | auth ? 'y' : 'n', pid, uid, magic, iocs); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | static void printhuman(unsigned long value, const char *name, int mult) | ||
320 | { | ||
321 | const char *p; | ||
322 | double f; | ||
323 | /* Print width 5 number in width 6 space */ | ||
324 | if (value < 100000) { | ||
325 | printf(" %5lu", value); | ||
326 | return; | ||
327 | } | ||
328 | |||
329 | p = name; | ||
330 | f = (double)value / (double)mult; | ||
331 | if (f < 10.0) { | ||
332 | printf(" %4.2f%c", f, *p); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | p++; | ||
337 | f = (double)value / (double)mult; | ||
338 | if (f < 10.0) { | ||
339 | printf(" %4.2f%c", f, *p); | ||
340 | return; | ||
341 | } | ||
342 | |||
343 | p++; | ||
344 | f = (double)value / (double)mult; | ||
345 | if (f < 10.0) { | ||
346 | printf(" %4.2f%c", f, *p); | ||
347 | return; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | static void getstats(int fd, int i) | ||
352 | { | ||
353 | drmStatsT prev, curr; | ||
354 | int j; | ||
355 | double rate; | ||
356 | |||
357 | printf(" System statistics:\n"); | ||
358 | |||
359 | if (drmGetStats(fd, &prev)) return; | ||
360 | if (!i) { | ||
361 | for (j = 0; j < prev.count; j++) { | ||
362 | printf(" "); | ||
363 | printf(prev.data[j].long_format, prev.data[j].long_name); | ||
364 | if (prev.data[j].isvalue) printf(" 0x%08lx\n", prev.data[j].value); | ||
365 | else printf(" %10lu\n", prev.data[j].value); | ||
366 | } | ||
367 | return; | ||
368 | } | ||
369 | |||
370 | printf(" "); | ||
371 | for (j = 0; j < prev.count; j++) | ||
372 | if (!prev.data[j].verbose) { | ||
373 | printf(" "); | ||
374 | printf(prev.data[j].rate_format, prev.data[j].rate_name); | ||
375 | } | ||
376 | printf("\n"); | ||
377 | |||
378 | for (;;) { | ||
379 | sleep(i); | ||
380 | if (drmGetStats(fd, &curr)) return; | ||
381 | printf(" "); | ||
382 | for (j = 0; j < curr.count; j++) { | ||
383 | if (curr.data[j].verbose) continue; | ||
384 | if (curr.data[j].isvalue) { | ||
385 | printf(" %08lx", curr.data[j].value); | ||
386 | } else { | ||
387 | rate = (curr.data[j].value - prev.data[j].value) / (double)i; | ||
388 | printhuman(rate, curr.data[j].mult_names, curr.data[j].mult); | ||
389 | } | ||
390 | } | ||
391 | printf("\n"); | ||
392 | memcpy(&prev, &curr, sizeof(prev)); | ||
393 | } | ||
394 | |||
395 | } | ||
396 | |||
397 | static int drmOpenMinor(int minor, uid_t user, gid_t group, | ||
398 | mode_t dirmode, mode_t devmode, int force) | ||
399 | { | ||
400 | struct stat st; | ||
401 | char buf[64]; | ||
402 | long dev = makedev(DRM_MAJOR, minor); | ||
403 | int setdir = 0; | ||
404 | int setdev = 0; | ||
405 | int fd; | ||
406 | |||
407 | if (stat(DRM_DIR_NAME, &st) || !S_ISDIR(st.st_mode)) { | ||
408 | remove(DRM_DIR_NAME); | ||
409 | mkdir(DRM_DIR_NAME, dirmode); | ||
410 | ++setdir; | ||
411 | } | ||
412 | |||
413 | if (force || setdir) { | ||
414 | chown(DRM_DIR_NAME, user, group); | ||
415 | chmod(DRM_DIR_NAME, dirmode); | ||
416 | } | ||
417 | |||
418 | sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); | ||
419 | if (stat(buf, &st) || st.st_rdev != dev) { | ||
420 | remove(buf); | ||
421 | mknod(buf, S_IFCHR, dev); | ||
422 | ++setdev; | ||
423 | } | ||
424 | |||
425 | if (force || setdev) { | ||
426 | chown(buf, user, group); | ||
427 | chmod(buf, devmode); | ||
428 | } | ||
429 | |||
430 | if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; | ||
431 | if (setdev) remove(buf); | ||
432 | return -errno; | ||
433 | } | ||
434 | |||
435 | int main(int argc, char **argv) | ||
436 | { | ||
437 | int c; | ||
438 | int mask = 0; | ||
439 | int minor = 0; | ||
440 | int interval = 0; | ||
441 | int fd; | ||
442 | char buf[64]; | ||
443 | int i; | ||
444 | |||
445 | while ((c = getopt(argc, argv, "avmcsM:i:")) != EOF) | ||
446 | switch (c) { | ||
447 | case 'a': mask = ~0; break; | ||
448 | case 'v': mask |= DRM_VERSION; break; | ||
449 | case 'm': mask |= DRM_MEMORY; break; | ||
450 | case 'c': mask |= DRM_CLIENTS; break; | ||
451 | case 's': mask |= DRM_STATS; break; | ||
452 | case 'i': interval = strtol(optarg, NULL, 0); break; | ||
453 | case 'M': minor = strtol(optarg, NULL, 0); break; | ||
454 | default: | ||
455 | fprintf( stderr, "Usage: dristat [options]\n" ); | ||
456 | return 1; | ||
457 | } | ||
458 | |||
459 | for (i = 0; i < 16; i++) if (!minor || i == minor) { | ||
460 | sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i); | ||
461 | fd = drmOpenMinor(i, 0, 0, 0700, 0600, 0); | ||
462 | if (fd >= 0) { | ||
463 | printf("%s\n", buf); | ||
464 | if (mask & DRM_VERSION) getversion(fd); | ||
465 | if (mask & DRM_MEMORY) getvm(fd); | ||
466 | if (mask & DRM_CLIENTS) getclients(fd); | ||
467 | if (mask & DRM_STATS) getstats(fd, interval); | ||
468 | close(fd); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | return 0; | ||
473 | } | ||