[Intel-gfx] [RFC] Tracing infrastructure for driver performance
Chris Wilson
chris at chris-wilson.co.uk
Wed Jul 8 20:58:30 CEST 2009
/* For reference, here is the user space utility to read i915_trace.
* -ickle
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
enum {
I915_TRACE_HEADER,
I915_TRACE_OBJECT_CREATE,
I915_TRACE_OBJECT_BIND,
I915_TRACE_OBJECT_CHANGE_DOMAIN,
I915_TRACE_OBJECT_GET_FENCE,
I915_TRACE_OBJECT_UNBIND,
I915_TRACE_OBJECT_DESTROY,
I915_TRACE_SUBMIT,
I915_TRACE_FLUSH,
I915_TRACE_COMPLETE,
I915_TRACE_RETIRE,
I915_TRACE_WAIT_BEGIN,
I915_TRACE_WAIT_END,
};
#define I915_TRACE_MAGIC 0xdeadbeef
#define I915_TRACE_VERSION 0
struct i915_trace_event {
uint64_t time;
uint32_t minor;
uint32_t id;
union {
uint64_t obj;
uint32_t seqno;
};
uint32_t arg1;
uint32_t arg2;
};
static void
watch (int fd)
{
struct i915_trace_event event[4096 / sizeof (struct i915_trace_event)];
int ret;
/* the very first event is a stream header */
ret = read (fd, &event[0], sizeof (event[0]));
if (ret != sizeof (event[0]))
return;
if (event[0].id != I915_TRACE_HEADER ||
event[0].seqno != I915_TRACE_MAGIC ||
event[0].arg1 != I915_TRACE_VERSION)
{
fprintf (stderr, "unhandled i915 trace: "
"type=%d, magic=%d, version=%d\n",
event[0].id,
event[0].seqno,
event[0].arg1);
return;
}
do {
struct i915_trace_event *ev;
ret = read (fd, event, sizeof (event));
if (ret < 0)
return;
ev = event;
while ((ret -= sizeof (*ev)) >= 0) {
switch (ev->id) {
case I915_TRACE_HEADER:
break;
case I915_TRACE_OBJECT_CREATE:
printf ("%qu: object_create(%08llx, %d)\n",
ev->time,
ev->obj,
ev->arg1);
break;
case I915_TRACE_OBJECT_BIND:
printf ("%qu: object_bind(%08llx)\n",
ev->time, ev->obj);
break;
case I915_TRACE_OBJECT_CHANGE_DOMAIN:
printf ("%qu: object_change_domain(%08llx, %04x, %04x)\n",
ev->time, ev->obj, ev->arg1, ev->arg2);
break;
case I915_TRACE_OBJECT_GET_FENCE:
printf ("%qu: object_get_fence(%08llx, %d, %d)\n",
ev->time, ev->obj, ev->arg1, ev->arg2);
break;
case I915_TRACE_OBJECT_UNBIND:
printf ("%qu: object_unbind(%08llx)\n",
ev->time, ev->obj);
break;
case I915_TRACE_OBJECT_DESTROY:
printf ("%qu: object_destroy(%08llx)\n",
ev->time, ev->obj);
break;
case I915_TRACE_SUBMIT:
printf ("%qu: submit(%d)\n", ev->time, ev->seqno);
break;
case I915_TRACE_FLUSH:
printf ("%qu: flush(%d, %04x, %04x)\n",
ev->time, ev->seqno, ev->arg1, ev->arg2);
break;
case I915_TRACE_COMPLETE:
printf ("%qu: complete(%d)\n", ev->time, ev->seqno);
break;
case I915_TRACE_RETIRE:
printf ("%qu: retire(%d)\n", ev->time, ev->seqno);
break;
case I915_TRACE_WAIT_BEGIN:
printf ("%qu: wait(%d) begin\n", ev->time, ev->seqno);
break;
case I915_TRACE_WAIT_END:
printf ("%qu: wait(%d) end\n", ev->time, ev->seqno);
break;
}
ev++;
}
} while (1);
}
static int
open_trace (const char *path, int card)
{
char buf[4096];
snprintf (buf, sizeof (buf), "%s/dri/%d/i915_trace", path, card);
return open (buf, O_RDWR);
}
static int
tracepoints_enable (int fd, int active)
{
return write (fd, active ? "*\n" : "!\n", 2) == 2;
}
int
main (int argc, char **argv)
{
const char *debugfs = "/sys/kernel/debug";
int card = 0;
int fd;
if (argc > 1)
card = atoi (argv[1]);
fd = open_trace (debugfs, card);
if (fd < 0) {
perror ("failed to open trace");
return 1;
}
if (! tracepoints_enable (fd, 1)) {
perror ("failed to enable events");
close (fd);
return 1;
}
watch (fd);
if (! tracepoints_enable (fd, 0))
perror ("failed to disable events");
close (fd);
return 0;
}
More information about the Intel-gfx
mailing list