From 3911621d0d23aced7feb1569b39f7fb52b309681 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 10 Aug 2015 18:17:47 +0100 Subject: benchmarks: Rename the gem_exec_trace tracer module Now that we actually install the benchmarks into a sane location, slightly abuse it to put the tracer for gem_exec_trace alongside. Signed-off-by: Chris Wilson --- benchmarks/gem_exec_tracer.c | 271 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 benchmarks/gem_exec_tracer.c (limited to 'benchmarks/gem_exec_tracer.c') diff --git a/benchmarks/gem_exec_tracer.c b/benchmarks/gem_exec_tracer.c new file mode 100644 index 00000000..ccc2d23a --- /dev/null +++ b/benchmarks/gem_exec_tracer.c @@ -0,0 +1,271 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#define _GNU_SOURCE /* for RTLD_NEXT */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intel_aub.h" +#include "intel_chipset.h" + +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; + +#define DRM_MAJOR 226 + +enum { + ADD_BO = 0, + DEL_BO, + EXEC, +}; + +struct trace_add_bo { + uint8_t cmd; + uint32_t handle; + uint64_t size; +} __attribute__((packed)); +struct trace_del_bo { + uint8_t cmd; + uint32_t handle; +}__attribute__((packed)); + +struct trace_exec { + uint8_t cmd; + uint32_t object_count; + uint64_t flags; +}__attribute__((packed)); + +struct trace_exec_object { + uint32_t handle; + uint32_t relocation_count; + uint64_t alignment; + uint64_t flags; + uint64_t rsvd1; + uint64_t rsvd2; +}__attribute__((packed)); + +struct trace_exec_relocation { + uint32_t target_handle; + uint32_t delta; + uint64_t offset; + uint32_t read_domains; + uint32_t write_domain; +}__attribute__((packed)); + +static void __attribute__ ((format(__printf__, 2, 3))) +fail_if(int cond, const char *format, ...) +{ + va_list args; + + if (!cond) + return; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(1); +} + +static void +trace_exec(int fd, const struct drm_i915_gem_execbuffer2 *execbuffer2) +{ + const struct drm_i915_gem_exec_object2 *exec_objects = + (struct drm_i915_gem_exec_object2 *)(uintptr_t)execbuffer2->buffers_ptr; + + { + struct trace_exec t = { + EXEC, execbuffer2->buffer_count, execbuffer2->flags + }; + fwrite(&t, sizeof(t), 1, 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; + { + struct trace_exec_object t = { + obj->handle, + obj->relocation_count, + obj->alignment, + 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); + } + } + + fflush(file); +} + +static void +trace_add(uint32_t handle, uint64_t size) +{ + struct trace_add_bo t = { ADD_BO, handle, size }; + fwrite(&t, sizeof(t), 1, file); +} + +static void +trace_del(uint32_t handle) +{ + struct trace_del_bo t = { DEL_BO, handle }; + fwrite(&t, sizeof(t), 1, file); +} + +int +close(int fd) +{ + if (fd == drm_fd) + drm_fd = -1; + + return libc_close(fd); +} + +int +ioctl(int fd, unsigned long request, ...) +{ + va_list args; + void *argp; + int ret; + + va_start(args, request); + argp = va_arg(args, void *); + va_end(args); + + if (_IOC_TYPE(request) == DRM_IOCTL_BASE && drm_fd != fd) { + char filename[80]; + if (file) + fclose(file); + sprintf(filename, "/tmp/trace.%d", fd); + file = fopen(filename, "w+"); + drm_fd = fd; + } + + if (fd == drm_fd) { + switch (request) { + case DRM_IOCTL_I915_GEM_EXECBUFFER: { + return libc_ioctl(fd, request, argp); + } + + case DRM_IOCTL_I915_GEM_EXECBUFFER2: { + trace_exec(fd, argp); + return libc_ioctl(fd, request, argp); + } + + case DRM_IOCTL_I915_GEM_CREATE: { + struct drm_i915_gem_create *create = argp; + + ret = libc_ioctl(fd, request, argp); + if (ret == 0) + trace_add(create->handle, create->size); + + return ret; + } + + case DRM_IOCTL_I915_GEM_USERPTR: { + struct drm_i915_gem_userptr *userptr = argp; + + ret = libc_ioctl(fd, request, argp); + if (ret == 0) + trace_add(userptr->handle, userptr->user_size); + return ret; + } + + case DRM_IOCTL_GEM_CLOSE: { + struct drm_gem_close *close = argp; + + trace_del(close->handle); + + return libc_ioctl(fd, request, argp); + } + + case DRM_IOCTL_GEM_OPEN: { + struct drm_gem_open *open = argp; + + ret = libc_ioctl(fd, request, argp); + if (ret == 0) + trace_add(open->handle, open->size); + + return ret; + } + + case DRM_IOCTL_PRIME_FD_TO_HANDLE: { + struct drm_prime_handle *prime = argp; + + ret = libc_ioctl(fd, request, argp); + if (ret == 0) { + off_t size; + + size = lseek(prime->fd, 0, SEEK_END); + fail_if(size == -1, "failed to get prime bo size\n"); + trace_add(prime->handle, size); + } + + return ret; + } + + default: + return libc_ioctl(fd, request, argp); + } + } else { + return libc_ioctl(fd, request, argp); + } +} + +static void __attribute__ ((constructor)) +init(void) +{ + libc_close = dlsym(RTLD_NEXT, "close"); + libc_ioctl = dlsym(RTLD_NEXT, "ioctl"); + fail_if(libc_close == NULL || libc_ioctl == NULL, + "failed to get libc ioctl or close\n"); +} -- cgit v1.2.3