aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGareth Hughes2001-02-15 02:12:14 -0600
committerGareth Hughes2001-02-15 02:12:14 -0600
commit360475376c5a597caf4a981c934a6b0d783fa94d (patch)
tree433f6970813deb74a2c8e1636b772a1f8567b267 /tests/dristat.c
parent38c22bc4883ac201bde7f5f130a72acd1be68ec5 (diff)
downloadexternal-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.c473
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
46typedef 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
61static 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
81typedef 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
92int 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
109int 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
124int 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
246static 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
288static 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
319static 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
351static 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
397static 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
435int 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}