Back to index

libdrm  2.4.37
dristat.c
Go to the documentation of this file.
00001 /* dristat.c -- 
00002  * Created: Mon Jan 15 05:05:07 2001 by faith@acm.org
00003  *
00004  * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
00005  * All Rights Reserved.
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this software and associated documentation files (the "Software"),
00009  * to deal in the Software without restriction, including without limitation
00010  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011  * and/or sell copies of the Software, and to permit persons to whom the
00012  * Software is furnished to do so, subject to the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the next
00015  * paragraph) shall be included in all copies or substantial portions of the
00016  * Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00021  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
00022  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00023  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00024  * DEALINGS IN THE SOFTWARE.
00025  * 
00026  * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
00027  * 
00028  */
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <unistd.h>
00033 #include "xf86drm.h"
00034 #include "xf86drmRandom.c"
00035 #include "xf86drmHash.c"
00036 #include "xf86drm.c"
00037 
00038 #define DRM_VERSION 0x00000001
00039 #define DRM_MEMORY  0x00000002
00040 #define DRM_CLIENTS 0x00000004
00041 #define DRM_STATS   0x00000008
00042 #define DRM_BUSID   0x00000010
00043 
00044 static void getversion(int fd)
00045 {
00046     drmVersionPtr version;
00047     
00048     version = drmGetVersion(fd);
00049     if (version) {
00050        printf("  Version information:\n");
00051        printf("    Name: %s\n", version->name ? version->name : "?");
00052        printf("    Version: %d.%d.%d\n",
00053               version->version_major,
00054               version->version_minor,
00055               version->version_patchlevel);
00056        printf("    Date: %s\n", version->date ? version->date : "?");
00057        printf("    Desc: %s\n", version->desc ? version->desc : "?");
00058        drmFreeVersion(version);
00059     } else {
00060        printf("  No version information available\n");
00061     }
00062 }
00063 
00064 static void getbusid(int fd)
00065 {
00066     const char *busid = drmGetBusid(fd);
00067     
00068     printf("  Busid: %s\n", *busid ? busid : "(not set)");
00069     drmFreeBusid(busid);
00070 }
00071 
00072 
00073 static void getvm(int fd)
00074 {
00075     int             i;
00076     const char      *typename;
00077     char            flagname[33];
00078     drm_handle_t    offset;
00079     drmSize         size;
00080     drmMapType      type;
00081     drmMapFlags     flags;
00082     drm_handle_t    handle;
00083     int             mtrr;
00084 
00085     printf("  VM map information:\n");
00086     printf("  flags: (R)estricted (r)ead/(w)rite (l)ocked (k)ernel (W)rite-combine (L)ock:\n");
00087     printf("    slot     offset       size type flags    address mtrr\n");
00088 
00089     for (i = 0;
00090         !drmGetMap(fd, i, &offset, &size, &type, &flags, &handle, &mtrr);
00091         i++) {
00092        
00093        switch (type) {
00094        case DRM_FRAME_BUFFER:   typename = "FB";  break;
00095        case DRM_REGISTERS:      typename = "REG"; break;
00096        case DRM_SHM:            typename = "SHM"; break;
00097        case DRM_AGP:            typename = "AGP"; break;
00098        case DRM_SCATTER_GATHER: typename = "SG";  break;
00099        default:                 typename = "???"; break;
00100        }
00101 
00102        flagname[0] = (flags & DRM_RESTRICTED)      ? 'R' : ' ';
00103        flagname[1] = (flags & DRM_READ_ONLY)       ? 'r' : 'w';
00104        flagname[2] = (flags & DRM_LOCKED)          ? 'l' : ' ';
00105        flagname[3] = (flags & DRM_KERNEL)          ? 'k' : ' ';
00106        flagname[4] = (flags & DRM_WRITE_COMBINING) ? 'W' : ' ';
00107        flagname[5] = (flags & DRM_CONTAINS_LOCK)   ? 'L' : ' ';
00108        flagname[6] = '\0';
00109        
00110        printf("    %4d 0x%08lx 0x%08lx %3.3s %6.6s 0x%08lx ",
00111               i, (unsigned long)offset, (unsigned long)size,
00112               typename, flagname, (unsigned long)handle);
00113        if (mtrr < 0) printf("none\n");
00114        else          printf("%4d\n", mtrr);
00115     }
00116 }
00117 
00118 static void getclients(int fd)
00119 {
00120     int           i;
00121     int           auth;
00122     int           pid;
00123     int           uid;
00124     unsigned long magic;
00125     unsigned long iocs;
00126     char          buf[64];
00127     char          cmd[40];
00128     int           procfd;
00129     
00130     printf("  DRI client information:\n");
00131     printf("    a   pid   uid      magic     ioctls   prog\n");
00132 
00133     for (i = 0; !drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs); i++) {
00134        sprintf(buf, "/proc/%d/cmdline", pid);
00135        memset(cmd, 0, sizeof(cmd));
00136        if ((procfd = open(buf, O_RDONLY, 0)) >= 0) {
00137            read(procfd, cmd, sizeof(cmd)-1);
00138            close(procfd);
00139        }
00140        if (*cmd) {
00141            char *pt;
00142 
00143            for (pt = cmd; *pt; pt++) if (!isprint(*pt)) *pt = ' ';
00144            printf("    %c %5d %5d %10lu %10lu   %s\n",
00145                  auth ? 'y' : 'n', pid, uid, magic, iocs, cmd);
00146        } else {
00147            printf("    %c %5d %5d %10lu %10lu\n",
00148                  auth ? 'y' : 'n', pid, uid, magic, iocs);
00149        }
00150     }
00151 }
00152 
00153 static void printhuman(unsigned long value, const char *name, int mult)
00154 {
00155     const char *p;
00156     double     f;
00157                             /* Print width 5 number in width 6 space */
00158     if (value < 100000) {
00159        printf(" %5lu", value);
00160        return;
00161     }
00162 
00163     p = name;
00164     f = (double)value / (double)mult;
00165     if (f < 10.0) {
00166        printf(" %4.2f%c", f, *p);
00167        return;
00168     }
00169 
00170     p++;
00171     f = (double)value / (double)mult;
00172     if (f < 10.0) {
00173        printf(" %4.2f%c", f, *p);
00174        return;
00175     }
00176     
00177     p++;
00178     f = (double)value / (double)mult;
00179     if (f < 10.0) {
00180        printf(" %4.2f%c", f, *p);
00181        return;
00182     }
00183 }
00184 
00185 static void getstats(int fd, int i)
00186 {
00187     drmStatsT prev, curr;
00188     int       j;
00189     double    rate;
00190     
00191     printf("  System statistics:\n");
00192 
00193     if (drmGetStats(fd, &prev)) return;
00194     if (!i) {
00195        for (j = 0; j < prev.count; j++) {
00196            printf("    ");
00197            printf(prev.data[j].long_format, prev.data[j].long_name);
00198            if (prev.data[j].isvalue) printf(" 0x%08lx\n", prev.data[j].value);
00199            else                      printf(" %10lu\n", prev.data[j].value);
00200        }
00201        return;
00202     }
00203 
00204     printf("    ");
00205     for (j = 0; j < prev.count; j++)
00206        if (!prev.data[j].verbose) {
00207            printf(" ");
00208            printf(prev.data[j].rate_format, prev.data[j].rate_name);
00209        }
00210     printf("\n");
00211     
00212     for (;;) {
00213        sleep(i);
00214        if (drmGetStats(fd, &curr)) return;
00215        printf("    ");
00216        for (j = 0; j < curr.count; j++) {
00217            if (curr.data[j].verbose) continue;
00218            if (curr.data[j].isvalue) {
00219               printf(" %08lx", curr.data[j].value);
00220            } else {
00221               rate = (curr.data[j].value - prev.data[j].value) / (double)i;
00222               printhuman(rate, curr.data[j].mult_names, curr.data[j].mult);
00223            }
00224        }
00225        printf("\n");
00226        memcpy(&prev, &curr, sizeof(prev));
00227     }
00228     
00229 }
00230 
00231 int main(int argc, char **argv)
00232 {
00233     int  c;
00234     int  mask     = 0;
00235     int  minor    = 0;
00236     int  interval = 0;
00237     int  fd;
00238     char buf[64];
00239     int  i;
00240 
00241     while ((c = getopt(argc, argv, "avmcsbM:i:")) != EOF)
00242        switch (c) {
00243        case 'a': mask = ~0;                          break;
00244        case 'v': mask |= DRM_VERSION;                break;
00245        case 'm': mask |= DRM_MEMORY;                 break;
00246        case 'c': mask |= DRM_CLIENTS;                break;
00247        case 's': mask |= DRM_STATS;                  break;
00248        case 'b': mask |= DRM_BUSID;                  break;
00249        case 'i': interval = strtol(optarg, NULL, 0); break;
00250        case 'M': minor = strtol(optarg, NULL, 0);    break;
00251        default:
00252            fprintf( stderr, "Usage: dristat [options]\n\n" );
00253            fprintf( stderr, "Displays DRM information. Use with no arguments to display available cards.\n\n" );
00254            fprintf( stderr, "  -a            Show all available information\n" );
00255            fprintf( stderr, "  -b            Show DRM bus ID's\n" );
00256            fprintf( stderr, "  -c            Display information about DRM clients\n" );
00257            fprintf( stderr, "  -i [interval] Continuously display statistics every [interval] seconds\n" );
00258            fprintf( stderr, "  -v            Display DRM module and card version information\n" );
00259            fprintf( stderr, "  -m            Display memory use information\n" );
00260            fprintf( stderr, "  -s            Display DRM statistics\n" );
00261            fprintf( stderr, "  -M [minor]    Select card by minor number\n" );
00262            return 1;
00263        }
00264 
00265     for (i = 0; i < 16; i++) if (!minor || i == minor) {
00266        sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
00267        fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
00268        if (fd >= 0) {
00269            printf("%s\n", buf);
00270            if (mask & DRM_BUSID)   getbusid(fd);
00271            if (mask & DRM_VERSION) getversion(fd);
00272            if (mask & DRM_MEMORY)  getvm(fd);
00273            if (mask & DRM_CLIENTS) getclients(fd);
00274            if (mask & DRM_STATS)   getstats(fd, interval);
00275            close(fd);
00276        }
00277     }
00278 
00279     return 0; 
00280 }