summaryrefslogtreecommitdiff
path: root/benchmarks/gem_exec_tracer.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-28 11:26:39 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2017-03-28 13:04:45 +0100
commit49e09e73460b74a56b210b804f32abbcf5eab66a (patch)
tree2b7a12365ef40b60ed42d0fc4f4d0a9541516d29 /benchmarks/gem_exec_tracer.c
parentb6eea5d29c42954d3b7bb790b1d8d5decf35422e (diff)
benchmarks/gem_exec_trace: Enhanced multi-context capture
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'benchmarks/gem_exec_tracer.c')
-rw-r--r--benchmarks/gem_exec_tracer.c200
1 files changed, 144 insertions, 56 deletions
diff --git a/benchmarks/gem_exec_tracer.c b/benchmarks/gem_exec_tracer.c
index f0057942..9af61420 100644
--- a/benchmarks/gem_exec_tracer.c
+++ b/benchmarks/gem_exec_tracer.c
@@ -45,17 +45,30 @@
static int (*libc_close)(int fd);
static int (*libc_ioctl)(int fd, unsigned long request, void *argp);
-static int drm_fd = -1;
-static FILE *file;
+struct trace {
+ int fd;
+ FILE *file;
+ struct trace *next;
+} *traces;
#define DRM_MAJOR 226
enum {
ADD_BO = 0,
DEL_BO,
+ ADD_CTX,
+ DEL_CTX,
EXEC,
};
+static struct trace_verion {
+ uint32_t magic;
+ uint32_t version;
+} version = {
+ .magic = 0xdeadbeef,
+ .version = 1
+};
+
struct trace_add_bo {
uint8_t cmd;
uint32_t handle;
@@ -66,16 +79,27 @@ struct trace_del_bo {
uint32_t handle;
}__attribute__((packed));
+struct trace_add_ctx {
+ uint8_t cmd;
+ uint32_t handle;
+} __attribute__((packed));
+struct trace_del_ctx {
+ uint8_t cmd;
+ uint32_t handle;
+}__attribute__((packed));
+
struct trace_exec {
uint8_t cmd;
uint32_t object_count;
uint64_t flags;
+ uint32_t context;
}__attribute__((packed));
struct trace_exec_object {
uint32_t handle;
uint32_t relocation_count;
uint64_t alignment;
+ uint64_t offset;
uint64_t flags;
uint64_t rsvd1;
uint64_t rsvd2;
@@ -85,6 +109,7 @@ struct trace_exec_relocation {
uint32_t target_handle;
uint32_t delta;
uint64_t offset;
+ uint64_t presumed_offset;
uint32_t read_domains;
uint32_t write_domain;
}__attribute__((packed));
@@ -101,71 +126,95 @@ fail_if(int cond, const char *format, ...)
vfprintf(stderr, format, args);
va_end(args);
- exit(1);
+ abort();
}
static void
-trace_exec(int fd, const struct drm_i915_gem_execbuffer2 *execbuffer2)
+trace_exec(struct trace *trace,
+ const struct drm_i915_gem_execbuffer2 *execbuffer2)
{
+#define to_ptr(T, x) ((T *)(uintptr_t)(x))
const struct drm_i915_gem_exec_object2 *exec_objects =
- (struct drm_i915_gem_exec_object2 *)(uintptr_t)execbuffer2->buffers_ptr;
+ to_ptr(typeof(*exec_objects), execbuffer2->buffers_ptr);
+
+ fail_if(execbuffer2->flags & (I915_EXEC_FENCE_IN | I915_EXEC_FENCE_OUT),
+ "fences not supported yet\n");
{
struct trace_exec t = {
- EXEC, execbuffer2->buffer_count, execbuffer2->flags
+ EXEC,
+ execbuffer2->buffer_count,
+ execbuffer2->flags,
+ execbuffer2->rsvd1,
};
- fwrite(&t, sizeof(t), 1, file);
+ fwrite(&t, sizeof(t), 1, trace->file);
}
for (uint32_t i = 0; i < execbuffer2->buffer_count; i++) {
const struct drm_i915_gem_exec_object2 *obj = &exec_objects[i];
const struct drm_i915_gem_relocation_entry *relocs =
- (struct drm_i915_gem_relocation_entry *)(uintptr_t)obj->relocs_ptr;
+ to_ptr(typeof(*relocs), obj->relocs_ptr);
{
struct trace_exec_object t = {
obj->handle,
obj->relocation_count,
obj->alignment,
+ obj->offset,
obj->flags,
obj->rsvd1,
obj->rsvd2
};
- fwrite(&t, sizeof(t), 1, file);
- }
- for (uint32_t j = 0; j < obj->relocation_count; j++) {
- struct trace_exec_relocation t = {
- relocs[j].target_handle,
- relocs[j].delta,
- relocs[j].offset,
- relocs[j].read_domains,
- relocs[j].write_domain,
- };
- fwrite(&t, sizeof(t), 1, file);
+ fwrite(&t, sizeof(t), 1, trace->file);
}
+ fwrite(relocs, sizeof(*relocs), obj->relocation_count,
+ trace->file);
}
- fflush(file);
+ fflush(trace->file);
+#undef to_ptr
}
static void
-trace_add(uint32_t handle, uint64_t size)
+trace_add(struct trace *trace, uint32_t handle, uint64_t size)
{
struct trace_add_bo t = { ADD_BO, handle, size };
- fwrite(&t, sizeof(t), 1, file);
+ fwrite(&t, sizeof(t), 1, trace->file);
}
static void
-trace_del(uint32_t handle)
+trace_del(struct trace *trace, uint32_t handle)
{
struct trace_del_bo t = { DEL_BO, handle };
- fwrite(&t, sizeof(t), 1, file);
+ fwrite(&t, sizeof(t), 1, trace->file);
+}
+
+static void
+trace_add_context(struct trace *trace, uint32_t handle)
+{
+ struct trace_add_ctx t = { ADD_CTX, handle };
+ fwrite(&t, sizeof(t), 1, trace->file);
+}
+
+static void
+trace_del_context(struct trace *trace, uint32_t handle)
+{
+ struct trace_del_ctx t = { DEL_CTX, handle };
+ fwrite(&t, sizeof(t), 1, trace->file);
}
int
close(int fd)
{
- if (fd == drm_fd)
- drm_fd = -1;
+ struct trace *t, **p;
+
+ for (p = &traces; (t = *p); p = &t->next) {
+ if (t->fd == fd) {
+ *p = t->next;
+ fclose(t->file);
+ free(t);
+ break;
+ }
+ }
return libc_close(fd);
}
@@ -186,14 +235,14 @@ size_for_fb(const struct drm_mode_fb_cmd *cmd)
static int is_i915(int fd)
{
- drm_version_t version;
+ drm_version_t v;
char name[5] = "";
- memset(&version, 0, sizeof(version));
- version.name_len = 4;
- version.name = name;
+ memset(&v, 0, sizeof(v));
+ v.name_len = 4;
+ v.name = name;
- if (libc_ioctl(fd, DRM_IOCTL_VERSION, &version))
+ if (libc_ioctl(fd, DRM_IOCTL_VERSION, &v))
return 0;
return strcmp(name, "i915") == 0;
@@ -202,6 +251,7 @@ static int is_i915(int fd)
int
ioctl(int fd, unsigned long request, ...)
{
+ struct trace *t, **p;
va_list args;
void *argp;
int ret;
@@ -210,53 +260,82 @@ ioctl(int fd, unsigned long request, ...)
argp = va_arg(args, void *);
va_end(args);
- ret = libc_ioctl(fd, request, argp);
- if (ret)
- return ret;
-
if (_IOC_TYPE(request) != DRM_IOCTL_BASE)
- return 0;
-
- if (drm_fd != fd) {
+ goto untraced;
+
+ for (p = &traces; (t = *p); p = &t->next) {
+ if (fd == t->fd) {
+ if (traces != t) {
+ *p = t->next;
+ t->next = traces;
+ traces = t;
+ }
+ break;
+ }
+ }
+ if (!t) {
char filename[80];
if (!is_i915(fd))
- return 0;
+ goto untraced;
- if (file)
- fclose(file);
+ t = malloc(sizeof(*t));
+ if (!t)
+ return -ENOMEM;
- sprintf(filename, "/tmp/trace.%d", fd);
- file = fopen(filename, "w+");
- drm_fd = fd;
+ sprintf(filename, "/tmp/trace-%d.%d", getpid(), fd);
+ t->file = fopen(filename, "w+");
+ t->fd = fd;
+
+ if (!fwrite(&version, sizeof(version), 1, t->file)) {
+ fclose(t->file);
+ free(t);
+ return -ENOMEM;
+ }
+
+ t->next = traces;
+ traces = t;
}
switch (request) {
case DRM_IOCTL_I915_GEM_EXECBUFFER2:
- trace_exec(fd, argp);
+ case DRM_IOCTL_I915_GEM_EXECBUFFER2_WR:
+ trace_exec(t, argp);
+ break;
+
+ case DRM_IOCTL_GEM_CLOSE: {
+ struct drm_gem_close *close = argp;
+ trace_del(t, close->handle);
break;
+ }
+
+ case DRM_IOCTL_I915_GEM_CONTEXT_DESTROY: {
+ struct drm_i915_gem_context_destroy *close = argp;
+ trace_del_context(t, close->ctx_id);
+ break;
+ }
+ }
+ ret = libc_ioctl(fd, request, argp);
+ if (ret)
+ return ret;
+
+ switch (request) {
case DRM_IOCTL_I915_GEM_CREATE: {
struct drm_i915_gem_create *create = argp;
- trace_add(create->handle, create->size);
+ trace_add(t, create->handle, create->size);
break;
}
case DRM_IOCTL_I915_GEM_USERPTR: {
struct drm_i915_gem_userptr *userptr = argp;
- trace_add(userptr->handle, userptr->user_size);
- break;
- }
-
- case DRM_IOCTL_GEM_CLOSE: {
- struct drm_gem_close *close = argp;
- trace_del(close->handle);
+ trace_add(t, userptr->handle, userptr->user_size);
break;
}
case DRM_IOCTL_GEM_OPEN: {
struct drm_gem_open *open = argp;
- trace_add(open->handle, open->size);
+ trace_add(t, open->handle, open->size);
break;
}
@@ -264,18 +343,27 @@ ioctl(int fd, unsigned long request, ...)
struct drm_prime_handle *prime = argp;
off_t size = lseek(prime->fd, 0, SEEK_END);
fail_if(size == -1, "failed to get prime bo size\n");
- trace_add(prime->handle, size);
+ trace_add(t, prime->handle, size);
break;
}
case DRM_IOCTL_MODE_GETFB: {
struct drm_mode_fb_cmd *cmd = argp;
- trace_add(cmd->handle, size_for_fb(cmd));
+ trace_add(t, cmd->handle, size_for_fb(cmd));
+ break;
+ }
+
+ case DRM_IOCTL_I915_GEM_CONTEXT_CREATE: {
+ struct drm_i915_gem_context_create *create = argp;
+ trace_add_context(t, create->ctx_id);
break;
}
}
return 0;
+
+untraced:
+ return libc_ioctl(fd, request, argp);
}
static void __attribute__ ((constructor))